決定木は以下の図のように「重さが5kg以下かどうか」「飛ぶことができるか」のようなルールでデータを振り分けていく方法です。このルールの部分を大量のデータで学習するのが決定木です。機械的にルールが計算されるので、ここまでわかりやすい決定木ができることはほぼありませんが、どのような振り分け方をしているかはわかります。そのため、機械学習がよくブラックボックスだといわれるのに対し、決定木は解釈可能なモデルといわれます。
画像分類に適用する場合は、「N 番目の画素の明るさが K 以上かどうか」のような直感的には理解し難いルールができあがります。
scikit-learn を利用して決定木を実装しましょう。決定木の使い方は scikit-learn のページの Examples に書かれています。ノートブックで使えるように転記したものが以下になります。
from sklearn import tree
X = [[0, 0], [1, 1]]
y = [0, 1]
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, y)
print(clf.predict([[2., 2.]]))
print(clf.predict_proba([[2., 2.]]))
主に以下の4ステップで構成されています。
上記の処理の流れはk-近傍法と同じであることに気づくと思います。
上記のコードを Jupyter Notebook で実行してみましょう。
上の例を少し書き換えて、MNIST のデータに決定木を適用してみましょう。 k-近傍法のときと同様に、Xに X_train, y に y_train を入力し、予測データに X_test[0] をいれます。 今回はサンプルコードをあえて表示しないので、ご自身で実装してみましょう。参考までにk-近傍法のコードは以下でした。
X = X_train
y = y_train
from sklearn.neighbors import KNeighborsClassifier
neigh = KNeighborsClassifier(n_neighbors=3)
neigh.fit(X, y)
print(neigh.predict([X_test[0]]))
print(neigh.predict_proba([X_test[0]]))
よくあるエラー1
カッコの数が左右であっていないと invalid syntax や unexpected EOF などになります。エラーの近くのカッコの数があっているか確認しましょう。
よくあるエラー2
X のデータは2軸のデータである必要があります。画像1枚 (例えば、X_test[0])だと画素のデータしかないので以下のようなエラーになります。
1枚だけ選ぶ場合は [X_test[0]] としてカッコでさらに囲んで軸を増やす必要があります。画像2枚以上 (X_test[0:2])だと、逆に囲んではいけません(3軸になってしまいます)。
よくあるエラー3
変数の名前を間違えると、not defined のエラーが出ます。大文字・小文字など気をつけましょう。
k-近傍法は推論時間が遅いというデメリットがありましたが決定木がどうか調べてみましょう。さきほどと同様に %%time をセルの最初に書いて、100枚の画像を予測をさせれば良いです。
100枚の画像に対する予測の時間を調べてみましょう。
ヒント
k-近傍法のときは以下のコードを利用しました。
%%time
neigh.predict(X_test[0:100])