第四章节内容点理解有困难,就不堆文字来,拆成3个小篇章,本文主要讲解决策树变量分箱。
决策树变量分箱
提取重要性变量
删除共性变量+样本均衡
本章节是建模前的重要处理部分,前面我们已经对数据进行清洗、转换,我们的样本数据目前已经基本全部数值化,并完成填充转换和延伸处理。由于建模的核心是对数值进行处理。第三章节处理后的数据,并不能马上应用于建模处理。建模对数据的分布和上下限等特征是敏感的。本章节中按照连续变量分箱、重要性排序、共性变量需要删除(与业务指标关联波动一样对建模冗余,需要删除)顺序、样本平衡进行处理,目的上降低建模干扰,提升建模效率和准确度。如下:
1、连续变量分箱:通过决策树找到分类节点,然后分箱。
2、随机森林筛选重要变量:计算IV,对于IV=inf无穷节点进行合并重算,删除IV<=0.003的列
3、共性变量删除:计算corr关联值,对于vif>10,cor>0.7列 按 iv值从大到小删除对列,直到IV无cor>0.7的列组合
4、样本拆分SMOTE`
热独编码oneHotCode:上章节中针对文本等离散分类数据,在处理时,直接赋值编码(类似我们日常的字典数据),由于分类数据存在大小,会造成模型计算时讲数值大小进行判断参数干扰,故使用等距的向量进行分类。这种处理方法会降低分类字典的数值大小影响,但由于向量会增加列的数目,增大建模损耗。
连续列的分箱处理**(无监督学习分类场景)**
这里使用决策树进行自动分箱,自动解析决策树输出pdf分类,采集dot信息,然后(网上大多文章是产生决策树pdf节点图,手工提取节点信息后进行分箱处理) 。这里以int_rate分箱前后的可视化,三张图分别是决策树dot图、分箱前柱状图、分箱后柱状图。可以看到分箱后数据边界清晰、差异明显。以下是重点过程。
1.筛选连续变量:按照指标值分布中类型lisan_cols_point>60归为连续变量。2.检查是否正态分布。3.提取单列升维度:网上有多列数据分类的文章,类似行为分类/客户vip分类等。默认需要2维以上,单列处理需要扩维。4.确认深度和叶子:决策树可以指定树的深度和叶子结点个数。保证分类输出符合最终的业务要求。5.提取节点分箱:输出包含可视化的决策树pdf,自动解析not的dot值,box_col_to_df进行分箱处理。
if 'modelPrepare' in stage:
print("四、建模准备")
start_time = time.time()
df = df_lcs # df_lcs为每阶段覆盖数据 区别于df
lianxu_cols = [i for i in df.columns if len(df[i].value_counts()) >= lisan_cols_point]
lisan_cols = [i for i in df.columns if len(df[i].value_counts()) < lisan_cols_point]
print("lisan_cols {}={}".format(len(lisan_cols), lisan_cols))
print("lianxu_cols {}={}".format(len(lianxu_cols), lianxu_cols))
# print(getrow(df, 4, data_disc)) # 单行
print("1、 连续变量分箱-决策树:分箱方法包括有监督的 卡方分箱 KS分箱和决策树分箱,无监督的 等宽 等频等分箱,"
"此处用决策树分箱open_acc,观察分享结果的覆盖度,可以通过散点图进行观察。")
normal_cols = [i for i in lianxu_col if o_ml.check_normal_distribution(df, i).pvalue > 0.05]
print('Kstest.pvalue>0.05符合正太分布:{}'.format(normal_cols))
cut_dict = {}
for lianxu_col in lianxu_cols: # 连续列-决策树分箱,获取切割点
x_data = df[lianxu_col]
x1_data = x_data[:, np.newaxis] # sklearn要求x,至少是二维数据,所以需要增加一维,np.newaxis 的位置决定了增加维度的位置
model = DecisionTreeClassifier(max_depth=4, min_samples_leaf=21054).fit(x1_data, df["loan_condition_int"])
nodes = model.tree_.threshold # 抽取决策树各个节点的分类值X[0]
nodes = np.sort(nodes[nodes > 0]).round(3)
cut_dict[lianxu_col] = nodes.tolist() # 记录各列的分箱值
dot_data = export_graphviz(model) # 显示图形pdf,需要提前安装graphviz,关于决策树DecisionTreeClassifier需要详细了解下参数、输出及调优
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf(base_dir + ("决策树{}.pdf".format(lianxu_col))) # 采集分支节点值
print("连续变量分箱--节点如下:")
print(cut_dict) # 打印各列的分箱值,可与"决策树*.pdf"文件X[0]进行核对。
for col, nodes in cut_dict.items():
o_ml.lisan_pivot_table(df, [col], 'loan_condition_int', data_disc, base_dir, '{}分箱前'.format(col)) # 离散-柱状图
o_ml.box_col_to_df(df, col, nodes, base_dir) # 分箱
if str(df[col].dtype) not in 'int32,int64,float64':
df[col] = df[col].astype(float)
o_ml.lisan_pivot_table(df, [col], 'loan_condition_int', data_disc, base_dir, '{}分箱后'.format(col)) # 离散-柱状图