#### 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=クラス <==ジニ不純度
# 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')
'''''
#予測する
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
# 決定木の可視化
# $ 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())