In [25]:
#### Decision tree

# 根ノード > 親ノード > 子ノード > エッジ
# root node > node > leaf node

# 情報利得:infomation gain
# データをある特徴量で分割したときどれだけ得をしたかの指標
# クラスをきれいに分けたい
#  ==> 分けたつもりだけど、どれだけ混在してしまったかを評価する
#    ==> 不純度
# データを分割すると不純度が下がるハズ。うまく特徴量を分割すれば不純度は一気に下るハズ
# 情報利得 = (親ノードでの不純度 ー 子ノードでの不純度)
# つまり、子ノードに分けたけど不純度が下がってなければ、分割する意味がなかったということ。

# 不純度
# >ジニ不純度(sklearnのデフォルト)
# >エントロピー
# >分類誤差

# ジニ不純度
# あるnodeにclass0が入る確率=0.6,class1が入る確率=0.4 のとき
# class0なのにclass1へ振り分けられてしまう確率: 0.4x0.6=0.24 : P(0)(1-P(0)) 
# class1なのにclass0へ振り分けられてしまう確率: 0.6x0.4=0.24
# よって、データが間違った方へ振り分けられてしまう確率は0.48
# 式で表現すると
# P(0)(1-P(0)) + P(1)(1-P(1))
# =P(0)-P(0)^2 +P(1) - P(1)^2
# =1- (P(0)^2 + P(1)^2)
# =1-ΣP(c)^2 :c=クラス   <==ジニ不純度
In [32]:
# DecisionTreeClassifier
# モジュール:サンプルデータ>訓練検証分割>モデル 
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

# データのインスタンスを作成
iris = load_iris()

# キーを確認
iris.keys()
#dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename'])

# input dataとtarget data として抽出する
X, y = iris.data, iris.target

# 訓練・検証データに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y ,test_size=0.3, random_state=0)

# 決定木モデルのインスタンスを作成する
tree = DecisionTreeClassifier(max_depth=10)

# 訓練する
tree.fit(X_train, y_train)

'''
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=3,
            max_features=None, max_leaf_nodes=None,
            min_impurity_decrease=0.0, min_impurity_split=None,
            min_samples_leaf=1, min_samples_split=2,
            min_weight_fraction_leaf=0.0, presort=False, random_state=None,
            splitter='best')
'''''
Out[32]:
"\nDecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=3,\n            max_features=None, max_leaf_nodes=None,\n            min_impurity_decrease=0.0, min_impurity_split=None,\n            min_samples_leaf=1, min_samples_split=2,\n            min_weight_fraction_leaf=0.0, presort=False, random_state=None,\n            splitter='best')\n"
In [33]:
#予測する
y_predicted = tree.predict(X_test)
y_predicted

# 正解率を算出する
import pandas as pd
df = pd.DataFrame(y_test,y_predicted)#, y_test, y_predicted)

result = df.index == df[0]

'''
array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True, False,  True,  True,  True,  True,  True,  True,  True])
'''

score = sum(result)/len(result)
'''
0.9777777777777777
'''
score
Out[33]:
0.9777777777777777
In [34]:
# 決定木の可視化
# $ pip install pydotplus
from pydotplus import graph_from_dot_data
from sklearn.tree import export_graphviz
import os

# dot形式データの抽出
dot_data = export_graphviz(tree, filled=True,
                           rounded=True,
                           class_names=['Setosa',
                                        'Versicolor',
                                        'Virginica'],
                           feature_names=['Sepal Length',
                                          'Sepal Width',
                                          'Petal Length',
                                          'Petal Width'],
                           out_file=None)

# 決定木のプロット
# グラフのインスタンスを作成
graph = graph_from_dot_data(dot_data)

'''graphvizのインストール
https://graphviz.gitlab.io/_pages/Download/Download_windows.html
graphviz-2.38.zip
展開して、C:\\Program Files (x86)\\graphviz-2.38\\release\\bin\\dot.exeになるようにgraphviz-2.38フォルダを移動する
'''
#パスを通す
graph.progs = {'dot': u'C:\\Program Files (x86)\\graphviz-2.38\\release\\bin\\dot.exe'}

# treeグラフを保存する
graph.write_png('tree.png')

# treeグラフを描画する
from IPython.display import Image
Image(graph.create_png())
Out[34]:
In [5]:
 
In [ ]: