ランダムフォレストによる高性能AIモデルへの挑戦とデータ処理

AI

前回の記事では、ロジスティック回帰というシンプルなモデルを使い、アヤメの品種分類で高い正解率を達成しました。
この「最初の成功体験」は、AI開発の大きな一歩です。

しかし、現実のAI開発では、この「完璧に見える結果」を鵜呑みにせず、より高い汎用性と信頼性を追求することが求められます。
高性能なAIモデルの実現は、単にモデルの訓練時間を長くすることではなく、「モデルの選択」と「データの準備」という2つの要素によって決まります。

この記事では、前回構築した開発環境をそのまま使用し、ロジスティック回帰を「超える」高性能モデルの開発に挑戦します。

  • モデルのグレードアップ: 多くの実務で使われる強力なモデル、ランダムフォレストを導入し、モデル選択の重要性を体験します。
  • データ処理の重要性: AIの性能を最大化するための必須テクニック、データの標準化(スケーリング)を行い、データ処理の重要性を実感します。

第1章:より強力なAIモデルの導入

前回作成した iris_ai.py ファイルには、データセットのロード、特徴量とターゲットの分割、そして訓練用・テスト用への分割といった、基本的な前処理が既に含まれています。

本章では、前回のコードを土台として活用しつつ、新しい高性能モデルの導入に備えます。

まずは、前回までのコードに、今回使う新しいモデル「ランダムフォレスト」とデータ処理用の機能を追加でインポートするところから始めましょう。

1.1. 「高性能の秘密」ランダムフォレストとは

前回記事で使用したロジスティック回帰がシンプルな直線でデータを分類しようとするのに対し、ランダムフォレストは、より複雑なデータに対応できる強力なモデルです。

ランダムフォレストは、以下の仕組みで高い性能を実現します。

  1. 複数の決定木を作成: データを分割しながら分類を行う「決定木(Decision Tree)」というシンプルなモデルを、数百本以上作成します。
  2. ランダムな学習: 各決定木は、データセットと特徴量の一部をランダムに選んで学習します。これにより、それぞれの決定木は異なる視点を持つようになります。
  3. 多数決で最終決定: 最終的な予測を行う際、数百本の決定木の予測結果を集め、多数決で最も多い答えを採用します。

一本の決定木は間違った予測をすることがあっても、多数の専門家(決定木)の意見を統合することで、ランダムフォレストは非常に安定して高い精度を発揮する、実務でも多用されるモデルとなっています。

1.2. 新しいライブラリとモデルのインポート

ランダムフォレストの導入に備え、前回作成した iris_ai.py ファイルを開き、必要な機能を追加でインポートします。

今回は、ランダムフォレストモデルと、後に使用するデータ標準化のための機能が必要です。

新規ファイル iris_rf_scale.py を作成し、以下のコードを入力してください。

from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler

💡 解説

  • RandomForestClassifier: 今回の主役となる高性能モデルです。sklearn.ensemble(アンサンブル学習)というモジュールからインポートします。
  • StandardScaler: 次の重要なステップであるデータ標準化のためのツールです。sklearn.preprocessing(前処理)モジュールに含まれています。

1.3. データ処理の必要性(StandardScalerの導入準備)

前回記事で作成したアヤメのデータセットは数値の範囲が(約1cm~7cm)と近く、データ処理の必要性は低かったですが、現実のデータではそうはいきません。

例えば、「年収(数百万)」と「年齢(数十)」のように、特徴量(AIへの入力情報)によって数値のスケール(大きさ)が大きく異なることは珍しくありません。
こういったデータのスケールに差がある場合は、次の理由によりスケールを揃える必要があります。

ランダムフォレストやロジスティック回帰をはじめとする多くのAIモデルは、数値の計算に基づいて学習を行います。

  • 影響力の偏り: スケールの大きい特徴量(年収など)は、スケールの小さい特徴量(年齢など)に比べ、計算上でモデルの予測に与える影響力が不当に大きくなります。
  • 学習の不安定化: スケールが不揃いなデータでは、モデルの学習プロセス(最適化)が不安定になり、計算時間が長くなったり、最悪の場合、性能が低下します。

この問題を解決し、どの特徴量も公平にモデルに影響を与えるようにするため、データの標準化(Standardization)という前処理が必要になるわけです。

第2章:データ前処理の実践

第1章で確認した通り、AIの性能を最大限に引き出すためには、モデルのグレードアップ(ランダムフォレスト)だけでなく、データ処理が不可欠です。

