クラス分類問題において、非線形な識別を可能にするランダムフォレストを用いた手法について、実装・解説します。
本シリーズでは、Pythonを使用して機械学習を実装する方法を解説します。
各アルゴリズムの数式だけでなく、その心、意図を解説していきたいと考えています。
ランダムフォレストは、以下のscikit-learnマップの黒矢印に対応します。
START→データが50以上→カテゴリーデータ→ラベルありデータ→データ数10万以下→Linear SVC失敗→K近傍法失敗→Ensemble Classification(の1つがランダムフォレスト)
ランダムフォレストは、決定木を複数用意して多数決で識別する、クラス分類手法です。
実装例
まずはじめに実装例を紹介します。
使用するデータはXORの分類データです。
これに対してランダムフォレストで識別を行うと、以下のような結果となります。
とてもキレイに学習、識別できています。
テストデータに対する正答率は1になっており100%です。
コードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | # 1:ライブラリのインポート-------------------------------- import numpy as np #numpyという行列などを扱うライブラリを利用 import pandas as pd #pandasというデータ分析ライブラリを利用 import matplotlib.pyplot as plt #プロット用のライブラリを利用 from sklearn import ensemble, metrics, preprocessing, cross_validation #機械学習用のライブラリを利用 from mlxtend.plotting import plot_decision_regions #学習結果をプロットする外部ライブラリを利用 # 2:XORのデータを作成する(x=正、y=正)=0,(x=正、y=負)=1, 的な-------------- np.random.seed(0) X_xor=np.random.randn(200,2) y_xor=np.logical_xor(X_xor[:,0]>0, X_xor[:,1]>0) y_xor=np.where(y_xor,1,0) pd.DataFrame(y_xor) #この行を実行するとデータが見れる # 3:プロットしてみる------------------------------------------------------ %matplotlib inline plt.scatter(X_xor[y_xor==1, 0], X_xor[y_xor==1, 1], c='b', marker='x', label='1') plt.scatter(X_xor[y_xor==0, 0], X_xor[y_xor==0, 1], c='r', marker='s', label='0') plt.legend(loc='best') plt.show # 4:データの整形------------------------------------------------------- X_std=X_xor z=y_xor # 解説5:機械学習で分類する--------------------------------------------------- clf_result=ensemble.RandomForestClassifier(criterion='entropy', n_estimators=10, random_state=1, n_jobs=2,class_weight="balanced") clf_result.fit(X_std, z) # 6:K分割交差検証(cross validation)で性能を評価する--------------------- scores=cross_validation.cross_val_score(clf_result, X_std, z, cv=10) print("平均正解率 = ", scores.mean()) print("正解率の標準偏差 = ", scores.std()) # 7:トレーニングデータとテストデータに分けて実行してみる------------------ X_train, X_test, train_label, test_label=cross_validation.train_test_split(X_std,z, test_size=0.1, random_state=0) clf_result.fit(X_train, train_label) #正答率を求める pre=clf_result.predict(X_test) ac_score=metrics.accuracy_score(test_label,pre) print("正答率 = ",ac_score) #plotする X_train_plot=np.vstack(X_train) train_label_plot=np.hstack(train_label) X_test_plot=np.vstack(X_test) test_label_plot=np.hstack(test_label) #plot_decision_regions(X_train_plot, train_label_plot, clf=clf_result, res=0.01) #学習データをプロット plot_decision_regions(X_test_plot, test_label_plot, clf=clf_result, res=0.01, legend=2) #テストデータをプロット # 8:任意のデータに対する識別結果を見てみる------------------ #predicted_label=clf_result.predict([1.0,-1.0]) #print("このテストデータのラベル = ", predicted_label) |
コードに関してはカーネルSVMのときとほぼ同じです。
解説5の部分だけ異なります。
#解説 5:機械学習で分類する—————————————————
clf_result=ensemble.RandomForestClassifier(criterion=’entropy’, n_estimators=10, random_state=1, n_jobs=2,class_weight=”balanced”)
このコードは、識別器としてランダムフォレストを使用します。
決定木を作成する指標としては「エントロピー」を使用します。
決定木は10本作成して、多数決します。
乱数のシードは1で固定しておきます。
CPUのコア2つを使用して並列で計算します。
クラスごとのサンプル数に偏りがある分は補正します。
という以上の内容を設定しています。
それでは「結局、ランダムフォレストって何をやっていたの?」を説明します。
ランダムフォレストの心
正確な情報は以下をご覧ください。
●scikit-learnのEnsemble methodsの解説ページ
ランダムフォレストは決定木を複数作成し、その多数決で識別結果を決める手法です。
決定木とは、特徴量に対して、単純な識別条件で2分類を繰り返す識別手法です。
今回の例では特徴量は2次元の(x,y)です。
そのため x>a or not でまず第一段階の識別をし、
その後、y>b or not で第二段階の識別をして、
最終的にクラス0か1かを決める
的なことをします。
とくに今回はXORなので、x>0, y>0 と x<0, y<0を使えば完璧に分類できることになります。
ここで、
「xで分類するのか、yで分類するのか、そしてその基準となるaやbの値をどう決めるのか?」
が問題となります。
そこで、今回はエントロピーを用いています。
その他にジニ不純度なども用いられます。
これらの指標をどう計算するかは、ここではおいて置きます。
ただやりたい心は、分ける前はクラス0,1がごちゃごちゃ入っているのが、できるだけクラス0だけとクラス1だけに分かれる基準で分けるということです。
このきれいに分かれている度合いを、エントロピーやジニ不純度で測定します。
これが決定木による識別手法です。
ですが、これでは同じ決定木が10本できるのでは?と思います。
そうならないようにランダムフォレストではブーストストラップ・サンプリングという手法を使用します。
これは学習データの数がNのとき、学習データから適当にN個をとってくる手法です。
このときに同じデータを何度もとってくることを許します。
そのため、N個からN個をとっても、毎回少し異なる学習データが得られることになります。
こうしてサンプリングしたN個のデータに対して決定木を作成する、という操作をN個の取り方を変えながら、今回であれば10回おこない、10本の決定木を作成しています。
テストデータに対してはこの10本の決定木で識別をして10個の識別結果を求め、多数決で最終的なクラスを決定します。
以上、Pythonとscikit-learnで学ぶ機械学習入門|第6回:クラス分類 -ランダムフォレスト-でした。
次回は、textデータをナイーブベイズで識別する手法について解説します。