クラス分類問題において、非線形な識別を可能にするカーネルSVMを用いた手法について、実装・解説します。
本シリーズでは、Pythonを使用して機械学習を実装する方法を解説します。
また各アルゴリズムの数式だけでなく、その心、意図を解説していきたいと考えています。
Kernel SVCは、以下のscikit-learnマップの黒矢印に対応します。
START→データが50以上→カテゴリーデータ→ラベルありデータ→データ数10万以下→Linear SVC失敗→K近傍法失敗→Kernel SVC
Kernel SVCは、カーネルを使用するSVM(サポートベクトル・マシン)に基づくクラス分類手法です。
実装例
まずはじめに実装例を紹介します。
使用するデータは第2, 4回と同じくXORの分類データです。
これに対してKernel SVCを行うと、以下のような結果となります。
コードは以下の通りです。
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 56 57 58 59 60 | # 1:ライブラリのインポート-------------------------------- import numpy as np #numpyという行列などを扱うライブラリを利用 import pandas as pd #pandasというデータ分析ライブラリを利用 import matplotlib.pyplot as plt #プロット用のライブラリを利用 from sklearn import svm, metrics, preprocessing, cross_validation #機械学習用のライブラリを利用 from mlxtend.plotting import plot_decision_regions #学習結果をプロットする外部ライブラリを利用 from sklearn.kernel_approximation import RBFSampler #カーネル近似用の関数 from matplotlib.colors import ListedColormap #plot用 # 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=svm.SVC(kernel='rbf', gamma=1/2 , C=1.0,class_weight='balanced', random_state=0) #loss='squared_hinge' #loss="hinge", loss="log" 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) # 9:識別平面の式を手に入れる-------------------------------- #print(clf_result.intercept_) #print(clf_result.dual_coef_ ) #coef[0]*x+coef[1]*y+intercept=0 |
コードに関してはカーネル近似やK近傍法のときとほぼ同じです。
解説5の部分だけ異なります。
#解説 5:機械学習で分類する—————————————————
clf_result=svm.SVC(kernel=’rbf’, gamma=1/2 , C=1.0,class_weight=’balanced’, random_state=0)
このコードは、識別器としてSVCを使用します。
カーネルの種類としてはrbfカーネル(ガウスカーネル)を使用します。
ガウスカーネルの係数gammaはdefaultでは1/次元数であり、今回は1/2としています。
分類ミスに対して損失の大きさは自動的にhinge関数になります。
損失の大きさをどれくらい考慮するかを決めるパラメータCは1.0とします。
またクラスごとのデータ数の違いを補正します(weight=’balanced’)。
乱数のシードは0に固定しておきます。
という命令になっています。
ちなみにカーネルを使わない(Linear Kernel)の場合は以下のような結果となりうまく識別できません。
それでは「結局、Kernel SVCって何をやっていたの?」を説明します。
Kernel SVCの心
正確な情報は以下をご覧ください。
●scikit-learnのKernel SVCの解説ページ
Kernel SVCはカーネルトリックを使用したSVMに基づく分類手法です。
カーネルトリックは以下で説明しています。
SVMは以下で説明しています。
これらを参照してください。
以上、Pythonとscikit-learnで学ぶ機械学習入門|第5回:クラス分類 -Kernel SVC-でした。
次回は、Ensemble classificationのランダムフォレストについて解説します。