web-dev-qa-db-ja.com

scikit-learnの決定木を説明する方法

Scikit-learnの決定木の結果を理解するには、2つの問題があります。たとえば、これは私の意思決定ツリーの1つです。

enter image description here 私の質問は、ツリーをどのように使用できるかということです。

最初の質問は、サンプルが条件を満たしている場合は[〜#〜] left [〜#〜]分岐(存在する場合)に進み、そうでない場合は[ 〜#〜]正しい[〜#〜]。私の場合、X [7]> 63521.3984のサンプルの場合。その後、サンプルは緑色のボックスに移動します。正しい?

2番目の質問は、サンプルがリーフノードに到達したときに、どのカテゴリに属する​​かをどのようにして知ることができるかということです。この例では、分類する3つのカテゴリがあります。赤いボックスには、それぞれ91、212、113のサンプルが条件を満たしています。しかし、どうすればカテゴリを決定できますか?カテゴリを伝えるための関数clf.predict(sample)があることは知っています。グラフからできますか???どうもありがとう。

24
Student Jack

各ボックスのvalue行は、そのノードのサンプル数が順番に各カテゴリに分類されることを示しています。そのため、各ボックスのvalueの数値は、sampleに表示される数値と合算されます。たとえば、赤いボックスの91 + 212 + 113 = 416です。つまり、このノードに到達すると、カテゴリ1には91個のデータポイントがあり、カテゴリ2には212個、カテゴリ3には113個のデータポイントがありました。

デシジョンツリーのリーフに到達した新しいデータポイントの結果を予測する場合は、カテゴリ2を予測します。これは、そのノードでのサンプルの最も一般的なカテゴリであるためです。

26
BrenBarn

最初の質問:はい、あなたの論理は正しいです。左のノードはTrue、右のノードはFalseです。これは直観に反する場合があります。 trueは、より小さなサンプルに相当します。

2番目の質問:この問題は、pydotplusを使用してツリーをグラフとして視覚化することで最適に解決されます。 tree.export_graphviz()の「class_names」属性は、各ノードの過半数クラスにクラス宣言を追加します。コードはiPythonノートブックで実行されます。

from sklearn.datasets import load_iris  
from sklearn import tree  
iris = load_iris()  
clf2 = tree.DecisionTreeClassifier()  
clf2 = clf2.fit(iris.data, iris.target)  

with open("iris.dot", 'w') as f:  
    f = tree.export_graphviz(clf, out_file=f)  

import os  
os.unlink('iris.dot')  

import pydotplus  
dot_data = tree.export_graphviz(clf2, out_file=None)  
graph2 = pydotplus.graph_from_dot_data(dot_data)  
graph2.write_pdf("iris.pdf")  

from IPython.display import Image  
dot_data = tree.export_graphviz(clf2, out_file=None,  
                     feature_names=iris.feature_names,  
                     class_names=iris.target_names,  
                     filled=True, rounded=True,  # leaves_parallel=True, 
                     special_characters=True)  
graph2 = pydotplus.graph_from_dot_data(dot_data)

## Color of nodes
nodes = graph2.get_node_list()

for node in nodes:
    if node.get_label():
        values = [int(ii) for ii in node.get_label().split('value = [')[1].split(']')[0].split(',')];
        color = {0: [255,255,224], 1: [255,224,255], 2: [224,255,255],}
        values = color[values.index(max(values))]; # print(values)
        color = '#{:02x}{:02x}{:02x}'.format(values[0], values[1], values[2]); # print(color)
        node.set_fillcolor(color )
#

Image(graph2.create_png() ) 

enter image description here

葉のクラスを決定することに関しては、あなたの例には、アヤメのデータセットのように、単一のクラスを持つ葉はありません。これは一般的であり、そのような結果を得るにはモデルを過剰適合させる必要がある場合があります。クラスの離散分布は、多くの相互検証済みモデルにとって最良の結果です。

コードをお楽しみください!

7
MyopicVisage

「scikit-learnの学習:Pythonでの機械学習」という本によると、決定木はトレーニングデータに基づく一連の決定を表しています。

!( http://i.imgur.com/vM9fJLy.png

インスタンスを分類するには、各ノードでの質問に答える必要があります。たとえば、セックスは0.5以下ですか? (私たちは女性について話しているのですか?) 答えが「はい」の場合、ツリーの左側の子ノードに移動します。それ以外の場合は、正しい子ノードに移動します。葉に達するまで、質問に答え続けます(彼女は3番目のクラスにいましたか?、彼女は1番目のクラスにいましたか?、彼女は13歳未満でしたか?)。 そこにいるとき、予測はほとんどのインスタンスを持つターゲットクラスに対応します

1
user3784777

Feature_names = X.columnsをtree.export_graphvizに追加します。Xはトレーニングデータです。

私のコードは次のとおりです

with open("lectureGini.txt", "w") as f:
    f = tree.export_graphviz(lectureGini, out_file=f,feature_names=X.columns)
# copy contents of file LectureGini.txt into WebGraphviz - http://webgraphviz.com/

lectureGiniは、DecisionTreeClassifierからの出力です。

これは、私が調査したGini IndexのすべてのWeb例に追加できる簡単な方法です。すべてのWebの例はこの方法を非常によく説明しましたが、カテゴリを見つける方法を示したものはありませんでした。 Graphvizをまだインストールしていないので、jupyterからテキストファイルをエクスポートし、テキストをWebgraphwizにコピーしています。

0
Roo