決定木の予測平面を描画してみる③

機械学習

さて、前回『決定木の予測平面を描画してみる② 』、多値でのケースも見てみたのですが、言うて7つの塊が置いてるだけ―、なので
もうちょっと複雑な分布が欲しくなります。なりました。
そこで、また、サイキットラーンデータセッツをまさぐると、やっぱりあるんですよ。
メイクガウシャンクオンタイルズです。

データの準備

先の公式サイトを見ると、
・多次元の標準化(分散:1、平均:0)された正規分布に従うデータを出すよ
・同心円で各データにラベルつけるけど、各ラベルのデータ数がほぼ同じになるようにするよ
ってなことらしい、百聞は一見に如かずだから、また特徴量2個でプロットしてみる。

import numpy as np
import matplotlib.pyplot as plt
plt.style.use("ggplot")

from sklearn.datasets import make_gaussian_quantiles

x,y=make_gaussian_quantiles(cov=20,n_samples=500,n_features=2,n_classes=3,random_state=10)

def plot_datasets(x,y):
    plt.plot(x[:,0][y==0],x[:,1][y==0],"o",c="blue",ms=15,alpha=0.2)
    plt.plot(x[:,0][y==1],x[:,1][y==1],"^",c="red",ms=15,alpha=0.2)
    plt.plot(x[:,0][y==2],x[:,1][y==2],"s",c="green",ms=15,alpha=0.2)
    plt.xlabel("x_0",fontsize=20)
    plt.ylabel("x_1",fontsize=20)

plt.figure(figsize=(15,10))
plot_datasets(x,y)
plt.show()

そういうことですね、サイキットラーンさん。ありがとうございます。
cov(デフォルト:1)は共分散の略ですが、公式見る限り特徴量各々の分散です。等方性を持つ分布をつくる、ということなのでどの特徴量の分散も同じ値にするようです。

そうです、こんなんです。この、ザ・線形分離不可の分布が欲しかったんです。
※前回も線形分離不可ですが。

学習と予測平面の描画

ということで、今回もランダムフォレストでもやっていきます。

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier

各々こんなハイパーパラメータで学習。

tree=DecisionTreeClassifier(max_depth=10,min_samples_leaf=5).fit(x,y)
rtree=RandomForestClassifier(n_estimators=500,max_depth=40,min_samples_leaf=1).fit(x,y)

正解率は、

print(tree.score(x,y))
print(rtree.score(x,y))
0.954
1.0

ランダムフォレスト
・max_depth=40(細かく領域分けていく)
・min_samples_leaf=1(一つの領域に入るデータの最小数を1にする)
としているので、正解率100%になっています。
過学習なのですが、どんな平面が描かれるのかが見たいのでやります。

まずは決定木(CART)

from matplotlib.colors import ListedColormap

def plot_decision_boundary(clf,x,m=0.2):
    _x0=np.linspace(x[:,0].min()-m,x[:,0].max()+m,500)
    _x1=np.linspace(x[:,1].min()-m,x[:,1].max()+m,500)  
    x0,x1=np.meshgrid(_x0,_x1)
    x_new=np.c_[x0.ravel(),x1.ravel()]
    y_pred=clf.predict(x_new).reshape(x1.shape)
    cmap=ListedColormap(["mediumblue","indianred","greenyellow"])
    plt.contourf(x0,x1,y_pred,alpha=0.3,cmap=cmap)

plt.figure(figsize=(15,10))

plot_decision_boundary(tree,x)
plot_datasets(x,y)

plt.show()

お見事。ランダムフォレストだと、

min_samples_leaf=1 なので、1個だけはみ出してるデータまで救って(?)くれています。
ランダムフォレストってすごいね。