Irisデータセットの多クラス分類問題を人気のアルゴリズムを使って解く

この記事では、Pythonでさまざまな機械学習アルゴリズムの実装方法と、それらの精度・実行時間比較を紹介します。今回紹介するのは「LightGBM・ランダムフォレスト・XGBoost・CatBoost・AdaBoost・Extra Trees・HistGradientBoosting」の７つです。
## それぞれの実装の紹介

Irisデータセットを読み込んで訓練データとテストデータに分割するところは、コピペで実行できるように全ての例に記載しています。

それではそれぞれの実装を見ていきましょう。

### ライブラリのインストール
必要なライブラリをインストールしておきます。
```
pip install scikit-learn xgboost lightgbm catboost
```

インストールしたライブラリのバージョンは以下の通りです。
```
scikit-learn==1.5.0
lightgbm==4.4.0
catboost==1.2.5
xgboost==2.1.0
```

### LightGBMで実装
LightGBMは、[勾配ブースティング決定木（Gradient Boosting Decision Tree）](https://www.feg.co.jp/analysis_tech/勾配ブースティング決定木/)を用いた機械学習アルゴリズムの一つです。LightGBMは高速で効率的な学習が可能で、大規模なデータセットにも適しています。LightGBMは、Microsoftによって開発されたオープンソースのライブラリであり、PythonやRなどのプログラミング言語で利用できます。

```python
import lightgbm as lgb
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# irisデータセットを読み込む
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 訓練データとテストデータに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

#LightGBMモデルを作成し、トレーニングデータで学習させます。
lgb_train = lgb.Dataset(X_train, y_train)
lgb_test = lgb.Dataset(X_test, y_test, reference=lgb_train)

params = {
    'objective': 'multiclass',
    'num_class': 3,
    'metric': 'multi_logloss',
    'boosting_type': 'gbdt',
    'num_leaves': 31,
    'learning_rate': 0.05,
    'feature_fraction': 0.9,
    "verbose": -1
}

gbm = lgb.train(params, lgb_train, num_boost_round=100, valid_sets=[lgb_train, lgb_test])

#テストデータでモデルを評価します。
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
y_pred_max = [list(x).index(max(x)) for x in y_pred]
accuracy = accuracy_score(y_test, y_pred_max)
print("Accuracy: {:.2f}".format(accuracy))
```


### ランダムフォレストで実装
ランダムフォレストは、機械学習のアルゴリズムの一つで、複数の決定木を組み合わせて予測を行う手法です。ランダムフォレストでは、データセットからランダムにサンプリングを行い、それぞれのサンプルで複数の決定木を構築します。そして、それぞれの決定木が出力した結果を組み合わせて最終的な予測を行います。ランダムフォレストは、過学習を防ぐ効果があり、高い予測精度を持つことが特徴です。
```python
# 必要なライブラリをインポート
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# irisデータセットを読み込む
iris = load_iris()
X = iris.data
y = iris.target

# 訓練データとテストデータに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# ランダムフォレスト分類器を作成し、訓練データを使ってモデルを訓練する
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)

# テストデータを使って予測を行う
y_pred = clf.predict(X_test)

# 精度を評価する
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')
```

### XGBoostで実装
XGBoostは、Extreme Gradient Boosting の略で、機械学習のアルゴリズムの一つです。XGBoostは、勾配ブースティングと呼ばれるアンサンブル学習手法を使用しており、複数の決定木モデルを組み合わせて強力な予測モデルを構築します。
```python
import xgboost as xgb
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Irisデータセットをロード
iris = load_iris()
X = iris.data
y = iris.target

# データを訓練用とテスト用に分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# XGBoostモデルを初期化
model = xgb.XGBClassifier(objective='multi:softmax', num_class=3)

# モデルを訓練
model.fit(X_train, y_train)

# テストデータで予測
y_pred = model.predict(X_test)

# 精度を評価
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")
```

### CatBoostで実装
CatBoostは、Gradient Boostingアルゴリズムの一種であり、カテゴリカル変数を扱う際に優れた性能を発揮する機械学習モデルです。CatBoostは、自動的にカテゴリカル変数をエンコードし、過学習を防ぐための機能を持っています。
```python
from catboost import CatBoostClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# irisデータセットを読み込む
iris = load_iris()
X = iris.data
y = iris.target

# データをトレーニングセットとテストセットに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# CatBoostモデルを定義してトレーニング
model = CatBoostClassifier(iterations=100, learning_rate=0.1, depth=6, verbose=False, loss_function='MultiClass')
model.fit(X_train, y_train)

# テストデータで予測
y_pred = model.predict(X_test)

# 精度を評価
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
```

### AdaBoostで実装
AdaBoost（Adaptive Boosting）は、機械学習の[アンサンブル学習手法](https://bodais.com/rd/knowledge/ensemblelearningmethod/)の一つです。AdaBoostは、複数の弱い学習器（例えば決定木など）を組み合わせて、より強力な予測モデルを構築する手法です。AdaBoostは、各学習器が間違えたデータに重みをつけて、次の学習器がより注意を払うように学習を進めます。

```python
from sklearn.ensemble import AdaBoostClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# irisデータセットをロード
iris = load_iris()
X = iris.data
y = iris.target

# データを訓練用とテスト用に分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# AdaBoostモデルを作成
ada_clf = AdaBoostClassifier(n_estimators=50, learning_rate=1.0, algorithm='SAMME', random_state=42)
ada_clf.fit(X_train, y_train)

# テストデータで予測
y_pred = ada_clf.predict(X_test)

# 精度を評価
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
```

### Extra Treesで実装
Extra Trees（エクストラツリー）は、ランダムフォレストに似た機械学習アルゴリズムの一種です。決定木をベースにしたアンサンブル学習手法です。

```python
from sklearn.datasets import load_iris
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# irisデータセットをロード
iris = load_iris()
X = iris.data
y = iris.target

# データをトレーニングセットとテストセットに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Extra Treesモデルを作成
model = ExtraTreesClassifier(n_estimators=100, random_state=42)

# モデルをトレーニング
model.fit(X_train, y_train)

# テストセットで予測
y_pred = model.predict(X_test)

# 精度を評価
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
```

### HistGradientBoostingで実装
scikit-learnライブラリで提供される勾配ブースティングの実装の一つです。従来のGradientBoostingよりも高速で、大規模なデータセットに対してより効率的に動作します。
```python
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.metrics import accuracy_score

# irisデータセットをロード
iris = load_iris()
X = iris.data
y = iris.target

# データを訓練用とテスト用に分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# HistGradientBoostingClassifierを定義
clf = HistGradientBoostingClassifier()

# モデルを訓練
clf.fit(X_train, y_train)

# テストデータで予測
y_pred = clf.predict(X_test)

# 精度を評価
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
```

## 実行スピード比較
50回Irisデータセットをtrainして推論を実行させた時間を計測した結果、以下のようになりました。Python3.10.9を使用し、2 GHz クアッドコアIntel Core i5のMacBook Proを使用しています。

| モデル | 実行時間(秒) |
|--------|----------|
| LightGBM | **3.09** |
| ランダムフォレスト | 6.24 |
| XGBoost | 3.35 |
| CatBoost | 3.50 |
| AdaBoost | 4.48 |
| ExtraTrees | 4.92 |
| HistGradientBoosting | 5.48 |

実行時間だけで見るとLightGBMが最も速いですね。

## Accuracy比較
1000回irisデータセットを学習させて、accuracyの平均値を算出してみた結果、以下のようになりました。

| モデル | avg(accuracy) |
|--------|----------|
| LightGBM | 0.9493 |
| ランダムフォレスト | 0.9511 |
| XGBoost | 0.9425 |
| CatBoost | **0.9551** |
| AdaBoost | 0.9433 |
| ExtraTrees | 0.9532 |
| HistGradientBoosting | 0.9448 |

CatBoostが最も精度が良いという結果になりました。

## まとめ
さまざまな機械学習アルゴリズムの実装を見ましたが、コードだけ見るとほぼ似通っていましたね。
Irisデータセットだけで見るとCatBoostが精度がよくそこそこ速いので、おすすめだという結果になりました。簡単にコードを書き換えて比較できるので、どの機械学習アルゴリズムが自分の目的に合っているかを試してみると良いと思います。ぜひその際の参考に使ってください。