OmniAICreator/Qiita-1.07M huggingface dataset:
2024 年の pgvector アップデートを振り返る（12/1 時点）

これは **[PostgreSQL Advent Calendar 2024](https://qiita.com/advent-calendar/2024/postgresql)** 2 日目の記事です。

昨日（1 日目）は yaju さんでした。

https://qiita.com/yaju/items/c9bcf7e2c431a2058b58

---

個人的な PostgreSQL 関連の持ちネタは [pgvector](https://github.com/pgvector/pgvector) くらいしかないので、（利用事例などは [16 日目の elhalti さん](https://qiita.com/elhalti/items/275225fcee374ce071e3)にお任せしつつ）2024 年のアップデートについて振り返ってみます。

## その前に

（pgvector が扱う）ベクトル検索についてよくわからない方は、[九州大学 数理・データサイエンス教育研究センターの講義資料](https://mdsc.kyushu-u.ac.jp/lectures)の中から関係しそうなものをピックアップして読んでみることをお勧めします。

- **[情報科学【AI・データサイエンス】第 5 回 ベクトル・距離・類似度](https://mdsc.kyushu-u.ac.jp/wp/wp-content/uploads/2023/07/a85dfe612a31b1a1e0a4b399a9b073bf.pdf)**
- **[データサイエンス概論 I＆II / データサイエンス総論 I＆II データのベクトル表現と集合](https://mdsc.kyushu-u.ac.jp/wp/wp-content/uploads/2024/10/2-%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E8%A1%A8%E7%8F%BE%E3%81%A8%E9%9B%86%E5%90%88.pdf)**
- **[データサイエンス概論 I＆II データ間の距離と類似度](https://mdsc.kyushu-u.ac.jp/wp/wp-content/uploads/2023/07/458290da747eff72c614ee500e1baa27.pdf)**

## 2024 年の pgvector（とその周辺）の主なアップデート

### バージョン 0.6.0（1/30 リリース）・0.7.0（4/30 リリース）

[こちらの記事](https://qiita.com/hmatsu47/items/8cdafc093fcda793e863)にまとめました。

https://qiita.com/hmatsu47/items/8cdafc093fcda793e863

- HNSW インデックス作成のパラレル化（0.6.0）
- 半精度（16 ビット）ベクトル（0.7.0）
- バイナリ（ビット）ベクトルおよびバイナリ（ビット）量子化（同）
- 疎ベクトル（同）
- サブベクトルのインデックス化（同）

をサポートしました。

「pgvector は遅い」という評判を覆すべく、パフォーマンスと効率の向上を狙ったアップデートでした。

なお、↓はバイナリインデックスおよびバイナリ量子化を試したときの記事です。

https://zenn.dev/hmatsu47/articles/pgvector070-binaryvector

### pgvectorscale 0.2.0（6/6 リリース）

バージョン 0.7.0 でひととおりの機能を備えたかに見えた pgvector ですが、ベクトルストアとして競合する Pinecone によって

- HNSW インデックスとベクトル以外の列によるフィルタリングを併用すると、本来抽出すべきデータが抽出できない可能性がある
- HNSW インデックスがメモリの範囲を超えるサイズに達した場合、インデックスの作成やインデックスによる検索が極端に遅くなる

という欠点を指摘されました。

それに対抗して、Timescale 社がリリースした pgvector 拡張が [pgvectorscale](https://github.com/timescale/pgvectorscale) です。

[こちらの記事](https://zenn.dev/hmatsu47/articles/pgvectorscale)に記したとおり、

https://zenn.dev/hmatsu47/articles/pgvectorscale

pgvectorscale では

- StreamingDiskANN インデックス
- 統計的バイナリ量子化（SBQ）

を実装することで pgvector の欠点を補っています。

このあたりの実装およびその背景の説明は、[こちらのブログ記事](https://www.timescale.com/blog/how-we-made-postgresql-as-fast-as-pinecone-for-vector-data/)に記されています。

https://www.timescale.com/blog/how-we-made-postgresql-as-fast-as-pinecone-for-vector-data/

:::note
[先の記事](https://zenn.dev/hmatsu47/articles/pgvectorscale) の時点でバージョン 0.2.0 だった pgvectorscale はその後、バージョン 0.5.0 で StreamingDiskANN インデックス 向けに L2 距離（ユークリッド距離）をサポートしています。

https://github.com/timescale/pgvectorscale/releases/tag/0.5.0
:::

### バージョン 0.8.0（10/31 リリース）

「IVFFlat / HNSW インデックスとベクトル以外の列によるフィルタリングを併用すると、本来抽出すべきデータが抽出できない可能性がある」問題への対処のため、[インデックスの反復スキャン](https://github.com/pgvector/pgvector?tab=readme-ov-file#iterative-index-scans)をサポートしました。

https://github.com/pgvector/pgvector?tab=readme-ov-file#iterative-index-scans

:::note
結果的に、pgvectorscale とは別の実装になっています（pgvectorscale は HNSW インデックスではなく StreamingDiskANN インデックスでこの問題に対処）。
:::

「メモリを超える容量の HNSW インデックスの作成・検索速度が極端に遅くなる」問題については特に対処は行われていないようです。

---

明日（3 日目）は onozaty さんです。

https://zenn.dev/onozaty/articles/schema-spy-postgresql
Githubでライセンスを追加する

先日、オープンソースのライセンスについて記事を書きました。

https://qiita.com/The_Past_of_Dice/items/ef438420542667bed92e

私はビビリなのでこれまでGithubのリポジトリをpublicにしたことはありませんが、Qiitaの記事を書くついでにコードを公開していこうかなと思います。
そうなると曲がりなりにもライセンスを意識した方が良いかなと思いました。

## 新規リポジトリの場合

Githubでリポジトリを新規作成する際は、下記画像のようにライセンスを初期から指定することができます。
意外と多くのライセンスがあるので、是非調べてみてください。

![スクリーンショット 2024-10-21 20.46.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/a702cb6e-acb5-f14c-de47-5d29470534f6.png)

## すでにあるリポジトリにライセンスを付与する

これまでライセンスを意識せずに
今回はすでにライセンスNoneで作成してしまったリポジトリにライセンス追加する方法です。
基本的にはGitHub上で操作していきます。

Add fileをクリックします(画像参照)
![スクリーンショット 2024-10-21 20.16.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/453e20e3-202e-77cd-6a93-ecd2e7db9d11.png)

出てきた画面のファイル名の入力欄に```LICENSE```と入力すると、Edit Preview切り替えボタンの隣に```Choose a license template```と表示されるので、そこをクリックしてください。
(テンプレートを使用せず、ライセンスを自分で描く場合はこのファイルに直接書いてください)
![スクリーンショット 2024-10-21 20.17.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/96f07cee-8e99-b3e7-305a-c6d0fd7fe10c.png)

```Choose a license template```をクリックすると下記画像の画面に移動します。
```Witch license best fits your projest```をクリックしてください。
![スクリーンショット 2024-10-21 20.20.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/7ebe627d-eb75-faf2-fc8d-7dab569e6171.png)

下記画面に移動します。
ここからライセンスを選ぶことができます。
ライセンスは複雑なので、いくつか自分がよく使うものを覚えておいて選ぶといいと思います。
![スクリーンショット 2024-10-21 20.20.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/6f977aca-1b55-7c02-4fbe-2eda0a8f7ca3.png)


ライセンスが問題になるくらいのいいコードを書けるように頑張ります。
ヒストリーテックアドベントカレンダー作りました

歴史研究に使える技術に取り組む、[Code for History](https://www.maplat.jp/)という個人事業を展開しております、こちずふぁんといいます。
どうぞよろしくお願いいたします。

2024年ももう終わりになりました。
今年を含むここ数年を振り返ってみると、歴史研究のビジュアライズ、プレゼンテーションや、歴史研究そのものに技術が使われる事例が、最近とみに増えてきたように感じています。
単に、投稿者は本業で歴史研究に専念しているわけではないので、以前から多かったのに気づいてなかっただけかもしれませんが…。

でも、前から盛り上がってたか今盛り上がりだしたかは別として、特定の技術分野の仲間が集まって毎年12月1日から25日まで1日1記事書く年末のお祭り「アドベントカレンダー」が、歴史技術に関して去年までなかったのは事実だと思います。
そこで、今年から歴史関連の技術を扱う、ヒストリーテックアドベントカレンダーを始めてみました。

アドベントカレンダー名をどうするか悩みました。
* [人文学オープンデータ共同利用センター](http://codh.rois.ac.jp/)さんが提唱している、歴史（ヒストリー）と技術（テック）を組み合わせた概念、[ヒストリーテック](http://codh.rois.ac.jp/sig/history-tech/)を敬意を表して使わせてもらうか
* それとも逆にその中心にいるわけでもない私が勝手にそれを名乗るアドベントカレンダーを立ち上げるのは失礼にあたるので別語を作るか

どちらをとるか悩みましたが、同じ概念を表す言葉がたくさんあっても仕方ないので、最終的に前者としました。
初めて設置するアドベントカレンダーなので、空き日や主催者が埋める日が多くなると思いますが、どなたでも参加はウェルカムなので、ぜひ投稿お願いします。

とりあえずネタは大切にしないといけないので、初日は挨拶まで。
25日間よろしくお願いいたします。
AIとは何か？

以下に、Pythonのコードを交えながらAIについてわかりやすく解説する記事を作成しました。この記事では、AIの基本概念から、機械学習や深層学習の具体例まで、段階的に説明します。

---

## **AIとは何か？**
AI（人工知能）は、コンピュータが人間のように「考え、学び、行動」できる技術です。AIは、パターン認識、データ分析、意思決定などのタスクを自動化し、効率的に行うために設計されています。

---

### **AIの基本的な流れ**
AIシステムの基本的な流れは以下の通りです。

1. **データの収集と前処理**: AIモデルの学習に使うデータを用意します。
2. **モデルの構築と学習**: モデルにデータを与えて学習させます。
3. **予測と応用**: 学習したモデルを使って予測や分析を行います。

---

## **Pythonを使った簡単なAIの例**

ここでは、AIの仕組みを具体的に理解するために、Pythonで「手書き数字を分類するAI」を例に説明します。

### 必要なライブラリをインストール
まず、以下のコードでライブラリをインストールします。

```bash
pip install tensorflow matplotlib
```

---

### **1. データの準備**
AIを学習させるために、MNIST（手書き数字データセット）を使用します。

```python
import tensorflow as tf
from tensorflow.keras.datasets import mnist

# MNISTデータセットの読み込み
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# データの正規化（0〜255のピクセル値を0〜1に変換）
x_train = x_train / 255.0
x_test = x_test / 255.0
```

ここでは、手書き数字の画像データを読み込み、AIが効率的に学習できるように正規化しています。

---

### **2. モデルの構築**
次に、簡単なニューラルネットワークを構築します。

```python
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Flatten, Dense

# モデルの定義
model = Sequential([
    Flatten(input_shape=(28, 28)),   # 画像を1次元に変換
    Dense(128, activation='relu'),  # 隠れ層
    Dense(10, activation='softmax') # 出力層
])
```

- **Flatten**: 28x28ピクセルの画像を1次元の配列に変換します。
- **Dense**: 全結合層で、データを処理します。
- **softmax**: 出力を確率分布に変換します。

---

### **3. モデルのコンパイルと学習**
次に、モデルをコンパイルして学習させます。

```python
# モデルのコンパイル
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# モデルの学習
model.fit(x_train, y_train, epochs=5)
```

- **optimizer='adam'**: 最適化アルゴリズム。
- **loss**: モデルの誤差を計算する関数。
- **metrics**: モデルの性能を評価する指標。

---

### **4. モデルの評価**
学習が終わったモデルをテストデータで評価します。

```python
# モデルの評価
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"テストデータの正解率: {test_acc * 100:.2f}%")
```

---

### **5. 予測の可視化**
学習済みモデルを使って、手書き数字を予測してみましょう。

```python
import matplotlib.pyplot as plt

# テストデータの1つを予測
predictions = model.predict(x_test)
predicted_label = predictions[0].argmax()

# 結果を表示
plt.imshow(x_test[0], cmap='gray')
plt.title(f"予測: {predicted_label}")
plt.show()
```

このコードは、手書き数字の画像を表示し、AIが予測した数字を示します。

---

## **AIの仕組みを簡単に説明**
1. **データの理解**  
   AIは、データを見てパターンを学習します。この例では、手書き数字のピクセルパターンを学習しました。

2. **ニューラルネットワーク**  
   ニューラルネットワークは、層（Layer）を通じてデータを変換し、最終的に結果を出します。

3. **学習と最適化**  
   学習過程では、AIは間違いを修正しながら精度を向上させます。

---

## **AIの応用例**
このようなAI技術は以下のような分野で活用されています。

- **画像認識**: 顔認識、医療診断。
- **自然言語処理**: 翻訳、チャットボット。
- **予測分析**: 売上予測、金融リスク分析。

---

## **まとめ**
この記事では、AIの基本概念とPythonを使った簡単な実装例を紹介しました。AIはデータから学び、人間のように意思決定や予測を行う強力なツールです。Pythonを使えば、初心者でも簡単にAIの仕組みを体験できます。

**次のステップ**として、さらに複雑なモデル（ディープラーニングや自然言語処理）に挑戦してみてください！
コンピュータが言語を理解する仕組み：構文から意味まで

以下は、自然言語処理における「構文（Syntax）」と「意味（Semantics）」の違いを明確にしながら、文法やルールを使ってコンピュータがどのように言語を理解するかを解説した記事です。

---

# コンピュータが言語を理解する仕組み：構文から意味まで

自然言語処理（Natural Language Processing: NLP）は、人間が日常的に使用する言語をコンピュータが理解し、操作する技術です。この分野では、言語の「構造」と「意味」を区別して考えることが重要です。本記事では、構文と意味の違い、そしてコンピュータがそれらをどのように扱うかを説明します。

---

## 構文：言語の「構造」に注目

構文は、文章の単語やフレーズがどのように構造化されているかに焦点を当てます。例えば、以下の2つの文章を比較してみましょう：

1. **例文 1:** 「9時ちょうど前に、シャーロック・ホームズは部屋にさっと入った。」
2. **例文 2:** 「シャーロック・ホームズ9時前ちょうど部屋に入ったさっと。」

最初の文章は正しい文法に基づいて構成されている一方で、2番目の文章は単語が乱雑に配置されており、構文的には正しくありません。

構文は、単語やフレーズがどのように組み合わされて文章を形成するかを明らかにする規則です。これらの規則を理解することで、コンピュータが文章の基本構造を解析できます。

---

## 意味：言語の「中身」を理解する

意味（セマンティクス）は、構文が正しいだけでは不十分で、その文章が何を「意味」するかを考えることです。

### 意味が似ているが異なる構造の例
次の2つの文章を見てみましょう：

- **文章 A:** 「9時ちょうど前に、シャーロック・ホームズは部屋にさっと入った。」
- **文章 B:** 「9時の数分前に、シャーロック・ホームズは部屋に素早く入った。」

構造（構文）は異なりますが、これらの文章はほぼ同じ意味を持っています。理想的には、コンピュータモデルがこれらの違いを認識し、それぞれの文章の意味が非常に似ていることを理解する必要があります。

### 無意味な構文の例
以下の文章を見てみましょう：

- **例:** 「色のない緑のアイデアが激しく眠る。」

この文章は構文的には正しい（形容詞が名詞を修飾し、動詞と副詞の位置も適切）ですが、意味的には矛盾しています。言語を理解するモデルを構築する際、こうした「構文的に正しいが意味が通らない」文章にも対応する必要があります。

---

## 言語のルールをコンピュータに教える方法

### 文法の形式化
言語には規則があります。例えば、英語では「名詞は動詞の前に来る」「名詞は形容詞で修飾される」などです。これらのルールを形式化してコンピュータに与えることで、文章の構造を解析できます。

これを実現する方法の一つが「**文脈自由文法（Context-Free Grammar）**」です。文脈自由文法は、文章を生成するための一連の規則を定義する仕組みです。以下の例を見てみましょう：

### 簡単な文法規則の例
例えば、「She saw the city（彼女は都市を見た）」という文を解析するとします。この文には以下の構成要素があります：

- **名詞（Noun: N）:** she, city
- **動詞（Verb: V）:** saw
- **限定詞（Determiner: D）:** the

これを生成するための文法規則を以下のように定義できます：

1. 文（S）は名詞句（NP）と動詞句（VP）で構成される：  
   `S → NP VP`

2. 名詞句（NP）は名詞（N）または限定詞（D）＋名詞（N）で構成される：  
   `NP → N | D N`

3. 動詞句（VP）は動詞（V）または動詞（V）＋名詞句（NP）で構成される：  
   `VP → V | V NP`

4. 名詞（N）は she または city：  
   `N → she | city`

5. 限定詞（D）は the：  
   `D → the`

### 文法解析の結果
この規則を使うと、「She saw the city」を以下のような構造として解析できます：

- 文（S）
  - 名詞句（NP）: she
  - 動詞句（VP）
    - 動詞（V）: saw
    - 名詞句（NP）
      - 限定詞（D）: the
      - 名詞（N）: city

---

## 文法ルールだけでは足りない場合

言語は非常に複雑で、すべての文章を手作業でルール化するのは困難です。そのため、統計的アプローチや機械学習を使って、より柔軟に言語を処理する方法が採用されています。

---

## 次回予告

次回は、統計的手法やニューラルネットワークを活用して、コンピュータがどのように言語の意味を学び、応用しているかについて詳しく解説します。言語の曖昧さを乗り越え、AIが自然言語をどのように活用するのか、一緒に学んでいきましょう！

--- 

この記事では、構文と意味の基本的な違い、そしてコンピュータがそれらをどのように解析するかについて紹介しました。自然言語処理の世界をさらに深く理解するための第一歩としてお役立てください！
AIとニューラルネットワークの応用：画像認識から自然言語処理まで

以下は「畳み込みニューラルネットワーク（CNN）」や「リカレントニューラルネットワーク（RNN）」などの高度なAI技術の応用例をわかりやすく解説した記事です。

---

# AIとニューラルネットワークの応用：画像認識から自然言語処理まで

人工知能（AI）の進化に伴い、ニューラルネットワークを活用した技術がさまざまな分野で活用されています。本記事では、特に **畳み込みニューラルネットワーク（CNN）** と **リカレントニューラルネットワーク（RNN）** の仕組みと、それらが解決する問題について分かりやすく説明します。

---

## CNN：画像認識の革命

### 畳み込み層とプーリング層
CNNは主に画像認識に利用されるネットワークで、画像の特徴を効率的に抽出するための構造を持っています。その中心となるのが「**畳み込み層**」と「**プーリング層**」です。

- **畳み込み層**  
画像にフィルター（カーネル）を適用してエッジや形状などの特徴を抽出します。例えば、あるカーネルを適用すると、画像内の境界線や輪郭を強調表示することが可能です。

- **プーリング層**  
抽出した特徴マップを縮小し、計算量を減らすとともに、画像内の小さな変化に対してロバスト性（頑健性）を持たせます。一般的に「**最大プーリング（max pooling）**」が使用され、一定範囲の中で最大値を選択します。

### 応用例：手書き文字認識
手書きの数字を認識するタスクでは、CNNが特定の形状や線を学習し、適切な数字を予測します。例えば、MNISTデータセット（0～9の手書き数字データ）を用いると、数万枚の画像をもとにCNNをトレーニングし、98%以上の精度で数字を認識することが可能です。

### 応用例：自動運転と画像処理
自動運転車では、カメラで撮影した道路状況を解析するためにCNNが活用されます。信号機の色や歩行者の位置、他の車両の動きを認識し、安全な運転を実現します。

---

## RNN：時間的なデータの理解

RNNは連続するデータ（時間軸を持つデータ）を扱うのに適したニューラルネットワークです。その特徴は、ネットワークが「過去の状態」を記憶し、それを次の計算に活用できる点です。これにより、以下のようなタスクに利用されます。

### 応用例1：自然言語処理
自然言語処理（NLP）では、RNNが文章や単語の並びを分析します。特に、「**長短期記憶（LSTM）**」と呼ばれる拡張版のRNNが広く使われています。例えば、Google翻訳では、入力された文章（例：「私は猫が好きです」）をRNNが処理し、適切な翻訳（「I like cats」）を生成します。

### 応用例2：動画解析
YouTubeでは、RNNを用いて動画コンテンツの分類を行います。動画は連続するフレームで構成されるため、RNNが各フレーム間の関連性を理解し、動画の内容（例：教育用、音楽、娯楽など）を分類します。

### 応用例3：音声認識
音声データも時間軸を持つため、RNNが効果的です。AppleのSiriやGoogleアシスタントは、RNNを利用して音声をテキストに変換し、ユーザーの意図を理解します。

---

## CNNとRNNの組み合わせ：高度な応用例

CNNとRNNを組み合わせることで、画像と言語を統合的に扱うことも可能です。例えば、「画像キャプション生成」というタスクでは、以下の手順で処理が行われます：

1. CNNが画像を解析し、特徴量を抽出。
2. RNNがその特徴量をもとに、テキスト（キャプション）を生成。  
   - 例：「この画像は、建物の前を歩く人々の集まりです。」

この技術は、MicrosoftのCaptionBotのようなアプリケーションで使用され、写真の内容を文章で説明する能力を実現しています。

---

## AI技術の可能性

CNNやRNNをはじめとするニューラルネットワークは、私たちの生活に多くの価値を提供しています。画像認識、自動運転、音声認識、翻訳サービスなど、これらの技術が私たちの体験を一新しています。将来的には、これらの技術がさらに進化し、AIがより多様な問題を解決することが期待されています。

---

この記事では、AIの中核を担うCNNとRNNの概要と実用例を紹介しました。次回は、AIが自然言語をどのように理解し、活用するかについてさらに掘り下げていきます！
ニューラルネットワークと画像処理の活用例：画像分類と手書き数字認識

### ニューラルネットワークと画像処理の活用例：画像分類と手書き数字認識

ニューラルネットワークを活用する際、単純な線形分離では処理できない複雑なデータ構造に対応するために、**隠れ層 (Hidden Layers)** や**畳み込みニューラルネットワーク (Convolutional Neural Networks; CNNs)** などが用いられます。本記事では、こうした技術の仕組みや応用例について解説します。

---

### **隠れ層を用いた複雑な分類**

#### **隠れ層の役割**
隠れ層を導入することで、単純な線形分離だけでは解決できない問題を処理できます。各隠れニューロンは、それぞれ異なる**決定境界**（線や曲線）を学習し、これらを組み合わせることで、複雑なデータ構造を分類する能力を向上させます。

#### **例：青点とオレンジ点の分類**
以下のような例で説明します。

1. **1つの隠れニューロン**：
   - 最初のニューロンは、青点とその他の点を分離する境界線を学習。
   - もう1つのニューロンは、オレンジ点を分離する境界線を学習。
   - しかし、完全な分類は難しい。

2. **ニューロンを追加**：
   - 隠れ層に3つ目のニューロンを追加すると、それぞれ異なる境界線を学習し、データ分類が改善。
   - さらにニューロンを増やすことで、分類精度が向上。

3. **決定境界の可視化**：
   - 各ニューロンの学習結果は、青点とオレンジ点を分けるための異なる境界線を形成します。
   - 境界線の「強さ」や「太さ」は、重み（入力の重要性）を示します。

---

### **畳み込みニューラルネットワーク (CNN)**

#### **CNNの概要**
CNNは、特に画像データの解析に効果的なニューラルネットワークで、以下の3つの主要ステップで構成されます：
1. **畳み込み (Convolution)**：
   - 画像に**フィルタ**（カーネル）を適用して特徴を抽出。
   - エッジや曲線、形状などの情報を強調します。

2. **プーリング (Pooling)**：
   - 画像サイズを縮小し、処理の効率化とロバスト性を向上。
   - **最大値プーリング (Max Pooling)** が一般的で、指定した領域の最大値を採用。

3. **全結合層 (Fully Connected Layer)**：
   - プーリング後のデータを平坦化し、従来のニューラルネットワークに入力。

#### **畳み込みの仕組み**
畳み込み操作は、画像の各ピクセル値とフィルタを掛け合わせ、その結果を足し合わせることで行います。例えば、エッジ検出用のフィルタを適用すると、隣接するピクセル値の違いを際立たせ、画像の境界を抽出できます。

#### **プーリングの仕組み**
プーリングは、画像のサイズを縮小するための操作です。例えば、2×2の最大値プーリングを使用すると、次のように最大値を抽出します：

| 元の画像 (4×4) | プーリング結果 (2×2) |
|---------------|----------------------|
| 50, 10, 20, 30 | 50, 110              |
| 110, 40, 10, 20|                     |
| 20, 30, 10, 40 |                     |
| 40, 10, 5, 10  |                     |

この結果、データ量が削減され、計算効率が向上します。

---

### **CNNの実装例：手書き数字認識**

#### **MNISTデータセットの活用**
MNISTは、手書き数字（0～9）の画像データセットです。各画像は28×28ピクセルの白黒画像として表現され、ピクセル値は0～255の範囲で示されます。

#### **TensorFlowによる実装**
以下は、TensorFlowを用いてCNNを構築する手順です。

1. **データ前処理**：
   - ピクセル値を0～1の範囲に正規化。
   - データをトレーニング用とテスト用に分割。

2. **CNNの構築**：
   - **畳み込み層**：
     - フィルタサイズ：3×3
     - フィルタ数：32
     - 活性化関数：ReLU
   - **プーリング層**：
     - 最大値プーリングで画像を縮小。
   - **全結合層**：
     - 平坦化後、出力層で0～9の分類を行う。

3. **モデルの訓練**：
   - トレーニングデータでモデルを訓練。
   - エポック数を増減させて精度を調整。

---

### **応用と可能性**

CNNは、手書き認識以外にも以下の応用が可能です：
- **医療画像解析**：X線やMRI画像の異常検出。
- **自動運転**：道路標識や障害物の認識。
- **顔認識**：写真や動画からの顔検出。

これらの技術は、画像解析や自動化の分野で広く活用され、今後さらに進化する可能性があります。

---

### **まとめ**

隠れ層やCNNを活用することで、単純なニューラルネットワークでは対応できない複雑な分類問題や画像解析が可能になります。特に、CNNは画像処理に特化した構造を持ち、畳み込みとプーリングを通じて効率的かつ精度の高い解析を実現します。これらの技術を応用して、さらなる課題解決や新たな可能性を探求してみてください。
強化学習における探索と活用：EpsilonグリーディアルゴリズムとNimゲームの学習

### 強化学習における探索と活用：EpsilonグリーディアルゴリズムとNimゲームの学習

---

強化学習 (Reinforcement Learning) は、エージェントが環境と相互作用しながら報酬や罰を基に行動を学ぶ手法です。この過程では「探索 (Exploration)」と「活用 (Exploitation)」のバランスが重要です。本記事では、この2つの概念と、それを調整するためのアルゴリズムであるEpsilonグリーディアルゴリズムについて解説し、簡単なゲームを題材にその応用を紹介します。

---

### **探索と活用のジレンマ**

#### **探索 (Exploration)**

探索とは、未知の行動を試み、新しい可能性を模索することを指します。例えば、ある行動がどのような結果をもたらすのかが未知の場合、その行動を試してみることで新たな報酬を得る可能性があります。

#### **活用 (Exploitation)**

活用とは、既存の知識に基づいて、過去に良い結果をもたらした行動を繰り返すことです。エージェントは、既に学んだ「最適な」行動を選択することで、短期的に高い報酬を得ようとします。

#### **ジレンマの重要性**

探索に偏りすぎると効率的に報酬を得られず、活用に偏りすぎると未知の可能性を見逃してしまいます。このジレンマを解決するために、多くのアルゴリズムが開発されています。

---

### **Epsilonグリーディアルゴリズム**

Epsilonグリーディアルゴリズムは、探索と活用のバランスを取るためのシンプルな手法です。このアルゴリズムでは、以下のルールに従って行動を選択します：

1. **確率 \( 1 - \epsilon \)** で、既知の最善の行動を選択する（活用）。
2. **確率 \( \epsilon \)** で、ランダムな行動を選択する（探索）。

ここで、\( \epsilon \) は探索の頻度を制御するパラメータであり、0から1の間の値を取ります。例えば、\( \epsilon = 0.1 \) であれば、10%の確率で探索を行い、90%の確率で最善の行動を選択します。

---

### **Epsilon値の調整**

- **初期段階**では高い \( \epsilon \) 値を設定し、探索を優先することで多様な行動を試みます。
- **学習が進むにつれて**、\( \epsilon \) を徐々に減少させ、より多くの時間を最善行動の活用に費やします。

---

### **Nimゲームの例**

Nimは、強化学習を用いて学習可能なシンプルなゲームです。以下にゲームのルールと学習の過程を紹介します。

#### **ゲームのルール**

1. 複数の山があり、各山には異なる数のオブジェクトがあります（例：1個、3個、5個、7個）。
2. プレイヤーは1ターンに1つの山から1つ以上のオブジェクトを取り除きます。
3. 最後のオブジェクトを取ったプレイヤーが負けです。

#### **学習の流れ**

1. **初期状態**：AIはランダムに行動し、報酬や罰を記録します。
   - 最後のオブジェクトを取った場合は負け（罰：-1）。
   - 相手が最後のオブジェクトを取った場合は勝ち（報酬：+1）。
2. **自己対戦**：AIが何千回も自分と対戦し、各行動の結果を学びます。
3. **人間との対戦**：学習した知識を活用し、戦略的に行動します。

#### **実験結果**

初期段階ではランダムに行動するため、簡単に勝つことができます。しかし、AIが1万回以上自己対戦を行った後では、戦略的に行動し、人間が勝つのが難しくなります。これにより、強化学習がゲーム戦略の習得に有効であることが示されます。

---

### **探索と活用の拡張**

Nimのような簡単なゲームでは全ての状態を探索できますが、チェスのように状態空間が膨大なゲームでは、すべての状態を学習するのは非現実的です。そのため、以下のような方法で学習を効率化します。

- **関数近似**：各状態と行動の組み合わせを直接学習するのではなく、特徴量を基に報酬を予測する関数を学習します。
- **特徴量エンジニアリング**：状態を特徴量に分解し、似たような状態に適用可能な一般的なパターンを学習します。

---

### **まとめ**

Epsilonグリーディアルゴリズムは、探索と活用のバランスを取り、強化学習の効率を向上させるシンプルかつ効果的な手法です。このアルゴリズムを用いることで、ゲームのようなタスクにおける効果的な行動戦略を学習できます。探索を重視する初期段階から、活用を重視する後期段階への移行を調整することで、長期的な報酬を最大化することが可能です。
アーク整合性とバックトラッキング探索：制約満足問題を効率的に解く手法

### アーク整合性とバックトラッキング探索：制約満足問題を効率的に解く手法

制約満足問題 (Constraint Satisfaction Problem, CSP) を効率的に解くためには、アーク整合性 (Arc Consistency) とバックトラッキング探索の手法を組み合わせることが重要です。本記事では、これらのアルゴリズムの詳細と、制約満足問題の解決における応用について解説します。

---

### **アーク整合性 (Arc Consistency) とは？**

アーク整合性は、制約グラフにおける変数間の制約を考慮し、不整合な値をドメインから除外するプロセスです。これにより、探索空間を縮小し、効率的に問題を解くことが可能になります。

#### **アーク整合性のプロセス**

1. **初期化**  
   制約グラフ内のすべてのアークをキューに追加します。

2. **整合性の確認**  
   キューからアークを取り出し、アーク整合性を確認します。例えば、変数 \( X \) のドメインから値を選び、それが隣接する変数 \( Y \) のドメインと一致するかを調べます。不一致の場合は、その値を \( X \) のドメインから削除します。

3. **隣接アークの更新**  
   もし \( X \) のドメインが更新された場合、その変更が影響を及ぼす隣接アークをキューに追加します。

4. **終了条件**  
   キューが空になれば、アーク整合性の処理は完了です。

---

### **AC3アルゴリズムの詳細**

AC3 (Arc-Consistency 3) アルゴリズムは、アーク整合性を効率的に適用する手法です。このアルゴリズムでは、以下の手順が実行されます。

1. **キューの準備**  
   問題に関連するすべてのアークをキューに追加します。

2. **アークのチェック**  
   キューからアーク \( (X, Y) \) を取り出し、\( X \) のドメインから不整合な値を削除します。

3. **再確認のアーク追加**  
   \( X \) のドメインが変更された場合、その影響を受ける隣接するアーク \( (Z, X) \) をキューに追加します。

4. **終了**  
   キューが空になるまで処理を繰り返します。

---

### **AC3とバックトラッキング探索の統合**

AC3アルゴリズムは、探索開始前または途中で実行することで、変数のドメインを事前に縮小し、探索効率を向上させます。以下に、バックトラッキング探索と統合した手法を示します。

#### **バックトラッキング探索**

バックトラッキング探索は、再帰的に変数に値を割り当てながら制約をチェックする手法です。矛盾が発生した場合は、直前の割り当てに戻り、別の値を試みます。

```python
def backtrack(assignment, problem):
    if is_complete(assignment, problem):
        return assignment
    var = select_unassigned_variable(assignment, problem)
    for value in order_domain_values(var, assignment, problem):
        if is_consistent(var, value, assignment, problem):
            assignment[var] = value
            inferences = ac3(problem, var)  # アーク整合性を適用
            if inferences is not None:
                result = backtrack(assignment, problem)
                if result:
                    return result
            del assignment[var]
    return None
```

---

### **効率化のためのヒューリスティクス**

探索効率をさらに向上させるために、以下のヒューリスティクスを活用します：

1. **最小残余値 (Minimum Remaining Values, MRV)**  
   ドメインサイズが最も小さい変数を優先して選択します。制約の影響が大きい変数を先に処理することで効率化を図ります。

2. **最大制約次数 (Degree Heuristic)**  
   他の変数と最も多くの制約を共有する変数を優先的に選択します。これにより、早期に矛盾を発見できます。

3. **最小制約値 (Least Constraining Value)**  
   他の変数のドメインを最小限に制約する値を優先します。これにより、後続の探索が容易になります。

---

### **実践例：試験スケジューリング問題**

#### **問題設定**  
7つの試験 (A～G) を、月～水曜日の3つのスロットに割り当てます。制約として、同じ日に複数の試験を受けることはできません。

#### **結果**  
AC3アルゴリズムとバックトラッキング探索を組み合わせることで、以下の割り当てが得られました：

- **月曜日**: A, E  
- **火曜日**: B, F  
- **水曜日**: C, D, G

この割り当てはすべての制約を満たしています。

---

### **まとめ**

AC3アルゴリズムとバックトラッキング探索は、制約満足問題を効率的に解くための強力なツールです。さらに、ヒューリスティクスを組み合わせることで、探索空間を最小化し、効率的な解決が可能になります。これらの手法は、スケジューリング問題やパズルの解決など、多岐にわたる応用が可能です。
gitの操作

## 記事の概要
git操作をVSCodeから行うコマンドの一覧が欲しかったので...
## ブランチを切ってからプッシュするまで
### ブランチを切る
```terminal
$ git checkout -b ブランチ名
```
### ブランチのコードをmainにコミットする
```terminal
$ git checkout main
$ git merge マージしたいブランチ名
$ git add .
$ git commit -m 'コミットメッセージ'
```
### リモートにプッシュする
```terminal
$ git push
```
### ブランチの確認から削除
```terminal
$ git branch
$ git branch -d 削除したいブランチ名
```
局所探索アルゴリズムと最適解へのアプローチ：ヒルクライミング、ランダムリスタート、焼きなまし法の実践

# **局所探索アルゴリズムと最適解へのアプローチ：ヒルクライミング、ランダムリスタート、焼きなまし法の実践**

最適化問題を解く際、完全な解空間を探索するのは時間がかかりすぎる場合があります。この記事では、局所探索アルゴリズムを使って効率的に「かなり良い解」を見つける方法を紹介します。特に以下の3つの手法に焦点を当てます：
1. **ヒルクライミング（Hill Climbing）**
2. **ランダムリスタート（Random Restart）**
3. **焼きなまし法（Simulated Annealing）**

---

## **1. 局所探索の限界：局所最適解と大域最適解**
局所探索では、現在の状態とその隣接状態（近い配置）を基にコスト関数や目的関数を評価します。しかし、局所最適解に陥る可能性があります。局所最適解はその近隣では最善ですが、全体の中で最善ではない場合もあります。

例として、病院の配置問題を考えます：
- **目標**: 各家から最寄りの病院までの距離の合計（コスト）を最小化する。
- **課題**: 隣接する状態のみを探索すると、大域最適解（最良の配置）を見つけられない可能性がある。

---

## **2. ランダムリスタート：局所最適解からの脱出**
ランダムリスタートは、ヒルクライミングの欠点を克服するための手法です。単に探索を1回行うのではなく、複数回ランダムに初期状態を生成し、それぞれでヒルクライミングを実行します。

### **ランダムリスタートの手順**
1. ランダムに初期状態を生成。
2. ヒルクライミングを実行して局所最適解を見つける。
3. 結果を記録し、次の初期状態で再び探索。
4. 全探索が終了したら、最良の解を選択。

### **実例**
- 初期状態のコスト: 56
- 20回のリスタートで以下の結果を得る：
  - 最良コスト: 41（3回目の試行）
  - 他の試行では41より良い結果は得られなかった。

ランダムリスタートは計算時間が増加するものの、局所最適解に囚われるリスクを減らす効果があります。

---

## **3. 焼きなまし法：悪い選択を許容して大域最適解を目指す**
焼きなまし法（Simulated Annealing）は、物理学の「焼きなまし」プロセスに基づいた手法です。このアルゴリズムは、高温の状態ではランダムな探索を許容し、低温になるにつれて探索範囲を狭めるという特性を持ちます。

### **焼きなまし法の基本概念**
1. **高温の状態**:
   - より悪い状態（コストが高い状態）への移動を許容。
   - ランダム性が高く、探索範囲が広い。
2. **低温の状態**:
   - より悪い状態への移動を抑制。
   - 解が収束し、大域最適解に近づく。

### **焼きなまし法の擬似コード**
```python
def simulated_annealing(problem, max_iterations):
    current = problem.initial_state()
    for t in range(1, max_iterations + 1):
        temperature = calculate_temperature(t, max_iterations)
        neighbor = random_neighbor(current)
        delta_e = problem.evaluate(neighbor) - problem.evaluate(current)
        
        if delta_e > 0 or random.uniform(0, 1) < math.exp(delta_e / temperature):
            current = neighbor
    
    return current
```

- **`temperature`**: 温度スケジュール。初期では高温、後半で低温。
- **`delta_e`**: 状態の改善量。正の値なら移動。負の場合も確率で移動。

### **焼きなまし法の効果**
焼きなまし法は、局所最適解から抜け出すために時折「悪い選択」を許容するため、大域最適解を見つける可能性を高めます。

---

## **4. 応用例：巡回セールスマン問題**
巡回セールスマン問題（TSP）は、複数の都市を最短距離で巡回するルートを見つける問題です。

### **TSPの定式化**
- **目標**: 総移動距離を最小化。
- **隣接状態**: ルート内の2辺を選び、それらを交換。

焼きなまし法を適用すると、ルートをランダムに変更しながら最良のルートを探索できます。例として、次のような改善が可能です：
1. ルートの2辺を選んで接続を変更。
2. 新ルートが改善されれば採用。悪化しても確率で採用。

---

## **5. まとめ**
局所探索アルゴリズムは、最適解を効率的に近似する強力な手法です：
- **ヒルクライミング**: 単純かつ高速だが局所最適解に陥る可能性あり。
- **ランダムリスタート**: 複数回試行することで局所最適解からの脱出を図る。
- **焼きなまし法**: ランダム性を活用し、大域最適解を目指す。

これらの手法を問題に応じて適切に選択することで、効果的な解を得ることが可能です。
文章題で身に付くプログラミング思考入門️（1/25）

## 知ってた？話が噛み合わない理由は、たった1つ。
### はじめに

話が噛み合わなかった経験、ない人いますか？
いませんよね？いたら連絡ください。

では、話が噛み合わない本当の理由を知ってますか？
実は知識の違いでも、前提の違いでも、話の組み立て方でも整理不足でも話を聞かないわけでも思い込みが激しいわけでもなく、**抽象度の違いです。**

抽象度を合わせることができれば、どんな人とも話を噛み合わせることができます。

### そしてエンジニアは、抽象度を操ることでコンピュータとの対話をコントロールします。

『文章題で身に付くプログラミング思考入門️』は、日常や文章問題からプログラミング思考を身に付けていく、簡単で身近で、あなたをちょっと輝かせてくれるシリーズです。

今回は抽象度についてお話ししていきましょう。

## 対象者
- プログラミングを学びたい人
- プログラミングに挫折したことのある人
- 論理的思考を鍛えたい人
- 文系の人
- エンジニアの思考を理解したい人

## 概要
ところで、国語のテストでバツをもらって、納得いかなかったことはありませんか？
それも、抽象度の違いが原因なんですね。

例えば、夏目漱石『吾輩は猫である』の冒頭部分から借りてきましょう。

> *吾輩は猫である。名前はまだ無い。
どこで生れたかとんと見当がつかぬ。
何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。*

さて、問題です。

#### ①「吾輩」は *何と* 泣いていたでしょうか？
答えは
- ニャーニャー

ですね。

#### ②「吾輩」は *どんな所* で泣いていたでしょうか？
- じめじめした所
- 薄暗い所
- 薄暗いじめじめした所
- じめじめした薄暗い所

文脈的には、どれも正しいですよね。
ただし、これがテストだったら、どれも正解なんてことはないでしょう。
だって、テストは『正答とあなたの回答が同じであれば正解』ですから。
**厳格なルールがあります。正答と同じ答えを出さないといけません。**

では、なぜ①ではたった一つの答えが導けたのでしょうか？

> ①「吾輩」は *何と* 泣いていたでしょうか？

そうです、質問が明確だったからです。
別の言い方をすると、**あなたの中で、答えるべき内容が明確に特定できたからです。**

逆に、どんな所？と聞かれたときは、イメージの細かさが人によって変わってきます。

> ②「吾輩」は *どんな所* で泣いていたでしょうか？


人は、あらゆる情報をイメージで理解しています。
ですから、曖昧な質問は、イメージの抽象度を曖昧にするので、答えを曖昧にします。
逆に言えば、**何が知りたいのかを明確に定義すれば、明確な答えを得ることができます。**

### 質問と答えの明確さを揃えましょう。これがプログラミングの本質です。

日常会話でも、情報の明確さ・曖昧さを相手と合わせることがコミュニケーションの助けになります。
知らない概念が出てくれば、聞き返せば良いのです。自分が理解できる抽象度で「例えば・つまり、こういうことですか？」と聞いてみましょう。
言いたいことがわかってもらえないのなら、相手の経験に例えて伝えてみましょう。イメージ化に成功すれば、伝わります。

諦める必要はありません。重要なのは、相手を理解しようとする姿勢です。
その姿勢が伝われば、相手はあなたと向き合ってくれます。
そして、人でもコンピュータでも同じ。**やりとりする情報を、相手の抽象度に合わせることです。**

では試しにやってみましょうか。
②をどのように変えたら、「吾輩」が泣いていた場所について明確な答えが得られるでしょうか？

> ②「吾輩」は *どんな所* で泣いていたでしょうか？

例えば、私はこのように変えてみました。

②「吾輩」は、どのような暗さの所で泣いていたでしょうか？
②「吾輩」が泣いていたのは、からっとした所でしたか？それともじめじめした所でしたか？

どうですか？さっきよりもずっと明確に答えられそうですね。

質問と答えの明確さを揃える。
これができるようになれば、プログラミングのコードが書けます。

よく日本語は難しい言語だと言われますが、そのおかげで、日本語を話す私たちは曖昧を理解して意味を特定するトレーニングを日常的に行っています。

### 要するに、曖昧さを明確にできる能力を既に持っているのです。

質問の曖昧さに気づいたあなたは素晴らしい。
すでにプログラマーの素養があります。

質問を明確にする大切さを知ったあなたは素晴らしい。
このシリーズを読み終わる頃には、プログラミングの基本を習得しているでしょう。

次回は、[なぜプログラミング思考力に文章題が有効なのか](https://qiita.com/yuki-TheWaggle/items/7ab3f08b9bab012c98ee)について解説します。


## まとめ
- エンジニアは、抽象度を操ることでコンピュータとの対話をコントロールします。
- 質問と答えの明確さを揃えましょう。これがプログラミングの本質です。
- 日本語を話す私たちは、曖昧さを明確にできる能力を既に持っているのです。

## 最後に
ここまで読んでくださってありがとうございます！
ちょっとでも役に立ったら「いいね」をください。続ける励みになります。
あと、初めてQiita Advent Calendarに参加してみてます。よくわからないです。ぬいぐるみ欲しいです。
どうしたらいいんでしょうか。これで合ってますか？
知ってる方、コメントで教えてください。
隠れマルコフモデル（Hidden Markov Model, HMM）の解説：不確実性に対処するAIの仕組み

### **隠れマルコフモデル（Hidden Markov Model, HMM）の解説：不確実性に対処するAIの仕組み**

現実世界の多くの問題では、AIは「真の状態（hidden state）」を直接観測できず、その結果として得られる「観測（observation）」だけを頼りに推論を行う必要があります。隠れマルコフモデル（HMM）は、こうした状況をモデル化し、不確実性を扱うための有力な手法です。本記事では、HMMの仕組みや、その活用法についてわかりやすく説明します。

---

### **1. 隠れた状態と観測の関係**

HMMは以下の要素で構成されます：
- **隠れた状態（Hidden State）**  
  実際には存在するが直接観測できない変数（例：天気、ユーザーの意図）。
  
- **観測（Observation）**  
  隠れた状態に基づいて得られるデータ（例：傘を持参したかどうか、音声波形）。
  
- **状態遷移（State Transition）**  
  時間に伴う隠れた状態の変化（例：晴れ→雨の確率）。
  
- **センサー・モデル（Sensor Model, Emission Probabilities）**  
  各隠れた状態から観測が生成される確率（例：雨なら傘を持参する確率が高い）。

---

### **2. HMMの仕組みを理解する例：天気と傘の観測**

#### **2.1 シナリオ**
ある建物に設置されたAIが、社員が持参する「傘」の観測データを基に、外の「天気」を予測するシステムを考えます。以下が前提です：
- **隠れた状態（天気）**: 晴れ (Sunny) または 雨 (Rainy)
- **観測（傘の持参）**: 傘あり (Umbrella) または 傘なし (No Umbrella)

#### **2.2 状態遷移モデル**
天気が時間経過で変化する確率：
- **晴れの翌日は晴れ**: 80%  
- **晴れの翌日は雨**: 20%  
- **雨の翌日は雨**: 70%  
- **雨の翌日は晴れ**: 30%

#### **2.3 センサー・モデル**
各天気における観測の確率：
- **晴れの日の傘持参確率**: 20%  
- **晴れの日の傘未持参確率**: 80%  
- **雨の日の傘持参確率**: 90%  
- **雨の日の傘未持参確率**: 10%

---

### **3. HMMのPython実装**

HMMをPythonで実装してみます。

#### **3.1 必要なライブラリの準備**
`pomegranate`ライブラリを使用します。

```python
from pomegranate import *

# 状態遷移モデルの定義
transitions = [[0.8, 0.2],  # 晴れから晴れ・雨
               [0.3, 0.7]]  # 雨から晴れ・雨

# 観測モデルの定義
emissions = [[0.8, 0.2],  # 晴れの日の観測（No Umbrella, Umbrella）
             [0.1, 0.9]]  # 雨の日の観測（No Umbrella, Umbrella）

# 開始確率
starts = [0.5, 0.5]  # 初日が晴れ・雨の確率

# HMMモデルの構築
model = HiddenMarkovModel.from_matrix(transitions, emissions, starts, 
                                      states=["Sunny", "Rainy"],
                                      symbols=["No Umbrella", "Umbrella"])
model.bake()
```

---

### **4. 推論の実行**

#### **4.1 観測データから最も可能性の高い状態列を推定**

観測データ（例：`["Umbrella", "Umbrella", "No Umbrella", "Umbrella"]`）を基に、最も可能性の高い天気のシーケンスを予測します。

```python
observations = ["Umbrella", "Umbrella", "No Umbrella", "Umbrella"]

# 最適な状態列を推定
predicted_states = model.predict(observations, algorithm="viterbi")
state_names = [model.states[state].name for state in predicted_states]

print(f"観測: {observations}")
print(f"推定された天気: {state_names}")
```

出力例：
```
観測: ['Umbrella', 'Umbrella', 'No Umbrella', 'Umbrella']
推定された天気: ['Rainy', 'Rainy', 'Sunny', 'Rainy']
```

この結果から、以下のことが推測されます：
- 最初の2日間は雨。
- 3日目は晴れ。
- 4日目に再び雨が降った。

---

### **5. HMMの応用例**

#### **5.1 音声認識**
観測：音声波形  
隠れた状態：発話された単語  
HMMを用いて、音声波形から単語列を推定できます。

#### **5.2 ユーザー行動の推測**
観測：クリックデータやページ閲覧時間  
隠れた状態：ユーザーの興味や意図  
ウェブサイトのUX改善に活用可能です。

---

### **6. HMMの限界と拡張**

HMMは非常に強力ですが、以下の限界があります：
- **過去の履歴の影響**: 状態は直前の状態にしか依存しないという仮定（マルコフ性）。
- **高次元データへの適用**: 観測や状態が多くなると計算が複雑化。

#### **6.1 拡張モデル**
- **条件付き確率場（CRF）**: より柔軟な依存関係をモデル化。
- **長短期記憶（LSTM）**: 深層学習を用いた時系列データの解析。

---

### **7. まとめ**

隠れマルコフモデル（HMM）は、不確実なデータから隠れた情報を推論するための基本的かつ重要なフレームワークです。Pythonライブラリを用いることで、複雑な計算を簡潔に実行可能です。本記事を基に、さまざまな現実問題への応用を試みてください。
Sourcetreeの使用に至る苦難と格闘の日々

# 藪をつついたら出た「大蛇」
これは、秋葉原ロボット部と関連した団体秘密結社オープンフォースの総統(@nanbuwks)とオンライン朝活をしていた時のこと…

秋葉原ロボット部のQiitaアドベントカレンダー2024の12月1日ぶんの担当者がいないため、総統から私に何か書きませんかと打診があった。
私は他の執筆があるためアドベントカレンダーに割くネタが無いと断ったら、以前共に苦労して設定したSourcetreeのことについて書きませんかと打診された。
現環境は執筆に使用しているため再度設定して壊したくないと断ったら、ではN100搭載WindowsPCを送りますのでそれを使ってくださいと打診された。

もしここで断ると、せっかくだからOS無しPCにubuntuを新規インストールしてからSourcetreeを設定してくださいと無茶ぶりされかねない。断るわけにはいかなくて藪をつついたら蛇が出たと私が呟くと、総統は（恐らく満面の笑顔で）大蛇をバンバン出していくスタイルでと返してきた。

かくして…
こうして再度、あの苦労したSourcetreeの設定を行うこととなったのだが…

# 補給経路は大事です
執筆している現在、N100搭載WindowsPCは手元にない。補給経路のどこかで不具合が生じたらしく物資が滞っているようだ。
それでも期限はやってくる。それがアドベントカレンダーという戦場だ。
この苦境を持ちこたえるべく、ここからは以前Sourcetreeを設定した時に生じた苦労を記そうと思う。
なお、N100WindowsPCが到着次第インストール顛末を追記するものとする。

# そもそも何故、Sourcetreeを使うことに？
宇宙関連の原稿 (https://github.com/busyoucow/spacefarm) を執筆するため、総統と朝活で~~喧々諤々~~議論しながら執筆内容やエビデンスを決めていたのだが、執筆した原稿内容を複数人で共有しながらバージョン管理するのに無期限無料で使える方法はないかと悩んでいた。


執筆はVSCodeを使用して (https://qiita.com/nanbuwks/items/56dad2c4d6a640f550e2#css-%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B) markdown形式で記述した後にGitHubへとアップロードしていた。印刷時はVSCodeでPDFファイルを作るか、総統側でmarkdownファイルを紙の原稿に適する形へ変換していた。

ある日バージョン管理ツールの使い方を覚えましょうと総統に言われこちら (https://qiita.com/nanbuwks/items/88027947b07bc1683209) を参照しながらSourcetreeを使用することとなった。

ちなみにコマンドベースでpushすればよいという意見もあるが、かくいう私がエンジニアにあるまじくコマンドライン入力のスペルミスやキーボードのチャタリングが多いので、ミス要因を減らすためにもバージョン管理ツールを使うものとした。
~~決して総統と執筆した誌面について食い違いが発生して別々のpushが発生したからではない。~~

# ようやく到着
N100搭載Windows11コンパクトPCが届いたので、早速セットアップ。お弁当を温められそうなくらい発熱があるがこれで正常らしい。この機種はファンレスなので特に発熱があるようだ。

https://qiita.com/nanbuwks/items/1ee463e2e9dac174c6f1

ダ〇ソーのステンレストレイをひっくり返してPCを乗せポータブルファンをあて発熱をどうにかする。朝ごはんも乗せてみよう（非推奨）
サンドボックス環境を整え、いざゼロベースでGithubリポジトリを作成してSourcetreeをインストールし設定する。

# gitコマンドが使えない？

https://qiita.com/nanbuwks/items/88027947b07bc1683209

上記を参照しながらSourcetreeを設定していくが、上記記事の前提条件として次にあげる事前準備が記載されていた

- GitHub にログオンできる状態にしておく
- GitHub にレポジトリを作っておく

ログオンについてはGitHubにサインインすれば良いので問題はないのだが

レポジトリを作っておく　でどこまでレポジトリを作っておけばよいかで悩んだ。
特にpushまで作っておかないといけないかと思い別途ネット上の情報を基にコマンドプロンプトでgit initをおこなったのだが

![screen.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327408/d7068e7e-6e40-fcf5-2fbc-990dfd2e105d.jpeg)
どうやらgitコマンドは専用アプリをインストールしないと使えないらしい。

そもそもgitはCUIベースのローカル上でインストールして使う管理ツールでありGithubはGUIベースのオンラインサービスである。
言い換えれば宿題を自己学習するか〇文教室でみてもらいながら行うのかの違いであろう。

# Sourcetreen内のターミナルを使う

SourcetreeではGUIの操作だけではなくGUI画面からターミナルを呼び出すことができる。そのターミナルではgitコマンドが使用できる。

Sourcetree用のgitコマンドがインストールされているらしい。またをgitの初期化コマンドであるgit initをしないといけないかと思ったが上記記事の前提条件であれば、Github上でgit initが済んでいる状態なのでローカルで行う必要はない。

Sourcetreeでレポジトリのクローンを行った後指定したフォルダにファイルを作成すればSourcetree上でコミットとプッシュが行える。

# バージョン管理ツールを使ってみて
コミットとプッシュ時にミスがほとんど出ないのはとても安心できると感じた。
また差分がわかりやすく表示され手戻り時もどこまで戻ればよいか、同時に複数人からコミットがあったときもどうなっているのかわかりやすいのがとても良かった。
ただ、権限付与の問題もあり既存のある程度書いたリポジトリを複数人で共有したり複製したりするときは手順をきちんと確認して行わないと完全な形になりにくいといけないと感じた。

# 最後に
N100搭載WindowsPCの上に乗せて温めたヤ〇ザキのチーズバーガーを食べながら、CUIの是非について考えてみた。
CUIであるコマンドラインは慣れれば素早く操作できるようだが、直感的な操作はGUIに軍配が上がる。
今後のITに必要なのは「慣れた」人向けのものなのか。それとも「慣れてない」人向けのものなのか。
昭和から平成中期までは圧倒的に前者だった。慣れるのがエンジニアとしての務めだった。
しかし現在はローコードやノーコードが流行り、宣伝でも「慣れてない」人向けのツールやプラットフォームが幅をきかせる。

ITは主にどちらへ向かうべきなのか。かつて技術立国と呼ばれた日本の凋落をみて考えを巡らせるが、まだ答えは出ない。
レトロPCのためのBASIC講座１　電源投入からプログラムを書くまで

# NEC PC-8801のBASIC
NECから1981年発売のPC-8801に搭載されていた、N88-BASICについて書いていこうと思いっます。

# 電源を入れると・・・
以下のような画面で起動します。
![PC-8801.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529369/e1e9c71e-53d4-cb06-f5b8-3227627ada86.png)

この黒い画面にカーソルがチカチカした状態で、カーソル自体は矢印キーで上下左右に動かすことができます。
基本的にこの状態で命令待ち状態になっているので例えば、１＋２という計算をして答えを表示したい場合は、BASICのPRINT命令を使って計算結果を出します。
なのでこの黒い画面で
PRINT １＋２[ENTER]
と打ち込んで２の後ろにカーソルがある状態で［Enter］キーを押すと、PRINT命令が実行され結果が表示されます。

# プログラムとして動かすためには？
この１行をプログラムにするには先頭に行番号という番号をつけて、スペースを１つ開けて命令を書き[ENTER]キーを押すとプログラムとして登録されます。
例
１０　PRINT １＋２[ENTER]

プログラムとして登録されたか確認するために
LIST[ENTER]
としてみると登録されたプログラムが表示されます。

# 実行するには？
登録されたプログラムを実行するには
RUN[ENTER]
で実行されます。
プログラムは、リセットするか電源が切れるまでメモリに残っているので残っているプログラムを消すために
NEW[ENTER]
で消すことができます。

# 以上の動画
https://youtu.be/D-ToAlUSSIs
Elixirのチートシートを作ろう。



# 1. OverView

お疲れ様です。小野寺です。
いやー、一年再開にかかりました。
いやぁ、覚える端からElixirの文法を忘れまして、年は取りたく…いや、お前は昔からだろう。

と言うわけでElixir Schoolの課題をこなしながら、チートシートを作っていこうと思いました。

その前に、Elixir School、綺麗にまとまっている上に、いろんなヒントがあっていいのですが、
一つ問題があって、ちょくちょく、そこまでで説明されてない機能が出てくるのが難点。
そこくらいは解説出来ればと思ってます。

本日のお題はここです。

    https://elixirschool.com/ja/lessons/basics/basics

    
# 2. まずは解説
1. 整数
```
　  整数    255
    2進数       0b0110
    8進数       0o644
    16進数      0x1F
```


2. 浮動小数
    「Elixirでは、浮動小数点数は少なくとも1桁の数字とその後に続く小数を必要とし、64ビットの倍精度で、指数 e に対応しています」
    と書いてありますね。

```
    3.14
    .14 -> エラー、最初に1桁以上の数字と、その後に続く少数が必要
    0.14 
    1.0e-10 指数 e ですね。
```

3. 真理値
```
    true
    false

    false と nil 以外は真なることに注意。
```

4. アトム
```
    自身の名前がそのまま値になる定数です
    :で始まり、英数字
    :test
    :mokemoke

    そして、キーワードリスト（後述）のシンボルとして使う場合は、
    以下の様な表記となる
    test:
    mokemoke:
```

備考：
    要するに、:testは単なるシンボルであり、test:はキーワードリストのキーとして
    使用されるシンボルです。どちらもシンボルですが、使用される文脈が異なります。

    二つは同じものなのは、以下の様にわかります。
    :example == :example
    true
    ※比較についても、後述しますね。

    元の文章では、色々書いてありますが、一旦、省略しておきます。

5. 文字列
```
    文字列はUTF-8でencodeされている。
    "test"
    "もけもけ"
```
先頭に0bをつける先頭に0bをつける
きりが良いので、ここでDay1終了
え？もっと書けって？明日、演算やるから、量が多かったんで、ここまでにします。

# 3. 本日のチートシート

1. 整数

    |数字       |例      |コメント|
    |:---------|--------:|:---------------------|
    |10進数     |255||
    |2進数      |0b0110|先頭に0bをつける|
    |8進数      |0o644|先頭に0oをつける|
    |16進数     |0x1F|先頭に0xをつける|


2. 浮動小数

    |浮動小数     |例      |コメント|
    |:---------|-------------:|:---------------------|
    |浮動小数    |3.14||
    |エラー     |.14|最初に1桁以上の数字と、その後に続く少数が必要|
    |指数e      |1.0e-10||

3. 真理値

    |真理値     |コメント|
    |:---------|:---------------------|
    |true||
    |false||

    false と nil 以外は真なることに注意。


4. アトム
    | 注意 |例|
    |:-----------------------------------------------------|:-----------|
    |自身の名前がそのまま値になる定数です
    |:で始まり、英数字で書きます| :test :mokemoke|
    |そして、キーワードリスト（後述）のシンボルとして使う場合は、以下の様な表記となる| test: mokemoke:|
MUI+Next.jsで実装する仮想キーボード

MUI + Next.jsの仮想キーボード実装例

## 実装
<details><summary>ダイジェスト</summary>

```tsx: Keyboard.tsx
function Keyboard(props: {
    layout: Array<Array<string>>,
    onKeyPress: (key: string) => void,
}) {
    return (
      <Box
       sx={theme => ({
         bgcolor: theme.palette.lightgray,
         position: 'fixed',
         height: '50vh',
         width: '100vw',
         bottom: 0,
       })}
      >
        { /* キーボードに含まれる列のコンテナ */ }
        <Grid 
         container
         direction="column"
         spacing={2}
         margin="5%"
        >
          {
            // 列を生成
            props.layout.map((keys, idx) => (
              <Grid
               container
               spacing={2}
               size={12}
               key={`[${keys}]-${idx}`}
              >
                {
                  // キーを生成
                  keys.map((key, idx) => (
                    <Grid size="grow" key={`${key}-${idx}`} >
                      <Button
                       onClick={() => props.onKeyPress(key)}
                       key={`btn-${key}-${idx}`}
                       fullWidth
                       sx={theme => ({
                         color: theme.palette.text.primary,
                         bgcolor: theme.palette.invertableWhite,
                         padding: theme.spacing(2),
                         textAlign: "center",
                         textTransform: "none",
                       })}
                      >
                        {key}
                      </Button>
                    </Grid>
                  ))
                }
              </Grid>
            ))
          }
        </Grid>
    </Box>
  );
});
```
</details>

[全実装](https://github.com/chiveslimey/MUI-NextJS-Keyboard/tree/main)
[デモ](https://mui-nextjs-keyboard.vercel.app)

## 課題
`Grid`が高さを自動調節してくれない。`padding`でいい感じにするのが精一杯だった...
もしかしたらflexboxに`style="align-items: stretch;"`あたりを指定した方が良かったかも
ElixirでPAY.JPのライブラリ作成シリーズ①

今年もQiitaのアドベントカレンダーの季節がやってきましたね。
東京にいるfukuokaexのYOSUKEこと中尾瑛佑です。

最近は、コードを書く機会が減ったのでこの時期にリハビリを兼ねてがっつり書いていこうと思いますが、リハビリかねてるので記事も丁寧いに少しづつ進行していこうかなと思います。w


https://qiita.com/Yoosuke/private/0e66683bb90fed80e6d5

こちらの続きです。

## PAY.JPのElixirライブラリPayjpex

Payjpexというライブラリ名にしたいと思います。
早速プロジェクトを立てていきましょう。

```bash
mix new payjpex
```

生成したら、恐らく使うであろうライブラリを追加しておきます。

`mix.exs` ファイルに必要なライブラリを追加します。

```elixir
  defp deps do
    [
      {:credo, "~> 1.7", only: [:dev, :test], runtime: false},
      {:ex_doc, "~> 0.27", only: :dev, runtime: false},
      {:dialyxir, "~> 1.0", only: [:dev], runtime: false},
      {:jason, "~> 1.4"},
      {:finch, "~> 0.13"},
      {:tesla, "~> 1.4"}
    ]
  end
```
追記したら早速取得しておきましょう。

```bash
mix deps.get 
```

ちなみに、ライブラリの説明を簡素にすると以下です。

### credo
コードの品質チェックツール
コーディング規約違反などを検出


### ex_doc
ドキュメント生成ツール
@moduledocや@docからHTMLドキュメントを生成


### dialyxir
型チェックツール
コードの型の問題を静的解析で検出


### jason
JSONパーサー/エンコーダー
APIとのJSON通信に使用


### finch
HTTPクライアント
高性能なHTTP通信を提供

### tesla
HTTPクライアントフレームワーク
APIクライアント構築を簡単にする


### only: :devやruntime: falseの解説
only: :dev → 開発時のみ使用
runtime: false → コンパイル時のみ必要
Elixirのチートシートを作ろう #1

Elixirのチートシートを作ろう。

# 1. OverView

お疲れ様です。小野寺です。
いやー、一年再開にかかりました。
いやぁ、覚える端からElixirの文法を忘れまして、年は取りたく…いや、お前は昔からだろう。

と言うわけでElixir Schoolの課題をこなしながら、チートシートを作っていこうと思いました。

その前に、Elixir School、綺麗にまとまっている上に、いろんなヒントがあっていいのですが、
一つ問題があって、ちょくちょく、そこまでで説明されてない機能が出てくるのが難点。
そこくらいは解説出来ればと思ってます。

本日のお題はここです。

    https://elixirschool.com/ja/lessons/basics/basics

    
# 2. まずは解説
1. 整数
```
　  整数    255
    2進数       0b0110
    8進数       0o644
    16進数      0x1F
```


2. 浮動小数
    「Elixirでは、浮動小数点数は少なくとも1桁の数字とその後に続く小数を必要とし、64ビットの倍精度で、指数 e に対応しています」
    と書いてありますね。

```
    3.14
    .14 -> エラー、最初に1桁以上の数字と、その後に続く少数が必要
    0.14 
    1.0e-10 指数 e ですね。
```

3. 真理値
```
    true
    false

    false と nil 以外は真なることに注意。
```

4. アトム
```
    自身の名前がそのまま値になる定数です
    :で始まり、英数字
    :test
    :mokemoke

    そして、キーワードリスト（後述）のシンボルとして使う場合は、
    以下の様な表記となる
    test:
    mokemoke:
```

備考：
    要するに、:testは単なるシンボルであり、test:はキーワードリストのキーとして
    使用されるシンボルです。どちらもシンボルですが、使用される文脈が異なります。

    二つは同じものなのは、以下の様にわかります。
    :example == :example
    true
    ※比較についても、後述しますね。

    元の文章では、色々書いてありますが、一旦、省略しておきます。

5. 文字列
```
    文字列はUTF-8でencodeされている。
    "test"
    "もけもけ"
```
先頭に0bをつける先頭に0bをつける
きりが良いので、ここでDay1終了
え？もっと書けって？明日、演算やるから、量が多かったんで、ここまでにします。

# 3. 本日のチートシート

1. 整数

    |数字       |例      |コメント|
    |:---------|--------:|:---------------------|
    |10進数     |255||
    |2進数      |0b0110|先頭に0bをつける|
    |8進数      |0o644|先頭に0oをつける|
    |16進数     |0x1F|先頭に0xをつける|


2. 浮動小数

    |浮動小数     |例      |コメント|
    |:---------|-------------:|:---------------------|
    |浮動小数    |3.14||
    |エラー     |.14|最初に1桁以上の数字と、その後に続く少数が必要|
    |指数e      |1.0e-10||

3. 真理値

    |真理値     |コメント|
    |:---------|:---------------------|
    |true||
    |false||

    false と nil 以外は真なることに注意。


4. アトム
    | 注意 |例|
    |:-----------------------------------------------------|:-----------|
    |自身の名前がそのまま値になる定数です
    |:で始まり、英数字で書きます| :test :mokemoke|
    |そして、キーワードリスト（後述）のシンボルとして使う場合は、以下の様な表記となる| test: mokemoke:|
今更聞けない『〇aaS』について浅く理解する

就活してるのに、正直IaaSとかPaaSとかBPaaSとかわかってない（SaaSも何となくしかわからない）

そこで、良く知ってる前提で出てくる**〇aaS**たちをまとめてみる

## **〇aaS の aaS の部分**

〇aaSは「〇 as a Service」の事。

つまり「サービスとしての〇」って感じで、「〇のサービス」って感じで考えるとわかりやすいかも

クラウドコンピューティングサービスの形態で、つまりインターネット上やクラウド上で機能や環境を提供するようなサービス。

ローカルじゃなくてインターネット上でってのが肝

## 色んな〇aaSを見ていこう


**SaaS(Software as a Service)**
一番よく聞くSaaSはSoftware as a Serviceの略で、クラウドで提供しているソフトの事を言う

例えば kintone とか Salseforce とか Dropbox とか

一昔前までクラウドで提供するのではなくて、ローカルにインストールするような形での提供だっから移行期ってこともあって SaaS が良く話題に上がるってワケ

**BPaaS(Business Process as a Service)**
BPOとSaaSを掛け合わせたようなサービス

そもそもBPOは、Business Process Outsourcingの略で、業務を一部外部委託して自社のリソース負担を削減できるようなサービスの事

つまり、クラウドのソフトを通して業務を外部委託できるようなサービスの事。

**PaaS(Platform as a Service)**
個人的には二番目に聞くかな？

これはAWSとかGCP、Azureみたいな感じで開発に使う環境とかを提供してくれているようなサービスの事。

これによって、サーバー建てて…環境構築して…みたいなことをしないで済む

**IaaS(Infrastructure as a Service)**
長いけど、「インフラストラクチャ as a Service」の略で、その名の通りインフラを提供しているようなサービスの事。

PaaSに比べてもっと簡素なもので、開発環境等も自分で用意する必要があるので、手間が多い反面自由度が高い

**BaaS(Backend as a Service)**
これはバックエンド開発を楽にするようなもので、データベース管理からユーザー認証・通知機能まで幅広く提供してくれる。

サービス例としてFirebaseとかHexabaseがある
LeetCodeを1日1題解いてみる (day32)

32日目に取り組んだ問題はこちら！

# 144. Binary Tree Preorder Traversal

https://leetcode.com/problems/binary-tree-preorder-traversal/description/

## 問題文
Given the root of a binary tree, return the preorder traversal of its nodes' values.

## 僕の回答
```py
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        stack = [root]
        result = []

        while stack:
            node = stack.pop()
            print(node.val)
            result.append(node.val)

            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
            
        return result  
```

## より効率の良い回答例
特になし

## コメント
深さ優先探索の理解ができてきた。stackでの操作も慣れてきた。

## 次の問題はこちら!
https://qiita.com/h_y_s_d/items/3985f62c0f050b369909
確率分布と条件付き確率の活用

以下は、上記の内容をわかりやすく日本語でまとめた記事です。

---

### **確率分布と条件付き確率の活用**

#### **1. 確率分布の基礎**
確率分布とは、ランダム変数が取る可能性のある各値に対する確率を示したものです。例えば、「フライト」というランダム変数が以下のような確率分布を持つとしましょう：
- フライトが時間通り（on time）である確率：60%（0.6）
- 遅延する（delayed）確率：30%（0.3）
- キャンセルされる（canceled）確率：10%（0.1）

これらの確率を合計すると1（100%）になります。これは確率論の基本ルールで、すべての可能な世界の確率を合計すると必ず1になるという原則に基づいています。

確率分布は、より簡潔にベクトル形式で表現することも可能です。例えば、このフライトの確率分布は次のように記述されます：
```plaintext
P(flight) = <0.6, 0.3, 0.1>
```
この表記では、値の順序が「時間通り」「遅延」「キャンセル」であることを知っていれば、それぞれの確率を簡単に把握できます。

---

#### **2. 独立性と条件付き確率**
確率の独立性は、「あるイベントが他のイベントに影響を与えない」ことを意味します。例えば、赤いサイコロを振った結果と青いサイコロを振った結果は互いに独立です。赤いサイコロが「6」を出しても、青いサイコロの結果には何の影響もありません。

一方で、**独立ではない場合**もあります。例えば、「朝が曇り（cloudy）」と「午後に雨が降る（rain）」といったイベントは関連している可能性があります。曇りの朝であれば、午後に雨が降る確率が高まる場合があるからです。

数学的には、独立性を次のように表現します：
- イベントAとBが独立であれば、
  ```plaintext
  P(A ∩ B) = P(A) × P(B)
  ```
  つまり、AとBが同時に発生する確率は、Aの確率とBの確率を掛けた値になります。

#### **条件付き確率の計算**
条件付き確率は、既知の情報を基に他の確率を計算する手法です。次の公式で計算されます：
```plaintext
P(A | B) = P(A ∩ B) / P(B)
```
ここで、P(A | B)は「Bが真であるときのAの確率」を表します。

---

#### **3. ベイズの定理**
**ベイズの定理**は、ある条件付き確率を逆方向の条件付き確率から計算するための重要な公式です。公式は次のように表されます：
```plaintext
P(B | A) = [P(A | B) × P(B)] / P(A)
```

例えば、「朝曇り（cloudy）であった場合に午後雨（rain）が降る確率」を計算したいとします。この状況で、以下のデータがあると仮定します：
- 午後雨が降った日の80%は朝が曇りだった（P(cloudy | rain) = 0.8）。
- 全体の40%の日が曇り（P(cloudy) = 0.4）。
- 全体の10%の日が雨（P(rain) = 0.1）。

ベイズの定理を使って、**P(rain | cloudy)** を計算します：
```plaintext
P(rain | cloudy) = [P(cloudy | rain) × P(rain)] / P(cloudy)
                 = (0.8 × 0.1) / 0.4
                 = 0.2
```
つまり、朝が曇りであれば午後雨が降る確率は20%と結論付けられます。

---

#### **4. 同時確率分布（Joint Probability Distribution）**
同時確率分布は、複数のランダム変数が取りうるすべての組み合わせの確率を示します。例えば、「朝曇り」と「午後雨」の関係を次の表で表すことができます：

| 朝曇り（Cloudy） | 午後雨（Rain） | 確率（Probability） |
|------------------|---------------|--------------------|
| 曇りかつ雨        | True          | 0.08               |
| 曇りで雨でない    | False         | 0.32               |
| 曇りでなく雨       | True          | 0.02               |
| 曇りでなく雨でない | False         | 0.58               |

この表に基づいて、例えば「朝曇りかつ午後雨」の確率P(cloudy ∩ rain)は0.08と計算できます。

---

### **まとめ**
確率分布、条件付き確率、そしてベイズの定理は、AIやデータ分析において非常に重要な概念です。これらを組み合わせることで、データから新しい知見を得たり、未来のイベントの発生確率を推測することが可能になります。次回は、不確実性の扱い方をさらに掘り下げていきます。
論理推論と規則の応用：分かりやすい説明

# 論理推論と規則の応用：分かりやすい説明

この記事では、論理推論を支えるいくつかの基本的な規則を取り上げ、それらがどのようにAIや知識ベースの推論に役立つかを説明します。さらに、複雑な論理式を扱いやすくするための標準形式「**CNF（合取標準形）**」への変換についても解説します。

---

## 推論規則：知識を広げる方法

### 1. **Modus Ponens（推論法）**
もし次の2つを知っている場合：

- \(A \rightarrow B\) （Aが成り立つならばBも成り立つ）
- \(A\) （Aが成り立つ）

この場合、論理的に結論として\(B\)が導き出せます。

**例**  
「雨が降ればハリーは家の中にいる」という条件（\(A \rightarrow B\)）と「雨が降っている」という事実（\(A\)）が分かれば、「ハリーは家の中にいる」（\(B\)）と結論付けられます。

この規則は非常に直感的ですが、コンピュータにこの規則を適用させるには明示的に教える必要があります。

---

### 2. **And Elimination（ANDの削除）**
もし次の情報を持っている場合：

- \(A \land B\) （AもBも成り立つ）

この場合、以下のように部分的な情報を結論として引き出せます：

- \(A\) または \(B\)

**例**  
「ハリーはロンとハーマイオニーの両方と友達である」という情報があれば、「ハリーはハーマイオニーと友達である」（\(B\)）という結論を導けます。

---

### 3. **Double Negation Elimination（二重否定の削除）**
もし次の情報がある場合：

- \(\neg(\neg A)\) （Aが成り立たないことが成り立たない）

この場合、結論として単純に\(A\)が導き出せます。

**例**  
「ハリーがテストに合格していないというのは間違いである」と分かれば、「ハリーはテストに合格した」という結論を導けます。

---

### 4. **Implication Elimination（含意の削除）**
含意（if-then）はOR表現に変換できます：

- \(A \rightarrow B\) は \(\neg A \lor B\) に等しい。

**例**  
「雨が降ればハリーは家の中にいる」（\(A \rightarrow B\)）は、「雨が降らない」または「ハリーは家の中にいる」という形に書き換えられます。

---

### 5. **Biconditional Elimination（二方向含意の削除）**
二方向含意（if and only if）は次のように書き換えられます：

- \(A \leftrightarrow B\) は \((A \rightarrow B) \land (B \rightarrow A)\) に等しい。

**例**  
「雨が降るときだけハリーは家の中にいる」という情報は、「雨が降ればハリーは家の中にいる」かつ「ハリーが家の中にいれば雨が降っている」という形に分解できます。

---

### 6. **De Morgan's Laws（ドモルガンの法則）**
ドモルガンの法則により、ANDとORの間で否定を操作できます：

1. \(\neg(A \land B)\) は \(\neg A \lor \neg B\)
2. \(\neg(A \lor B)\) は \(\neg A \land \neg B\)

**例**  
「ハリーとロンの両方がテストに合格しなかった」という情報（\(\neg(A \land B)\)）は、「ハリーがテストに合格しなかった」または「ロンがテストに合格しなかった」という形に変換できます。

---

## 合取標準形（CNF）への変換

論理式を扱いやすくするために、「CNF（合取標準形）」という形式に変換します。CNFはANDで結合された複数のOR式の集合として表されます。

**例**  
\((A \lor B) \land (\neg C \lor D)\)

### CNFへの変換手順

1. **二方向含意の削除**  
   \(A \leftrightarrow B\) を \((A \rightarrow B) \land (B \rightarrow A)\) に変換します。

2. **含意の削除**  
   \(A \rightarrow B\) を \(\neg A \lor B\) に変換します。

3. **否定を内側に移動**  
   ドモルガンの法則を使って、否定を個々の命題シンボルに適用します。

4. **分配法則の適用**  
   ANDとORを分配して、ORが内側、ANDが外側になるようにします。

---

## 推論規則の活用例

### 例1：推論の簡単な適用
「雨が降ればハリーは家の中にいる」という情報と「雨が降っている」という事実をもとに、「ハリーは家の中にいる」という結論を導きます。

### 例2：ゲームやパズルへの応用
推理ゲーム「Clue」では、カード情報を元に論理推論を行い、結論を導きます。これにより、AIは矛盾のない情報から新たな知識を構築できます。

---

## 結論

論理推論規則を用いることで、AIは複雑な情報から合理的な結論を導き出すことが可能になります。CNFへの変換や推論規則の適用は、AIの推論を効率的に行うための基本です。これらを理解することで、知識ベースの推論をさらに深めることができます。
AIと論理推論：非降雨時の知識モデルの構築と応用

# AIと論理推論：非降雨時の知識モデルの構築と応用

以下の動画の、内容を要約しました。
https://youtu.be/5NgNicANyqM?si=Qc3Dzaw6gf3x5qmd

AIの推論アルゴリズムを使って、特定の状況から結論を導き出す方法を考えます。本記事では、**非降雨時の論理モデル**を構築し、それを用いた推論と推論規則の適用について説明します。具体的には、Pythonによる知識表現とモデルチェックを用いた論理的な結論の導出を解説します。

---

## 知識の定義：論理式の構築

まず、次のような状況を考えます。

1. **非降雨の場合、ハリーはハグリッドを訪問する。**
2. **ハリーはハグリッドまたはダンブルドアを訪問した。**
3. **ハリーはハグリッドとダンブルドアの両方を訪問していない。**
4. **ハリーはダンブルドアを訪問した。**

これらの情報をPythonコードで次のように表現します：

```python
from logic import Symbol, And, Or, Not, Implication

# シンボルの定義
rain = Symbol("It is raining")
hagrid = Symbol("Harry visited Hagrid")
dumbledore = Symbol("Harry visited Dumbledore")

# 知識の構築
knowledge = And(
    Implication(Not(rain), hagrid),  # 非降雨時にハグリッド訪問
    Or(hagrid, dumbledore),         # ハグリッドまたはダンブルドア訪問
    Not(And(hagrid, dumbledore)),   # ハグリッドとダンブルドアを同時に訪問していない
    dumbledore                      # ダンブルドア訪問
)
```

このコードでは、`Symbol`で命題を定義し、`And`、`Or`、`Not`、`Implication`で論理式を構築しています。

---

## モデルチェックによる推論

次に、モデルチェックを使って「雨が降っているかどうか」を判断します。

### モデルチェックの仕組み

モデルチェックは、知識ベース内のすべての可能な状況（モデル）を列挙し、特定のクエリが真であるかを検証する手法です。例えば、「非降雨時にハリーがハグリッドを訪問する」という知識を用いて、雨が降っているかどうかを検証します。

以下のコードで実装します：

```python
from logic import model_check

# クエリの設定
query = rain  # 雨が降っているかどうかを確認

# モデルチェックを実行
result = model_check(knowledge, query)
print(f"Is it raining? {result}")
```

実行結果：

```
Is it raining? True
```

### 結論の導出

モデルチェックにより、「知識ベース内の条件が真である状況では、雨が降っている」と結論付けられました。これにより、ハリーがハグリッドを訪問しない理由も論理的に説明できます。

---

## 推論規則による効率化

モデルチェックは有効ですが、大量のモデルを列挙するため計算コストが高くなります。より効率的に推論を行う方法として、**推論規則（Inference Rules）**を使用します。

### 推論規則の例：Modus Ponens

以下の2つの情報があるとします：
1. 「もし雨が降っていなければ、ハリーはハグリッドを訪問する」（\(\neg P \rightarrow Q\)）。
2. 「雨が降っていない」（\(\neg P\)）。

これに基づき、「ハリーはハグリッドを訪問する」（\(Q\)）と結論付けます。この推論規則を**Modus Ponens**と呼びます。

### 推論規則をPythonで実装

以下は、推論規則を活用して推論を効率化する例です：

```python
from logic import entails

# 推論規則を適用
if entails(knowledge, hagrid):
    print("Harry visited Hagrid.")
else:
    print("Harry did not visit Hagrid.")
```

結果として、雨の状況や訪問場所に関する推論を直接導き出すことが可能です。

---

## 応用例：論理パズルの解決

このような論理推論は、論理パズルやゲーム（例：推理ゲーム「Clue」）にも応用できます。例えば、特定の条件下で可能な選択肢を絞り込み、最適な行動を見つける際に役立ちます。

---

## 結論

本記事では、AIによる論理推論の基本として、モデルチェックと推論規則を解説しました。これにより、複雑な状況下でも効率的に結論を導き出す方法を学ぶことができます。次に取り組むべき課題は、より高度な知識表現や推論アルゴリズムを学び、現実の問題解決に応用することです。