本章では、データのスケールを揃えるための必須テクニックである標準化StandardScaler を使って実践します。

2.1. データの標準化(Standardization)

標準化とは、それぞれの特徴量(花びらの長さなど)のデータが持つ平均を 0 に、分散を 1 に変換する処理です。
これにより、単位やスケールの異なるデータも公平に扱えるようになります。

項 1.2. で作成した iris_rf_scale.py を、以下の通り更新してください。

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 全ての列を表示するための設定 (前回と同様)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 1000)

# 1. データセットのロード
iris = load_iris()
X = iris.data # 特徴量
y = iris.target # ターゲット

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

# 3. StandardScalerの初期化と学習・変換
scaler = StandardScaler()

# 訓練データでスケーラーを学習(fit)し、変換(transform)を行う
X_train_scaled = scaler.fit_transform(X_train)

# テストデータは訓練データで学習したスケーラーを使って変換(transform)のみ行う
X_test_scaled = scaler.transform(X_test)

print("--- 標準化完了 ---")
print("標準化後のX_train_scaledの一部:\n", X_train_scaled[:5])
print("X_train_scaledの平均:", X_train_scaled.mean(axis=0))
print("X_train_scaledの標準偏差:", X_train_scaled.std(axis=0))

ここまでのプログラムを実行すると、以下のような結果が表示されます。

標準化後のX_train_scaledの一部:
 [[-1.47393679  1.20365799 -1.56253475 -1.31260282]
 [-0.13307079  2.99237573 -1.27600637 -1.04563275]
 [ 1.08589829  0.08570939  0.38585821  0.28921757]
 [-1.23014297  0.75647855 -1.2187007  -1.31260282]
 [-1.7177306   0.30929911 -1.39061772 -1.31260282]]
X_train_scaledの平均: [ 1.71344420e-15 -1.66579713e-15 -2.23894977e-16 -5.73615229e-17]
X_train_scaledの標準偏差: [1. 1. 1. 1.]

💡 解説

iris_rf_scale.py では、インポートからデータ分割、そして標準化までを一貫して行っています。
特に、上記の出力結果を見ると、前回作成したプログラムでは 5.1 と表示されていたデータが、-1.4739... のようなマイナス値を含む新しい値に置き換わっていることがわかります。この数値そのものの変化が、「データが標準化という処理を経て変換された」ことの明確な証拠です。

  • X_train_scaledの標準偏差[1. 1. 1. 1.]、つまり「1」になっていることを確認してください。
  • X_train_scaledの平均の末尾が e-15e-16 といった極めて小さな負の指数になっていることを確認してください。これは、数値が限りなくゼロに近いことを示しており、標準化が成功した証拠です。

第3章:ランダムフォレストによるモデル訓練

データ処理後のモデル訓練は非常に簡単です。
前回と異なるのは、モデルのクラス名と、訓練に使用するデータが標準化されたものに変わる点だけです。

3.1. 高性能モデルの初期化と訓練

iris_rf_scale.py に、以下のコードを追加してください。
また、前半の動作は確認済なので、不要な print 処理をコメントアウトしておくと、結果の出力が見やすくなります。

## これより上のコードは省略...

# print("--- 標準化完了 ---")
# print("標準化後のX_train_scaledの一部:\n", X_train_scaled[:5])
# print("X_train_scaledの平均:", X_train_scaled.mean(axis=0))
# print("X_train_scaledの標準偏差:", X_train_scaled.std(axis=0))

# 4. モデルの選択と初期化(ランダムフォレストに変更)
model = RandomForestClassifier(random_state=42) 

# 5. 標準化されたデータを使ってモデルを学習させる!
print("\n--- ランダムフォレスト訓練開始 ---")
# 訓練には標準化後のデータ(X_train_scaled)を使用
model.fit(X_train_scaled, y_train)
print("モデル訓練完了!")

💡 解説

  • モデルの切り替え: 前回使用した LogisticRegression から、高性能な RandomForestClassifier に切り替えました。
  • 標準化されたデータの使用: 訓練データには、標準化を行った X_train_scaled を使用しています。標準化によってスケールが統一されたデータを使うことで、モデルはより効率的かつ安定して学習を進められます。
  • random_state=42: 前回同様、モデル内のランダムな要素(どの決定木を使うかなど)の結果を固定し、再現性を確保するための設定です。

3.2. ランダムフォレストの予測と評価

前回同様、訓練に使っていないテストデータを使って予測を行い、正解率を計算します。
今回は、標準化されたデータを使うことが重要なポイントです。

