Python 使用dtreeviz可视化决策树

Python 使用dtreeviz可视化决策树,python,scikit-learn,visualization,dtreeviz,Python,Scikit Learn,Visualization,Dtreeviz,我喜欢从中获得的决策树可视化,可以使用 #安装库 !pip安装dtreeviz !apt获取并安装graphviz #示例代码 从sklearn.datasets导入* 从sklearn导入树 从dtreeviz.trees导入* 从IPython.core.display导入显示,HTML 分类器=树。决策树分类器(最大深度=4) 癌症=乳腺癌() 分类器.fit(cancer.data,cancer.target) viz=dtreeviz(分类器, 癌症数据, 癌症,目标, target_

我喜欢从中获得的决策树可视化,可以使用

#安装库
!pip安装dtreeviz
!apt获取并安装graphviz
#示例代码
从sklearn.datasets导入*
从sklearn导入树
从dtreeviz.trees导入*
从IPython.core.display导入显示,HTML
分类器=树。决策树分类器(最大深度=4)
癌症=乳腺癌()
分类器.fit(cancer.data,cancer.target)
viz=dtreeviz(分类器,
癌症数据,
癌症,目标,
target_name='cancer',
功能名称=癌症。功能名称,
类别名称=[“恶性”、“良性”],
幻想(错误)
显示(HTML(即svg()))
然而,当我将上述内容应用于我自己制作的dtree时,代码爆炸了,因为我的数据位于pandas DF(或np数组)中,而不是scikit学习束对象中

现在,他们非常严厉地告诉我,不要试图创建一个束对象;但我也不具备将DF或NP数组转换为viz函数可以接受的东西的技能

我们可以假设我的DF有九个特性和一个目标,分别称为“Feature01”、“Feature02”等和“Target01”

我通常会这样分开

FeatDF=FullDF.drop(列=[“Target01”]) LabelDF=FullDF[“Target01”] 然后以我的方式指定一个分类器,或者如果是ML,则创建一个测试/训练分割

当调用
dtreeviz
时,这一切都没有帮助,因为dtreeviz需要“feature\u 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) 

还是这太愚蠢了?感谢您迄今为止的指导

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

让我们看一看iris数据集的示例

从sklearn.datasets导入*
#加载虹膜数据
iris=加载_iris()
#虹膜类型
类型(虹膜)
如前所述,数据集存储为sklearn Bunch对象

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

#虹膜数据-参数
类型(iris.data)
#形状
data.data.shape
(150, 4)
因此很明显,
dtreeviz
方法使用的是numpy数组,没有使用Bunch对象。在您的情况下,要素名称与选定要素的列名无关

更新

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_)
         )
#替换示例代码中的以下内容以适合您的数据帧
cancer.data DF.iloc[:,:-1]
cancer.target DF['Target01']
#其他参数
特征名称=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_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_)
         )


旧答案

让我们使用cancer数据集创建一个数据帧

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)
i、 e.只需将最后一列以外的所有列作为培训/输入,
target
列作为输出/目标

可视化也一样:

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

您能否提供一个示例,以便我们可以复制该问题?您能否提供尝试调用dtreeviz的方式?因为我知道如何构造数据帧,但我想知道如何使用数据帧调用函数,以及错误是什么。谢谢。你说得对,我很困惑!假设我使用上面的DF-我是否转换为单个numpy数组并使用它?似乎不起作用。此外,在上面的示例中,cancer.data和cancer.target不是coll-因此似乎还有其他事情在进行(除了feature_names=coll(我得到了))。在最基本的层面上:你将如何处理玩具DF,使其对dtreeviz友好?再次感谢。我已经用集成示例数据帧的方式更新了答案
DF
。它包括如果您有大量的功能和标签以及。如果您觉得有帮助,请选中“回答”旁边的复选框。干杯谢谢我想我们很接近。。。也许我只是犯了一个明显的错误。上面返回的错误是
异常:类名称必须是dict或sequence,而不是ndarray。
如果我将
类名称=DF['Target01'].unique()替换为
类名称=[“红色”、“蓝色”、“蓝色”]
,我的任务是
TypeError:不能将序列乘以类型为'float'的非int
。它需要一个
列表
。错误消息指定将列表与某个值相乘。确保只为
类名
Try list(DF['Target01'].unique())分配一个元素列表如果您觉得解决方案有用,请向上投票并选中复选框以接受解决方案。感谢您再次参与。在癌症研究中,目标是整数,对吗?然而,当我使用玩具df和
class\u names=[“Red”、“Blue”、“Teal”]
时,我得到
TypeError:不能将序列乘以'float'类型的非int
,当我说
class\u names=list(df['Target01'].unique())
时,它会引发一个不祥的
关键错误:3
。这有什么意义吗?对不起,我应该补充一下,在上面的第二部分,我也把红色改为1,蓝色改为2,蓝绿色改为3…@R