Pythonで作る簡易AI（データ分類）

# 1. はじめに
この記事は2023年3月時点の情報です。

最近、様々なAIが一般的にも浸透してきましたね。
せっかくなので、学習がてら、簡易AIを作成してみました。
私もまだ学習中なので、何かあれば、コメントしていただけると幸いです:bow_tone1:
# 2. 前提条件
## 2-1. 簡易AIで何をするか
簡易AIでは、アヤメの花の特徴量（がくの長さ、がくの幅、花びらの長さ、花びらの幅）を入力として、アヤメの種類（Iris setosa, Iris versicolor, Iris virginica）を予測する教師あり学習の分類問題を解きます。

## 2-2. 利用するデータセットと、このデータセットを使う理由
データセットには、Irisデータセットを使用します。Irisデータセットは、機械学習のデータセットとしてよく利用されており、サイズが小さく、特徴量が少ないため、データの理解や可視化を比較的簡単に行うことができるそうです。また、3つのクラスがあるため、多クラス分類の問題を学ぶのに適しています。

ここで、3つのクラスとは、以下3種類のアヤメを表します。
a. セトサ (Iris Setosa)：花びらとがく片が比較的短く、広がりがあることが特徴です。
b. バーシクル (Iris Versicolor)：セトサとバージニカの中間的な形状とサイズを持っています。
c. バージニカ (Iris Virginica)：花びらとがく片が比較的長く、細長いことが特徴です。

## 2-3. 今回利用するモデルについて
今回は、ロジスティック回帰モデルを利用します。ロジスティック回帰モデルは、入力された情報をもとに、物事が起こる確率を予測するためのモデルです。例えば、天気予報やアヤメの種類の予測などが可能です。

## 2-4. ロジスティック回帰モデルで何をするのか
ロジスティック回帰モデルを使って、アヤメの花の特徴量から、アヤメの種類を予測します。それぞれの種類のアヤメである確率を計算し、確率が一番高い種類を答えとして選びます。

# 3. 環境構築
Pythonの仮想環境を作成して、必要なパッケージをインストールします。
```shell
python -m venv simple_ai
source simple_ai/bin/activate  # Windowsの場合: myenv\Scripts\activate
pip install wheel numpy cython
pip install scikit-learn pandas
```
# 4. 実装
以下の例では、データの中身と検証結果を表示するようにしてます。
```python:iris_classifier.py
# データ解析や操作のためのライブラリ
import pandas as pd
# 機械学習のためのライブラリで、データセットを含んでいる
from sklearn import datasets
# データを訓練用とテスト用に分割するための関数
from sklearn.model_selection import train_test_split
# ロジスティック回帰という機械学習の手法を使って分類問題を解くためのクラス
from sklearn.linear_model import LogisticRegression
# 予測の正確さ（正解率）を計算するための関数
from sklearn.metrics import accuracy_score

# データセットの内容を表示
def print_iris_data(X, y, iris_labels):
    iris_df = pd.DataFrame(X, columns=['sepal length', 'sepal width', 'petal length', 'petal width'])
    iris_df['species'] = [iris_labels[label] for label in y]
    print(iris_df.head())

# データセットの読み込み
def load_iris_data():
    iris = datasets.load_iris()
    X = iris.data
    y = iris.target
    iris_labels = {0: 'setosa', 1: 'versicolor', 2: 'virginica'}
    return X, y, iris_labels

def main():
    # Irisデータセットをロードし、特徴量X、ラベルy、およびiris_labels（アヤメの種類の名称）を取得
    X, y, iris_labels = load_iris_data()
    # Irisデータセットの内容を表示
    print_iris_data(X, y, iris_labels)
    # データを訓練データとテストデータに分割（訓練データ80%、テストデータ20%）
    # random_stateは、分割が再現可能なように固定（42以外でもOK）
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # ロジスティック回帰モデルのインスタンスを作成
    model = LogisticRegression()
    # モデルを訓練データに適合させる（訓練する）
    model.fit(X_train, y_train)

    # テストデータを使ってモデルで予測を行い、予測結果をy_predに格納
    y_pred = model.predict(X_test)
    # 実際のテストデータのラベル（y_test）と予測結果（y_pred）を比較し、正解率を計算
    accuracy = accuracy_score(y_test, y_pred)

    iris_labels = {0: 'setosa', 1: 'versicolor', 2: 'virginica'}

    print("Index | Actual | Predicted | Correct")
    print("------|--------|-----------|--------")
    for idx, (actual, predicted) in enumerate(zip(y_test, y_pred)):
        correct = "Yes" if actual == predicted else "No"
        print(f"{idx:5} | {iris_labels[actual]:<8} | {iris_labels[predicted]:<9} | {correct}")

    print(f"\nAccuracy: {accuracy:.2f}")

if __name__ == "__main__":
    main()
```
# 検証方法
作成したコードを実行し、正解率が表示されることで検証できます。
```bash
python iris_classifier.py
```
### 出力例
#### データセットの表
データセットの最初の5つのデータポイントが表示されており、特徴量（sepal length、sepal width、petal length、petal width）がスケーリングされてます。
```bash
% python iris_classifier.py
   sepal length  sepal width  petal length  petal width species
0     -0.900681     1.019004     -1.340227    -1.315444  setosa
1     -1.143017    -0.131979     -1.340227    -1.315444  setosa
2     -1.385353     0.328414     -1.397064    -1.315444  setosa
3     -1.506521     0.098217     -1.283389    -1.315444  setosa
4     -1.021849     1.249201     -1.340227    -1.315444  setosa
```
#### 予測結果の表
Index: テストデータのインデックス
Actual: 実際の品種名
Predicted: 予測した品種名
Correct: 予測が正しいかどうか（Yes/No）

Accuracy: 正確度、正解率
```bash
Index | Actual | Predicted | Correct
------|--------|-----------|--------
    0 | versicolor | versicolor | Yes
    1 | setosa   | setosa    | Yes
    2 | virginica | virginica | Yes
    ...
   27 | virginica | virginica | Yes
   28 | setosa   | setosa    | Yes
   29 | setosa   | setosa    | Yes

Accuracy: 1.00
```
# まとめ
Pythonを使って簡易AI（機械学習モデル）を作成する方法を紹介しました。
この簡易AIでは、テストデータに対して100%の正解率でアヤメの種類を予測できました。

私もまだまだ学習中ですが、みなさんが機械学習に興味を持つきっかけとなれば幸いです:grinning: