美文网首页收藏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