本記事では、機械学習ライブラリのscikit-learnを利用し、ランダムフォレストのアルゴリズムに基づいてクラス分類を行う方法について書きます。
本記事における用語の説明
まずはいくつか用語の説明をします。
既に知っているという方は読み飛ばして下さい。
クラス分類とは
対象となるデータがいくつかのグループの内どれに属するのかを予測することです。
例としては、スパムメールの分類(受信メールがスパムか否かを予測)などが挙げられます。
ランダムフォレストとは
AI関連技術である機械学習の代表的な手法の一つです。同じく機械学習手法の決定木をベースとしています。決定木についての解説は以下の記事を参照して下さい。
【scikit-learn】決定木によるクラス分類【DecisionTreeClassifier】
ランダムフォレストでは、複数の決定木モデルを生成し、それらモデルの多数決によって最終的な予測を決定するという仕組みです。
各モデルは元々の学習用データセットを分割して生成したサブデータセットを用いて学習を行うため、それぞれが微妙に異なる予測性能を発揮します。
そのため、生成する決定木モデルの数が多いほど、ランダムフォレスト全体としての汎化能力が高まり、予測の性能も向上する傾向があります。
なお、ランダムフォレストのメリット、デメリットはそれぞれ以下の通りです。
- メリット:
入力データに含まれる各特徴量の重要度の算出が可能 - デメリット:
複数の決定木モデルを使用するため、計算時間が長くなりやすい
実際にプログラムを作成してみる
ランダムフォレストのアルゴリズムに基づいてクラス分類を行うプログラムを作成してみます。
プログラム作成の手順
ここでは、以下の手順で処理を実装します。
- 実験用のデータセットを用意する
- データセットの一部を利用して学習(モデルの構築)を行う
- 構築したモデルを用いて残りのデータセットに対する予測を行う
今回に限らず、機械学習のモデルを構築する際には上記手順で実行することが多いです。
使用する実験用データセット
scikit-learnには、学習やテストで使用する実験用のデータセットが用意されているため、今回はその中の一つのアヤメの計測データ(load_iris)を使用します。
使用するデータセットの概要は以下の通りです。
- 用途:分類(3クラス)
- データ件数:150
- データ次元数:4
- ドキュメント:sklearn.datasets.load_iris
花弁や萼片の長さなどの情報(4項目)を入力データとしてアヤメの種類を予測します。
モデル構築に使用するクラス
scikit-learnには、ランダムフォレストのアルゴリズムに基づいてクラス分類の処理を行うRandomForestClassifierクラスが存在するため、今回はこれを利用します。
RandomForestClassifierの主なパラメータは以下の通りです。(一部省略)
- n_estimators:int型
使用する決定木の数 - criterion:{‘gini’, ‘entropy’}
学習時、モデルの評価に使用する指標 - max_depth:int型 or None
決定木の深さの最大値(Noneの場合は、深さの制限無し) - random_state:int型
乱数のシードを指定する
RandomForestClassifierはsklearn.ensembleパッケージからインポートします。
実装例
上記の手順に従ってプログラムを作成します。使用する言語はPythonです。
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
import random
if __name__ == '__main__':
# データセットを読み込む
iris = load_iris()
x = iris.data
y = iris.target
# 読み込んだデータセットをシャッフルする
p = list(zip(x, y))
random.shuffle(p)
x, y = zip(*p)
# 学習データの件数を指定する
train_size = 100
test_size = len(x) - train_size
# データセットを学習データとテストデータに分割する
train_x = x[:train_size]
train_y = y[:train_size]
test_x = x[train_size:]
test_y = y[train_size:]
# ランダムフォレストの学習を行う
rfc = RandomForestClassifier(n_estimators=100, criterion='gini', max_depth=None)
rfc.fit(train_x, train_y)
# 学習させたモデルを使ってテストデータに対する予測を出力する
count = 0
pred = rfc.predict(test_x)
for i in range(test_size):
print('[{0}] correct:{1}, predict:{2}'.format(i, test_y[i], pred[i]))
if pred[i] == test_y[i]:
count += 1
# 予測結果から正答率を算出する
score = float(count) / test_size
print('{0} / {1} = {2}'.format(count, test_size, score))
このプログラムを実行すると以下の出力結果が得られます。
[0] correct:0, predict:0 [1] correct:2, predict:2 [2] correct:0, predict:0 ...省略... [47] correct:0, predict:0 [48] correct:0, predict:0 [49] correct:0, predict:0 47 / 50 = 0.94
テスト用データ50件に対する予測は正答率が0.94となりました。十分高い分類精度が得られたことがわかります。