使用 dtreeviz 可视化决策树

Use dtreeviz to visualize decision tree

我喜欢 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 有九个特征和一个目标,称为 'Feature01'、'Feature02' 等和 'Target01'.

这个我一般会这样分的

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

然后按照我喜欢的方式设置一个分类器,或者如果是 ML,则创建一个 test/train 拆分。

None 这在调用 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) 

或者这是愚蠢的吗?感谢您到目前为止的指导!

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

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()
  • 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_)
         )


旧答案

让我们使用癌症数据集创建一个 Pandas 数据框

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)

即只需将除最后一列以外的所有列作为 training/input 并将 target 列作为 output/target.

可视化相同:

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