美文网首页收藏AIData science
【实战篇】集成算法建模(二)

【实战篇】集成算法建模(二)

作者: 山药鱼儿 | 来源:发表于2022-01-30 21:05 被阅读0次

    连载的上一篇文章,小鱼和大家一起学习了 ROC 曲线和 AUC 面积:AUC 被定义为 ROC 曲线下方的面积,AUC 面积的取值为 0.5 ~ 1 之间,越接近于 1 则分类器的分类效果越好。

    此外,我们还对导入的政党捐赠数据集进行了标签处理、度热编码以及数据集的切分。得到的训练集数据和标签如下:

    本节,小鱼将使用决策树和随机森林进行建模,我们来实际感受一下随机森林 Bagging 思想的魅力。

    数据集样本占比情况

    首先,我们来看一下原始数据集中正负样本分布情况:

    y_counts = df.cand_pty_affiliation.value_counts(normalize=True)
    y_counts.plot(kind='bar', title="Share of donations")
    

    value_counts 函数如果想得出计数占比,可以加参数 normalize=True 绘制结果:

    使用过采样方法平衡正负样本:

    from imblearn.over_sampling import SMOTE
    
    smote = SMOTE(random_state=SEED)
    x_over_sample_train, y_over_sample_train = smote.fit_resample(xtrain, ytrain)
    plt.bar(['DEM', 'REP'],y_over_sample_train.value_counts())
    plt.title('over sample train dataset')
    

    SMOTE 过采样结果:

    这样就可以是的模型在训练时学习到的正负样本数量一样多,从而做出更客观的决断。

    树模型的可视化以及 ROC-AUC Score

    下面,我们来定义决策树可视化的函数 print_graph

    环境:需要安装 pydotplus Python 库,并在操作系统安装 graphviz。

    graphviz 的下载地址为:http://download.csdn.net/download/shouwangzhelv/9492517 ,将安装或者解压的 graphviz 下的 bin 目录添加到系统的 path 中,重启 notebook。

    sklearn.tree.export_graphviz 的参数 class_names 可以指定决策树分类标签使用的绘制名称;clf 为训练好的决策树模型。套用小鱼的 print_graph 函数时,只需要修改这两个参数即可。

    import pydotplus
    from IPython.display import Image
    from sklearn.metrics import roc_auc_score
    from sklearn.tree import DecisionTreeClassifier, export_graphviz
    
    def print_graph(clf, feature_names):
        """pringt decision tree"""
        graph = export_graphviz(clf, label="root", proportion=True, impurity=False, out_file=None, 
                                feature_names=feature_names, class_names={0: "D", 1: "R"}, filled=True, rounded=True)
        graph = pydotplus.graph_from_dot_data(graph)
        return Image(graph.create_png())
    

    下面,小鱼就来绘制一个深度为 1 的决策树试试吧~

    t1_o = DecisionTreeClassifier(max_depth=1, random_state=SEED)
    t1_o.fit(x_over_sample_train, y_over_sample_train)
    p_o = t1_o.predict_proba(xtest)[:,1]
    
    print("Decision tree ROC-AUC score: ", roc_auc_score(ytest, p_o))
    print_graph(t1_o, x_over_sample_train.columns)
    

    其中,roc_auc_score 导入自 sklearn.metrics 模块,用于评估模型的分类效果,越接近于 1 ,说明模型越理想。

    Decision tree ROC-AUC score:  0.6243616070247398
    

    决策树根节点中的 transation_tp_15E <=0.5 指出了该节点分类时使用的判断条件,value 表示正负样本的占比。

    叶子节点中,第一行百分比表示有多少样本落在了当前节点:经过根节点的切分,86.6% 的样本落在了左子树,13.4% 的样本落在了右子树。

    第二行,即 value 值,表示正负样本占比情况:左边的叶子节点中,标签 0 占比为 0.425,标签 1 占比为 0.575,因此左边的叶子节点被判定为标签 1 类型,即 R,已经在第三行为我们标识出来了。

    决策树模型

    首先,我们来训练一棵决策树。

    注:为了可视化演示的方便,小鱼这里将决策树的深度限制为 3 。

    t2_o = DecisionTreeClassifier(max_depth=3, random_state=SEED)
    t2_o.fit(x_over_sample_train, y_over_sample_train)
    p_o = t2_o.predict_proba(xtest)[:,1]
    
    print("Decision tree ROC-AUC score: ", roc_auc_score(ytest, p_o))
    print_graph(t2_o, x_over_sample_train.columns)
    

    ROC-AUC Score 为:

    Decision tree ROC-AUC score:  0.7541002451733411
    

    决策树可视化展示:

    上述决策树中,有个叶子节点非常醒目,有 49.8% 的样本都落到了该叶子节点;还有最左侧的叶子节点,23.9% 的样本也落在了该叶子节点上。

    此时的模型过拟合的风险是比较大的,因为它很可能过度地关注某一个特征,而忽视了其它特征。我们希望模型在做决策时,充分考虑所有特征,群策群力,而不是过分依赖某个特征,这样的模型是片面的。

    下面,我们尝试去掉对结果响应最大的特征 transaction_tp_15E 看看:

    drop = ["transaction_tp_15E"]
    
    xtrain_slim_o = x_over_sample_train.drop(drop, axis=1)
    xtest_slim = xtest.drop(drop, axis=1)
    
    t3_o = DecisionTreeClassifier(max_depth=3, random_state=SEED)
    t3_o.fit(xtrain_slim_o, y_over_sample_train)
    p = t3_o.predict_proba(xtest_slim)[:, 1]
    
    print("Decision tree ROC-AUC score: %.3f" % roc_auc_score(ytest, p))
    print_graph(t3_o, xtrain_slim.columns)
    

    去掉 transaction_tp_15E 后的决策树 ROC-AUC Score 为:

    Decision tree ROC-AUC score: 0.765
    

    可视化展示:

    两棵树的 ROC-AUC Score 值基本一致,评估结果差不多;但决策树的内部构造确是完全不同的,可以说它们各自有各自的错误,也各自有各自的优点,那我们何不综合这两棵树来得出最终的预测呢?

    p1_o = t2_o.predict_proba(xtest)[:, 1]
    p2_o = t3_o.predict_proba(xtest_slim)[:, 1]
    p = np.mean([p1_o, p2_o], axis=0)
    
    print("Average of decision tree ROC-AUC score: %.3f" % roc_auc_score(ytest, p))
    

    综合两棵树得出的 ROC-AUC Score 值:

    Average of decision tree ROC-AUC score: 0.773
    

    一平均 ROC-AUC 的值还真的提高了!可见,选择不同的特征会产生不同的结果,然后用不同的结果进行组合得到了一个升华!那让我们多选几组不就是随机森林了吗?

    随机森林

    from sklearn.ensemble import RandomForestClassifier
    
    rf = RandomForestClassifier(n_estimators=100, max_features=3, random_state=SEED)
    rf.fit(x_over_sample_train, y_over_sample_train)
    p_o = rf.predict_proba(xtest)[:, 1]
    
    print("Average of decision tree ROC-AUC score: %.3f" % roc_auc_score(ytest, p_o))
    

    使用随机森林构造 100 棵不同的决策树,评估结果:

    Average of decision tree ROC-AUC score: 0.869
    

    使用随机森林建模的 ROC-AUC Score 值又有了显著的提升!这就是 Bagging 集成思想的魅力~

    补充

    除了使用 Graphviz 插件绘制决策树之外,还可以使用 sklearn 自带的 plot_tree 函数来绘制:

    from sklearn import tree
    import matplotlib.pyplot as plt
    
    fig, axe = plt.subplots(figsize=(12,6), dpi=150)
    # 使用sklearn自带的工具绘制决策树, impurity为True则显示gini系数
    tree.plot_tree(t2_o, filled=True, ax=axe, proportion=True, rounded=True, impurity=False, label='root', 
                  feature_names=xtrain.columns, fontsize=10, class_names={0:'D', 1:'R'})
    

    绘图结果:

    相关文章

      网友评论

        本文标题:【实战篇】集成算法建模(二)

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