美文网首页
Python中的决策树模型--构建、可视化、评估

Python中的决策树模型--构建、可视化、评估

作者: Python_Camp | 来源:发表于2022-06-15 11:30 被阅读0次

Python中的决策树模型--构建、可视化、评估
来自MITx Analytics Edge的使用Python的指南和实例
分类和回归树(CART)可以转化为预测分类的图形或规则集。当逻辑回归模型不能提供足够的决策边界来预测标签时,它们会有所帮助。此外,决策树模型更具有可解释性,因为它们模拟了人类的决策过程。此外,决策树回归可以捕捉到非线性关系,从而允许建立更复杂的模型。

Decision Tree Models in Python .jpeg

作者根据Unsplash上Johann Siemens的照片进行修改
CART模型是如何工作的?
考虑两个独立变量X1和X2的情况。我们想预测结果是红色还是蓝色。CART试图将这个数据分割成子集,使每个子集尽可能地纯洁或同质。

决策树逻辑和数据拆分 - 图片由作者提供。
第一个分割(split1)以一种方式分割数据,如果变量X2小于60,将导致蓝色结果,如果不是,将导致看第二个分割(split2)。当X1>20时,考虑到X2<60,Split2指导预测红色。如果X2<90,Split3将预测蓝色,否则预测红色。

如何控制模型的性能?
在你通过学科知识或特征选择过程为模型选择了要考虑的变量后,你需要定义最佳的分割数量。

拆分的目标是增加每个节点的结果的同质性。增加其对数据进行分类的能力。换句话说,在每次分裂后增加纯度。如果我们预测的是蓝色和红色,如果可能的话,选择能给出所有蓝色和所有红色的拆分数量。选择能产生纯净结果的拆分数量。

一个纯粹的节点是一个能产生完美预测的节点。

但如何量化拆分后的纯度,以确保我们有尽可能多的纯净节点。

我们的目标是在每次拆分后减少不确定性。一个不好的分割会使结果是50%的蓝色和50%的红色。完美的分割会得到100%的蓝色,例如。

为了衡量拆分后信息量的增加情况,我们可以依靠以下措施。

1 - 熵 [熵=-1sum(plog(p)) ]

2 - 基尼不纯度[Gini = sum(p(1-p)), 其中p是子分区内错误分类的观察比例] 。

例子。
预测史蒂文斯法官的决定
目标是预测史蒂文斯法官是否投票推翻法院的判决,1表示投票推翻判决,0表示他维持法院的判决。

代码和数据都可以在GitHub上找到。

数据框架如下所示,目标变量为 "逆转"。


Decision tree logic and data splitting .jpeg

史蒂芬法官的法庭裁决 - 图片由作者提供
重要提示:决策树(DT)可以处理连续变量和数字变量。但如果你使用的是Python Scikit Learn,你可能会得到一个关于分类的ValueError。

特征中有许多分类值,我们将使用下面的函数将其转换为数值。

def convert_cat(df,col):
    """
    输入:数据帧和分类列的col列表
    输出:带有数值的数据框架
    """
    for c in col:
        item_list = df[c].unique().tolist()
        enum=enumerate(item_list)
        d = dict((j,i) for i,j in enum)
        print(c)
        print(d)
        
        df[c].replace(d, inplace=True)
    return df
convert_cat(df,['Circuit', 'Issue', 'Petitioner', 'Respondent',
       'LowerCourt'])

将数据分成训练和测试

X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=0)
在训练数据上建立一个决策树模型

clf = tree.DecisionTreeClassifier('gini', min_samples_leaf=30, random_state=0)
clf = clf.fit(X_train, y_train)

绘制决策树模型

from sklearn import tree # 用于决策树模型
plt.figure(figsize = (20,16))
tree.plot_tree(clf, fontsize = 16,rounded = True , filled = True)

Decision tree model.jpeg

决策树模型 - 图片由作者提供
使用分类报告来评估该模型。

predTree = clf.predict(X_test)
from sklearn.metrics import accuracy_score,confusion_matrix, classification_report
report = classification_report(predTree, y_test)
print(report)
          precision    recall  f1-score   support

       0       0.48      0.64      0.55        39
       1       0.77      0.64      0.70        75

accuracy                           0.64       114

macro avg 0.63 0.64 0.63 114
weighted avg 0.67 0.64 0.65 114

# plot a confusion matrix
def plot_confusion_matrix(y,y_predict):
    "this function plots the confusion matrix"
    from sklearn.metrics import confusion_matrix


    cm = confusion_matrix(y, y_predict)
    ax= plt.subplot()
    sns.heatmap(cm, annot=True, ax = ax); #annot=True to annotate cells
    ax.set_xlabel('Predicted labels')
    ax.set_ylabel('True labels')
    ax.set_title('Confusion Matrix'); 
    ax.xaxis.set_ticklabels(['1 ', '0']); ax.yaxis.set_ticklabels(['1', '0'])
plot_confusion_matrix(y_test,predTree)
cVdDsWAxxz.png

阅读分类报告 混淆矩阵
F1_score: 2(精度召回率)/(精度+召回率)

