使用dtreeviz可视化决策树

时间:2019-06-20 09:59:31

标签: python scikit-learn visualization

我喜欢Dtreeviz library - GitHub提供的决策树可视化效果,并且可以使用

# Install libraries
!pip install dtreeviz
!apt-get install graphviz

# Sample code
from sklearn.datasets import *
from sklearn import tree
from dtreeviz.trees import *
from IPython.core.display import display, HTML

classifier = tree.DecisionTreeClassifier(max_depth=4)
cancer = load_breast_cancer()

classifier.fit(cancer.data, cancer.target)
viz = dtreeviz(classifier,
               cancer.data,
               cancer.target,
               target_name='cancer',
               feature_names=cancer.feature_names, 
               class_names=["malignant", "benign"],
               fancy=False) 

display(HTML(viz.svg()))

但是,当我将上面的代码应用于我自己制作的dtree时,代码爆炸了,因为我的数据位于pandas DF(或np数组)中,而不是scikit-learn束对象。

现在,在Sci-kit learn - How to create a Bunch object,他们很严厉地告诉我不要试图创建一个束对象。但是我也不具备将DF或NP数组转换为上述viz函数可以接受的功能的技能。

我们可以假设我的DF具有9个功能和一个目标,分别是“ Feature01”,“ Feature02”等和“ Target01”。

我通常会这样拆分

FeatDF  = FullDF.drop( columns = ["Target01"])
LabelDF = FullDF["Target01"]

,然后以我喜欢的方式进行设置以分配分类器,或者如果是ML,则创建测试/训练拆分。

在调用dtreeviz时,这些方法都没有帮助-期望像“ feature_names”(我认为“ bunch”对象中包含某些东西)之类的东西。而且由于我无法将DF转换成一束,所以我非常困住。哦,请带来你的智慧。

更新:我想任何简单的DF都可以说明我的难题。我们可以随便

import pandas as pd

Things = {'Feature01': [3,4,5,0], 
          'Feature02': [4,5,6,0], 
          'Feature03': [1,2,3,8], 
          'Target01': ['Red','Blue','Teal','Red']}
DF = pd.DataFrame(Things,
                  columns= ['Feature01', 'Feature02', 
                            'Feature02', 'Target01']) 

作为示例DF。现在,我可以走了吗

DataNP = DF.to_numpy()
classifier.fit(DF.data, DF.target)
feature_names = ['Feature01', 'Feature02', 'Feature03'] 
#..and what if I have 50 features...

viz = dtreeviz(classifier,
               DF.data,
               DF.target,
               target_name='Target01',
               feature_names=feature_names, 
               class_names=["Red", "Blue", "Teal"],
               fancy=False) 

还是这个傻瓜?感谢到目前为止的指导!

2 个答案:

答案 0 :(得分:1)

  • sklearn的决策树需要数字目标值
  • 您可以使用sklearn的LabelEncoder将字符串转换为整数

    from sklearn import preprocessing
    
    label_encoder = preprocessing.LabelEncoder()
    label_encoder.fit(df.Target01)
    
    df['target'] = label_encoder.transform(df.Target01)
    
  • dtreeviz期望class_nameslistdict,所以让我们从我们的label_encoder

    中获取它
    class_names = list(label_encoder.classes_)        
    

完整代码

import pandas as pd
from sklearn import preprocessing, tree
from dtreeviz.trees import dtreeviz

Things = {'Feature01': [3,4,5,0], 
          'Feature02': [4,5,6,0], 
          'Feature03': [1,2,3,8], 
          'Target01': ['Red','Blue','Teal','Red']}
df = pd.DataFrame(Things,
                  columns= ['Feature01', 'Feature02', 
                            'Feature02', 'Target01']) 

label_encoder = preprocessing.LabelEncoder()
label_encoder.fit(df.Target01)
df['target'] = label_encoder.transform(df.Target01)

classifier = tree.DecisionTreeClassifier()
classifier.fit(df.iloc[:,:3], df.target)

dtreeviz(classifier,
         df.iloc[:,:3],
         df.target,
         target_name='toy',
         feature_names=df.columns[0:3],
         class_names=list(label_encoder.classes_)
         )

enter image description here


旧答案

让我们使用癌症数据集来创建熊猫数据框

df = pd.DataFrame(cancer.data, columns=cancer.feature_names)
df['target'] = cancer.target

这将为我们提供以下数据框。

mean radius mean texture    mean perimeter  mean area   mean smoothness mean compactness    mean concavity  mean concave points mean symmetry   mean fractal dimension  radius error    texture error   perimeter error area error  smoothness error    compactness error   concavity error concave points error    symmetry error  fractal dimension error worst radius    worst texture   worst perimeter worst area  worst smoothness    worst compactness   worst concavity worst concave points    worst symmetry  worst fractal dimension target
0   17.99   10.38   122.8   1001.0  0.1184  0.2776  0.3001  0.1471  0.2419  0.07871 1.095   0.9053  8.589   153.4   0.006399    0.04904 0.05373 0.01587 0.03003 0.006193    25.38   17.33   184.6   2019.0  0.1622  0.6656  0.7119  0.2654  0.4601  0.1189  0
1   20.57   17.77   132.9   1326.0  0.08474 0.07864 0.0869  0.07017 0.1812  0.05667 0.5435  0.7339  3.398   74.08   0.005225    0.01308 0.0186  0.0134  0.01389 0.003532    24.99   23.41   158.8   1956.0  0.1238  0.1866  0.2416  0.186   0.275   0.08902 0
2   19.69   21.25   130.0   1203.0  0.1096  0.1599  0.1974  0.1279  0.2069  0.05999 0.7456  0.7869  4.585   94.03   0.00615 0.04006 0.03832 0.02058 0.0225  0.004571    23.57   25.53   152.5   1709.0  0.1444  0.4245  0.4504  0.243   0.3613  0.08758 0
[...]
568 7.76    24.54   47.92   181.0   0.05263 0.04362 0.0 0.0 0.1587  0.05884 0.3857  1.428   2.548   19.15   0.007189    0.00466 0.0 0.0 0.02676 0.002783    9.456   30.37   59.16   268.6   0.08996 0.06444 0.0 0.0 0.2871  0.07039 1

对于您的分类器,可以按以下方式使用。

classifier.fit(df.iloc[:,:-1], df.target)

即只需将除最后一列以外的所有内容作为训练/输入,并将target列作为输出/目标。

相同的可视化效果:

viz = dtreeviz(classifier,
               df.iloc[:,:-1],
               df.target,
               target_name='cancer',
               feature_names=df.columns[0:-1],
               class_names=["malignant", "benign"]) 

答案 1 :(得分:0)

我认为您对文档中提供的示例感到困惑。

Here让我们看一下带有虹膜数据集的示例。

from sklearn.datasets import *

# Loading iris data
iris = load_iris()

# Type of iris
type(iris)
<class 'sklearn.utils.Bunch'>

如上所述,数据集存储为sklearn Bunch对象。

但是dtreeviz不在其任何参数中使用此对象。所有参数都是numpy数组。

# Iris data - parameter
type(iris.data)
<class 'numpy.ndarray'>

# Shape
data.data.shape
(150, 4)

因此很显然dtreeviz方法正在使用numpy数组,并且不使用Bunch对象。就您而言,所选名称的列名称中没有任何功能名称。

更新

# Replace the following the the sample code to fit your dataframe
cancer.data <> DF.iloc[:, :-1]
cancer.target <> DF['Target01']

# Other parameters
feature_names = DF.columns[:-1]
class_names = DF['Target01'].unique()