iris_rf_scale.py に、以下のコードを追加してください。
また、ここまでの動作は確認済なので、不要な print 処理をコメントアウトしておくと、結果の出力が見やすくなります。

# 6. 標準化されたテストデータを使って予測を実行
y_pred_rf = model.predict(X_test_scaled)

# 7. 正解率を計算し、表示
# (予測値 == 正解値) の平均で正解率を計算します
accuracy_rf = (y_pred_rf == y_test).mean() * 100.0

print("\n--- 評価結果 ---")
print(f"ランダムフォレストの正解率: {accuracy_rf:.2f}%")

プログラムを実行すると、以下のような結果になります。

--- 評価結果 ---
ランダムフォレストの正解率: 100.00%

💡 解説

  • 予測データの使用: 予測の際、入力には必ず標準化されたテストデータ (X_test_scaled) を使用します。
  • 結果の確認: ランダムフォレストの結果は、100.00%が出ているはずです。
    • データのスケールが小さいため前回のプログラムでも100%が出やすく、モデル変更による正解率の数値的な向上は実感しづらいかもしれません。しかし、今回のステップは非常に重要です。このランダムフォレストは、ロジスティック回帰よりも遥かに複雑で、現実の難解なデータに対しては圧倒的な強さを発揮します。今はその「高性能なエンジン」を搭載できたこと、そしてデータ標準化によってAIの学習が安定したことを確認できた成功と捉えてください。

第4章:評価指標の多角化

4.1. 正解率(Accuracy)だけではAIとして不十分

前回と今回で、AIの性能を正解率(Accuracy)のみで評価してきました。
しかし、実際のAI開発では、この指標だけを頼りにすることは不十分であり、危険でもあります。

正解率とは「すべての予測の中で、正しかった割合」を示しますが、データに偏りがある場合、正解率は高くても、肝心な予測を外している可能性があります。

次のような例を考えてみましょう。

  • データ構成: 1,000人のデータのうち、990人が健康10人が病気(極端な偏りがある)。
  • AIの予測: AIモデルが、すべての患者を「健康」と予測するという、極端な振る舞いをしたとします。
  • 結果: このAIの正解率は \(990 / 1000 = 99\%\) です。
  • 問題点: 正解率は 99% と極めて高いにもかかわらず、最も重要な病気の患者10人を全員見逃しており、実用上は全く役に立たないAIということになります。

このような、データの偏りによって正解率が誤解を招く問題を避けるには、AIの性能を多角的に評価するための、別の指標が併せて必要になります。

4.2. 適合率(Precision)と再現率(Recall)

AIの性能を深く理解するために、適合率(Precision)と再現率(Recall)という2つの主要な指標を導入します。

  1. 適合率(Precision)
    • 定義: AIが「病気だ」と予測したもののうち、実際に病気だった割合。
    • 重要性: 誤診(無駄な治療)を減らしたい場合に重要。
  2. 再現率(Recall)
    • 定義: 実際に病気だった人のうち、AIが「病気だ」と正しく見つけられた割合。
    • 重要性: 見落とし(致命的な見逃し)を減らしたい場合に重要。

4.3. 新たな評価指標のコードへの追加

scikit-learn ライブラリには、これらの指標をまとめて計算する便利な関数 classification_report が用意されています。

iris_rf_scale.py に、以下のコードを追加し、実行してください。

from sklearn.metrics import classification_report

# 8. より詳細な評価レポートの表示
print("\n--- 分類レポート(適合率、再現率など)---")
print(classification_report(y_test, y_pred_rf, 
      target_names=iris.target_names))

プログラムを実行すると、以下のような結果になります。

--- 分類レポート(適合率、再現率など)---
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        10
  versicolor       1.00      1.00      1.00         9
   virginica       1.00      1.00      1.00        11

    accuracy                           1.00        30
   macro avg       1.00      1.00      1.00        30
weighted avg       1.00      1.00      1.00        30

💡 解説

アヤメのデータは完璧に近いため、すべての指標が「1.00」(100%)になっています。
しかし、現実のデータではこれらの値がバラバラになり、どの指標を重視すべきかを開発者が判断する必要があります。

まとめ

今回では、以下のステップを習得しました。

  • 高性能モデルの導入
  • データ標準化という必須処理
  • 評価指標の多角化

これで、「とりあえず動かす」から「本格的に性能を追求する」段階へと進みました。

次回のAI開発シリーズでは、今回のモデルのハイパーパラメーター(詳細設定)を調整することで、さらに性能を引き出すテクニックを学ぶ予定です。

コメント

タイトルとURLをコピーしました