F1分数,是衡量一个模型在数据集上的准确性。它被用来评估二元分类系统,该系统将实例分为 "正面 "或 "负面"。

F分数是结合模型的精度和召回率的一种方式,它被定义为模型的精度和召回率的谐波平均值。

精度:(TP)/(TP+FP)

召回率: TP/(TP+FN)

混淆矩阵及其python函数

一个从混淆矩阵中获取所有可能统计信息的python函数

混淆矩阵:在过去的几周里,我一直致力于建立一个用户级别的倾向性模型,我们可以在谷歌PPC自动竞价过程中使用。我们目前使用Exponea/Bloomreach作为我们的CDXP,然而,该工具的预测分析能力对于我来说太过局限。这个工具的好处(在我看来)是,只要你能把你的数据输入并追踪你网站上的事件,它就能很容易地插入各种广告平台。总之,这篇博客不是关于Exponea或用户层面的建模,而是关于混淆矩阵。

混淆矩阵是了解模型性能的一个好方法。你可以从4个单元格中得出许多诊断性的统计数据。在一个标准的二元分类问题中,你有两个状态--实际和预测,在每个状态中你有真或假。

我一直在使用Exponea来建立一个用户级别的转换模型。然而,我用来判断模型性能的统计资料在那里是不可用的。因此,我决定写一个Python函数,只要我把混淆矩阵输入其中,就能从混淆矩阵中计算出我需要的所有可能的统计信息。我本可以使用sklearn,但是我需要导入度量,然后为每个统计数字引用一个函数,说实话,为什么没有一个函数,只要你输入y和y_pred或混淆矩阵,就能吐出所有统计数字呢?

所以,只要你有一个数组形式的混淆矩阵,并且看起来像下面这样(我使用的是stats models pred_table),我的代码就能正常工作,并返回一个包含混淆矩阵中统计信息的字典。

A python function to get all the possible stats from a confusion matrix.jpg

使用statsmodels pred_table的混淆矩阵

def model_diagnostic_stats(confusion_matrix):
    tp = confusion_matrix[1,1]
    tn = confusion_matrix[0,0]
    fp = confusion_matrix[0,1]
    fn = confusion_matrix[1,0]
    
    p = tp + fn
    n = fp + tn
    pp = tp + fp
    pn = fn + tn
    
    diagnostic_dict = {   
    'recall' : tp/p,
    'false_neg_rate' : fn/p,
    'false_pos_rate' : fp/n,
    'true_neg_rate' : tn/n,
    'positive_liklihood_ratio' : (tp/p)/(fp/n),
    'neg_liklihood_rate' : (fn/p)/(tn/n),
    'precision' : tp/pp,
    'false_omission_rate' : fn/pn,
    'false_discovery_rate' : fp/pp,
    'neg_pred_value' : tn/pn,
    'markedness' : (tp/pp)+(tn/pn)-1,
    'diagnostic_odds_ration' : ((tp/p)/(fp/n))/( (fn/p)/(tn/n)),
    'informedness' : (tp/p)+(tn/n)-1,
    'prevalence_threshold' : (sqrt((tp/p)*(fp/n))-(fp/n))/((tp/p)-(fp/n)),
    'prevalence' : p/(p+n),
    'accuracy' : (tp+tn)/(p+n),
    'balanced_accuracy' : ((tp/p)+(tn/n))/2,
    'F1_score' : 2*tp/(2*tp+fp+fn),
    'fowlkes_mallows_index' : sqrt((tp/pp)*(tp/p)),
    'jaccard_index' : tp/(tp+fn+fp),
    }
    
    return diagnostic_dict
Confusion Matrix using statsmodels pred_table.png
诊断数据 = {   
'recall' : tp/p,
'false_neg_rate' : fn/p,
'false_pos_rate' : fp/n,
'true_neg_rate' : tn/n,
'positive_liklihood_ratio' : (tp/p)/(fp/n),
'neg_liklihood_rate' : (fn/p)/(tn/n)。
'精度' : tp/pp,
'false_omission_rate' : fn/pn,
'错误发现率' : fp/pp,
'neg_pred_value' : tn/pn,
'markedness' : (tp/pp)+(tn/pn)-1,
'diagnostic_odds_ration' : ((tp/p)/(fp/n))/( (fn/p)/(tn/n) )。
'知情度' : (tp/p)+(tn/n)-1,
'prevalence_threshold' : (sqrt((tp/p)*(fp/n))-(fp/n))/( (tp/p)-(fp/n)) 。
'流行率' : p/(p+n),
'准确性' : (tp+tn)/(p+n)。
'balanced_accuracy' : ((tp/p)+(tn/n))/2。
'F1_score' : 2*tp/(2*tp+fp+fn)。
'fowlkes_mallows_index' : sqrt((tp/pp)*(tp/p))。
'jaccard_index' : tp/(tp+fn+fp),
}

返回 diagnostic_dict

现在我有了模型的诊断统计,我可以判断我的模型与我在Exponea中建立的模型相比,好坏程度如何。

相关文章

网友评论

      本文标题:Python中的决策树模型--构建、可视化、评估

      本文链接:https://www.haomeiwen.com/subject/jvqxvrtx.html