Python/scikit-learnのRandomForestでもirisの分類をしてみる
昨日のPySparkのRandomForestを使った記事に引き続き、今日はscikit-learnのRandomForestを使ってみます。
データの読み込みとプロット
>>> import matplotlib.pyplot as plt >>> import sklearn.datasets >>> iris = sklearn.datasets.load_iris() >>> features = iris.data[:, [0, 2]] >>> plt.scatter(*features.T, c=[['orange', 'green', 'blue'][x] for x in iris.target]) >>> plt.show()
昨日とほぼ同じです。今回も長さのデータだけで幅は使いません。
訓練用とテスト用のデータを分ける
精度を測るべく、訓練用とテスト用のデータを分けます。 昨日と同じく7:3の割合で行きます。
>>> import sklearn.model_selection >>> train_x, test_x, train_y, test_y = sklearn.model_selection.train_test_split(features, iris.target, test_size=0.3)
x(特徴量)とy(ラベル)が別々になっているので、PySparkよりちょっと面倒臭い感じがする。
学習器を作って学習
昨日のと違って前処理をしていないので、かなりシンプル。
>>> import sklearn.ensemble >>> rf = sklearn.ensemble.RandomForestClassifier() >>> rf.fit(train_x, train_y)
PySparkの場合と違って、fitの戻り値を保持する必要はありません。
実行して、精度を確かめる
学習が終わったら、実行してみましょう。
>>> prediction = rf.predict(test_x) >>> print(prediction) [0 2 2 1 1 2 0 0 2 2 2 0 0 2 2 2 0 0 1 2 2 2 2 2 0 0 2 1 0 1 2 0 0 1 1 1 0 0 1 1 0 2 1 1 1]
こんな感じ。predict()
を呼ぶと分類した結果が入ったnumpyの配列が返ってきます。
分類器自体に精度を計算するメソッドがあるので、それを使えば簡単に精度を確認出来ます。
>>> accuracy = rf.score(test_x, test_y) >>> print('accuracy {0:.2%}'.format(accuracy)) 95.56%
実行し直すのでデータ量が多い場合は時間が掛かっちゃいそうな気がします。 分類結果も使うのであれば、自分で計算した方が良いかもしれません。
どこを間違えたのかプロットしてみる
>>> plt.scatter(*test_x.T, c=[['orange', 'green', 'blue'][answer] if answer == predict else 'red' for answer, predict in zip(test_y, prediction)]) >>> plt.show()
昨日のものとほぼ一緒。赤い点が間違えた所です。
scikit-learnもmatplotlibもnumpy.arrayを使うので、ほぼ何も変換せずに使えます。せいぜい転置してるくらい。
まとめ
繋げると大体以下のようになります。
import matplotlib.pyplot as plt import sklearn.datasets import sklearn.ensemble import sklearn.model_selection # データの用意 iris = sklearn.datasets.load_iris() features = iris.data[:, [0, 2]] train_x, test_x, train_y, test_y = sklearn.model_selection.train_test_split(features, iris.target, test_size=0.3) # 学習 rf = sklearn.ensemble.RandomForestClassifier() rf.fit(train_x, train_y) # 評価 accuracy = rf.score(test_x, test_y) print('accuracy {0:.2%}'.format(accuracy)) # 結果のプロット prediction = rf.predict(test_x) plt.scatter(*test_x.T, c=[['orange', 'green', 'blue'][answer] if answer == predict else 'red' for answer, predict in zip(test_y, prediction)]) plt.show()
いやあ、超簡単。 とりあえずこっちでやって、時間が掛かりそうならPySparkに移行するのが良いのかもしれません。 大まかなプログラムの流れは変わらないですし、移行するのはそんなに問題にならなそう。