大数跨境
0
0

风控策略的自动化生成-利用决策树分分钟生成上千条策略

风控策略的自动化生成-利用决策树分分钟生成上千条策略 CDA数据分析师
2024-02-02
0
导读:本文重点:风控策略挖掘、策略推荐,策略发现,风控策略自动化,决策树大家好,我是小伍哥,决策做策略挖掘,读的人

本文重点:风控策略挖掘、策略推荐,策略发现,风控策略自动化,决策树
大家好,我是小伍哥,决策做策略挖掘,读的人非常多,不过已经两年了,有些包变了,当时也留下一些小尾巴,没写完。今天重新整理下,大家参考新的这个就行了。
风控策略同学在挖掘有效的风控规则的时候,时时需要基于业务经营思考将那几个特征进行组合,会导致在特征组合的时候浪费大量的时间,我们有没有什么方法,替代人工的分析,直接得出策略组合呢,决策树就是其中的一个选择,可以实现自动化的挖掘大批量的策略组合。
在众多的算法中,决策树整体分类准确率不高,但是部分叶子节点的准确率却可以很高,因此我们可以提取决策树的叶子规则,并筛选准确率比较高的叶子节点,作为风控策略挖掘手段,并进行策略推荐,替代人工或者辅助人工,大大提高策略发现的效率于效果。
本文介绍了如何在风控策略中使用决策树算法来挖掘有效的规则,并会分享自己编写的提取函数,此套代码会在极短的时间挖掘上千条规则,快速且有效,目标就是:风控策略自动化,然后干掉自己。【文末有获取代码和数据的方法】
策略节选

一、数据说明及读取

1、数据集信息

数据从真实场景和实际应用出发,利用个人的基本身份信息、个人的住房公积金缴存和贷款等数据信息,来建立准确的风险控制模型,来预测用户是否会逾期还款。一共提供了40000带标签训练集样本,数据仅有一张表,一共有19个基本特征,且均不包含任何缺失值。

2、数据属性信息

标签:label是否逾期(是 = 1,否 = 0)。
特征:包含以下19个变量,名称和含义如下。
序号
字段名
类型
说明
1
id
String
主键
2
XINGBIE
int
性别
3
CSNY
int
出生年月
4
HYZK
int
婚姻状况
5
ZHIYE
int
职业
6
ZHICHEN
int
职称
7
ZHIWU
int
职务
8
XUELI
int
学历
9
DWJJLX
int
单位经济类型
10
DWSSHY
int
单位所属行业
11
GRJCJS
float
个人缴存基数
12
GRZHZT
int
个人账户状态
13
GRZHYE
float
个人账户余额
14
GRZHSNJZYE
float
个人账户上年结转余额
15
GRZHDNGJYE
float
个人账户当年归集余额
16
GRYICE
float
个人月缴存额
17
DWYICE
float
单位月缴存额
18
DKFFE
int
贷款发放额
19
DKYE
float
贷款余额
20
DKLL
float
贷款利率
21
label
int
是否逾期 (0代表没逾期1代表逾期)

3、读取数据

  
#数据读取import pandas as pdimport numpy as nppd.set_option('display.max_columns', None)#显示所有的列path = '/Users/wuzhengxiang/Documents/DataSets/RizhaoGongJiJin/train.csv'train = pd.read_csv(path).fillna(-1)train.columnsIndex(['id', 'XINGBIE', 'CSNY', 'HYZK', 'ZHIYE', 'ZHICHEN', 'ZHIWU', 'XUELI','DWJJLX', 'DWSSHY', 'GRJCJS', 'GRZHZT', 'GRZHYE', 'GRZHSNJZYE','GRZHDNGJYE', 'GRYJCE', 'DWYJCE', 'DKFFE', 'DKYE', 'DKLL', 'label'], dtype='object')
train.head()#查看前面的数据 id XINGBIE CSNY HYZK ZHIYE ZHICHEN ZHIWU XUELI DWJJLX \0 train_0 1 1038672000 90 90 999 0 99 1501 train_1 2 504892800 90 90 999 0 99 1102 train_2 1 736185600 90 90 999 0 99 1503 train_3 1 428515200 90 90 999 0 99 1504 train_4 2 544204800 90 90 999 0 99 900
DWSSHY GRJCJS GRZHZT GRZHYE GRZHSNJZYE GRZHDNGJYE GRYJCE \0 12 1737.0 1 3223.515 801.310 837.000 312.001 0 4894.0 1 18055.195 53213.220 1065.200 795.842 9 10297.0 1 27426.600 13963.140 7230.020 1444.203 7 10071.5 1 111871.130 99701.265 2271.295 1417.144 14 2007.0 1 237.000 11028.875 35.780 325.50
DWYJCE DKFFE DKYE DKLL label 0 312.00 175237 154112.935 2.708 01 795.84 300237 298252.945 2.979 02 1444.20 150237 147339.130 2.708 03 1417.14 350237 300653.780 2.708 04 325.50 150237 145185.010 2.708 0
#构建训练集X = train.loc[:,'XINGBIE':'DKLL']Y = train['label']


二、两种决策树的构建

决策树是常用的机器学习算法之一,决策树模型的决策过程非常类似人类做判断的过程,比较好理解。scikit-learn 是基于Python 的一个机器学习库,简称为sklearn,其中实现了很多机器学习算法。我们可以通过sklearn 官方手册 来学习如何使用它。
sklearn 库的tree模块实现了两种决策树:
  • sklearn.tree.DecisionTreeClassifier 类:分类树的实现。
  • sklearn.tree.DecisionTreeRegressor 类:回归树的实现。
分类树用于预测离散型数值,回归树用于预测连续性数值。
sklearn 只实现了预剪枝,没有实现后剪枝。

1、分类树构建

  
## 训练一个决策树,这里限制了最大深度和最小样本树from sklearn import treeclf = tree.DecisionTreeClassifier(max_depth=3,min_samples_leaf=50)clf = clf.fit(X, Y)


2、回归树构建

  
## 训练一个决策树,这里限制了最大深度和最小样本树from sklearn import treeclf = tree.DecisionTreeClassifier(max_depth=3,min_samples_leaf=50)clf = clf.fit(X, Y)


三、决策树的可视化

决策树可视化的方案比较多,都写出来给对比看看,推荐第二种和第三种。对决策树进行可视化,是非常有必要的,能够帮助我们自己充分理解决策树的生成过程,如果是风控,也有利于咱们给业务部门解释数据和结果。

1、plot_tree可视化

  
#包里自带的,有点丑,但是还行,清晰度设置高点,就还可以了import matplotlib.pyplot as plttree.plot_tree(clf)plt.show()

#设置图片的大小,想要清晰的可以设置的大点plt.figure(figsize=(8,8),dpi=1000)
tree.plot_tree(clf)plt.show()


2、graphviz可视化

如果搜索“可视化决策树”,很快便能找到由scikit提供的基于Python语言的解决方案:sklearn.tree.export_graphviz,这个也是最常用的解决方案
  
import graphviz dot_data = tree.export_graphviz(clf, out_file=None, feature_names=X.columns, class_names=['good','bad'], filled=True, rounded=True, special_characters=True) graph = graphviz.Source(dot_data) graph

弄个更深的树
  

#构建训练集X = train.loc[:,'XINGBIE':'DKLL']Y = train['label']
# 训练一个模型from sklearn import treeclf = tree.DecisionTreeClassifier(max_depth=9,min_samples_leaf=1800)clf = clf.fit(X, Y)
import graphviz dot_data = tree.export_graphviz(clf, out_file=None, feature_names=X.columns, class_names=['good','bad'], filled=True, rounded=True, special_characters=True) graph = graphviz.Source(dot_data) graph
#graph.save('prueba2.png')

生成的决策树解释
1)samples:节点中观察的数量,比如根节点40000,表示数据集总共有4万个样本
2)有多少种类别,整棵树的叶子就有多少种颜色,比如我们这里有2个类别,颜色对应是黄、绿、Gini指数越小,该节点颜色越深,也就是纯度越高。
3)value表示当前节点2种类别的样本有多少,比如下面第一棵树的根节点,value = [37243,2757],表示有37243个好样本,2757坏样本
4)class表示当前那个类别的样本最多,比如下面最右边的一棵树的根节点,class = bad,可以看到当前节点它的坏样本数是最多的。
5)gini:节点的基尼不纯度。当沿着树向下移动时,平均加权的基尼不纯度必须降低。

3、dtreeviz可视化

dtreeviz是我认为非常完美的决策树可视化的包,非常好理解,也非常美观。下面我们看看这个包可视化的结果。
 算法的基本参数
  
dtreeviz.model(model, X_train, y_train, tree_index: int=None, feature_names: List[str]=None, target_name: str=None, class_names: (List[str], Mapping[int, str])=None) -> DTreeVizAPI

起码开始做可视化。
 
# 训练一个模型
from sklearn import tree
clf = tree.DecisionTreeClassifier(
max_depth=6,
min_samples_leaf=20
)
clf = clf.fit(X, Y)


# 开始可视化
import dtreeviz
import warnings
warnings.filterwarnings("ignore")

viz_model = dtreeviz.model(clf,
X_train=X,
y_train=Y,
target_name='label',
feature_names=X.columns,
class_names={0:'good',1:'bad'},
)

v = viz_model.view() # render as SVG into internal object
v.show() # pop up window
v.save("/tmp/gonjijin.svg") # optionally save as svg
预测某个样本在树上的路径
  
testX = X.iloc[77,:]v = viz_model.view(x=testX)v.show()


只看预测的路径。
  
v = viz_model.view(x=testX,show_just_path=True)v.show() v.save("gonjijin.svg") # optionally save as svg





我们把深度加深点,max_depth=7,可以看到生成的树更复杂了。
  
#数据读取import pandas as pdimport numpy as nppd.set_option('display.max_columns', None)#显示所有的列path = 'train.csv'train = pd.read_csv(path).fillna(-1)
#构建训练集X = train.loc[:,'XINGBIE':'DKLL']Y = train['label']
# 训练一个模型from sklearn import treeclf = tree.DecisionTreeClassifier( max_depth=7, min_samples_leaf=20 )clf = clf.fit(X, Y)
# 开始可视化import dtreevizimport warningswarnings.filterwarnings("ignore")
viz_model = dtreeviz.model(clf, X_train=X, y_train=Y, target_name='label', feature_names=X.columns, class_names={0:'good',1:'bad'}, )
v = viz_model.view() # render as SVG into internal object v.show() # pop up windowv.save("gonjijin.svg") # optionally save as svg


也可以横向展示
  
#数据读取import pandas as pdimport numpy as nppd.set_option('display.max_columns', None)#显示所有的列path = 'train.csv'train = pd.read_csv(path).fillna(-1)
#构建训练集X = train.loc[:,'XINGBIE':'DKLL']Y = train['label']
# 训练一个模型from sklearn import treeclf = tree.DecisionTreeClassifier( max_depth=5, min_samples_leaf=20 )clf = clf.fit(X, Y)
testX = X.iloc[77,:]
# 开始可视化import dtreevizimport warningswarnings.filterwarnings("ignore")
viz_model = dtreeviz.model(clf, X_train=X, y_train=Y,
target_name='label', feature_names=X.columns, class_names={0:'good',1:'bad'}, )
v = viz_model.view(orientation="LR") v.show() v.save("gonjijin.svg")  


设置更简洁的模式
  
#数据读取import pandas as pdimport numpy as nppd.set_option('display.max_columns', None)#显示所有的列path = 'train.csv'train = pd.read_csv(path).fillna(-1)
#构建训练集X = train.loc[:,'XINGBIE':'DKLL']Y = train['label']
# 训练一个模型from sklearn import treeclf = tree.DecisionTreeClassifier( max_depth=4, min_samples_leaf=50 )clf = clf.fit(X, Y)
testX = X.iloc[77,:]
# 开始可视化import dtreevizimport warningswarnings.filterwarnings("ignore")
viz_model = dtreeviz.model(clf, X_train=X, y_train=Y,
target_name='label', feature_names=X.columns, class_names={0:'good',1:'bad'}, )
v = viz_model.view(fancy=False) v.show() v.save("gonjijin.svg")


有了决策树的可视化,我们就能直接得到每条策略了,当时人为的看,效率还是比较低,我们需要更高效的方式,对数据决策树上的信息进行提取,直接得到规则。

4、回归树可视化

  
# 回归树可视化from sklearn.datasets import fetch_california_housingfrom sklearn.tree import DecisionTreeClassifier,DecisionTreeRegressorimport dtreeviz
clf = DecisionTreeRegressor(max_depth=5)data = fetch_california_housing()
X = data.dataY = data.targetclf.fit(X, Y)

viz_model = dtreeviz.model(clf, X_train=X, y_train=Y, target_name=data.target_names, feature_names=data.feature_names )
v = viz_model.view() # render as SVG into internal object viz_model.view()v.show() # pop up windowv.save("/tmp/iris.svg") # optionally save as svg


  
# 回归树可视化from sklearn.datasets import fetch_california_housingfrom sklearn.tree import DecisionTreeClassifier,DecisionTreeRegressorimport dtreeviz
clf = DecisionTreeRegressor(max_depth=4)data = fetch_california_housing()
X = data.dataY = data.targetclf.fit(X, Y)

viz_model = dtreeviz.model(clf, X_train=X, y_train=Y, target_name=data.target_names, feature_names=data.feature_names )
v = viz_model.view(orientation="LR") # render as SVG into internal object viz_model.view()v.show() # pop up windowv.save("gonjijin.svg")

四、理解决策树的底层设计

要提取出来其中的规则,我们需要探索决策树的存储结构,为了探究sklearn中决策树是如何设计和实现的,以分类决策树为例,首先看下决策树都内置了哪些属性和接口:通过dir属性查看一颗初始的决策树都包含了哪些属性(这里过滤掉了以"_"开头的属性,因为一般是内置私有属性),得到结果如下:
  
from sklearn.datasets import load_irisfrom sklearn import treeiris = load_iris()clf = tree.DecisionTreeClassifier()clf = clf.fit(iris.data, iris.target)clf.classes_[x for x in dir(clf) if not x.startswith('_')]

大致浏览上述结果,属性主要是决策树初始化时的参数,例如ccp_alpha:剪枝系数,class_weight:类的权重,criterion:分裂准则等;还有就是决策树实现的主要函数,例如fit:模型训练,predict:模型预测等等。
本文的重点是探究决策树中是如何保存训练后的"那颗树",所以我们进一步用鸢尾花数据集对决策树进行训练一下,而后再次调用dir函数,看看增加了哪些属性和接口:

通过集合的差集,很明显看出训练前后的决策树主要是增加了6个属性(都是属性,而非函数功能),其中通过属性名字也很容易推断其含义:
classes_:分类标签的取值,即y的唯一值集合
max_features_:最大特征数
n_classes_:类别数,如2分类或多分类等,即classes_属性中的长度
n_features_in_:输入特征数量,等价于老版sklearn中的n_features_,现已弃用,并推荐n_features_in_
n_outputs:多输出的个数,即决策树不仅可以用于实现单一的分类问题,还可同时实现多个分类问题,例如给定一组人物特征,用于同时判断其是男/女、胖/瘦和高矮,这是3个分类问题,即3输出(需要区别理解多分类和多输出任务)
tree_:毫无疑问,这个tree_就是今天本文的重点,是在决策树训练之后新增的属性集,其中存储了决策树是如何存储的。

那我们对这个tree_属性做进一步探究,首先打印该tree_属性发现,这是一个Tree对象,并给出了在sklearn中的文件路径:
我们可以通过help方法查看Tree类的介绍:
通过上述doc文档,其中第一句就很明确的对决策树做了如下描述:
Array-based representation of a binary decision tree.
即:基于数组表示的二分类决策树,也就是二叉树!进一步地,在这个二叉树中,数组的第i个元素代表了决策树的第i个节点的信息,节点0表示决策树的根节点。那么每个节点又都蕴含了什么信息呢?我们注意到上述文档中列出了节点的文件名:_tree.pxd,查看其中,很容易发现节点的定义如下:
虽然是cython的定义语法,但也不难推断其各属性字段的类型和含义,例如:
left_child:size类型(无符号整型),代表了当前节点的左子节点的索引
right_child:类似于left_child
feature:size类型,代表了当前节点用于分裂的特征索引,即在训练集中用第几列特征进行分裂
threshold:double类型,代表了当前节点选用相应特征时的分裂阈值,一般是≤该阈值时进入左子节点,否则进入右子节点
n_node_samples:size类型,代表了训练时落入到该节点的样本总数。显然,父节点的n_node_samples将等于其左右子节点的n_node_samples之和。

至此,决策树中单个节点的属性定义和实现基本推断完毕,那么整个决策树又是如何将所有节点串起来的呢?我们再次诉诸于训练后决策树的tree_属性,看看它都哪些接口,仍然过滤掉内置私有属性,得到如下结果:
  
# 决策树结构探索dir(clf.tree_)['apply','capacity','children_left','children_right','compute_feature_importances','compute_partial_dependence','decision_path','feature','impurity','max_depth','max_n_classes','n_classes','n_features','n_leaves','n_node_samples','n_outputs','node_count','predict','threshold','value','weighted_n_node_samples']

大概比较重要的就是这些了!为了进一步理解各属性中的数据是如何存储的,我们仍以鸢尾花数据集为例,训练一个max_depth=2的决策树(根节点对应depth=0),并查看如下取值:
  
clf.tree_.children_leftclf.tree_.children_rightclf.tree_.featureclf.tree_.capacityclf.tree_.thresholdclf.tree_.valueclf.tree_.impurityclf.tree_.decision_path

可知:
  • 训练后的决策树共包含5个节点,其中3个叶子节点
  • 通过children_left和children_right两个属性,可以知道第0个节点(也就是根节点)的左子节点索引为1,右子节点索引为2,;第1个节点的左右子节点均为-1,意味着该节点即为叶子节点;第2个节点的左右子节点分别为3和4,说明它是一个内部节点,并做了进一步分裂
  • 通过feature和threshold两个属性,可以知道第0个节点(根节点)使用索引为3的特征(对应第4列特征)进行分裂,且其最优分割阈值为0.8;第1个节点因为是叶子节点,所以不再分裂,其对应feature和threshold字段均为-2
  • 通过value属性,可以查看落入每个节点的各类样本数量,由于鸢尾花数据集是一个三分类问题,且该决策树共有5个节点,所以value的取值为一个5×3的二维数组,例如第一行代表落入根节点的样本计数为[50, 50, 50],第二行代表落入左子节点的样本计数为[50, 0, 0],由于已经是纯的了,所以不再继续分裂。
  • 另外,tree中实际上并未直接标出各叶节点所对应的标签值,但完全可通过value属性来得到,即各叶子节点中落入样本最多的类别即为相应标签。甚至说,不仅可知道对应标签,还可通过计算数量之比得到相应的概率!
拿鸢尾花数据集手动验证一下上述猜想,以根节点的分裂特征3和阈值0.8进行分裂,得到落入左子节点的样本计数结果如下,发现确实是分裂后只剩下50个第一类样本,也即样本计数为[50, 0, 0],完全一致。
另外,通过children_left和children_right两个属性的子节点对应关系,其实我们还可以推断出该二叉树的遍历方式为前序遍历,即按照根-左-右的顺序,对于上述决策树其分裂后对应二叉树示意图如下:
知道了具体的存储结构,我们下面就要设计算法,把二叉树提取出我们方便使用的规则了。

五、决策规则提取

1、老方法提取策略

通过上面的分析,我们知道了决策树的存储方式,下面就开始规则提取,在网上搜索,基本上只能收到下面的方法:
  
#数据读取import pandas as pdimport numpy as np
pd.set_option('display.max_columns', None)#显示所有的列path = '/Users/wuzhengxiang/Documents/DataSets/RizhaoGongJiJin/train.csv'train = pd.read_csv(path).fillna(-1)train.columns
#构建训练集X = train.loc[:,'XINGBIE':'DKLL']Y = train['label']
## 训练一个决策树,这里限制了最大深度和最小样本树from sklearn import treeclf = tree.DecisionTreeClassifier( max_depth=3, min_samples_leaf=50 )clf = clf.fit(X, Y)

# 决策树规则提取-老方法from sklearn.tree import _treedef tree_to_code(tree, feature_names): tree_ = tree.tree_ feature_name = [ feature_names[i] if i != _tree.TREE_UNDEFINED else "undefined!"for i in tree_.feature ]print ("def tree({}):".format(", ".join(feature_names)))
def recurse(node, depth): indent = " " * depthif tree_.feature[node] != _tree.TREE_UNDEFINED: name = feature_name[node] threshold = tree_.threshold[node] print("{}if {} <= {}:".format(indent, name, threshold)) recurse(tree_.children_left[node], depth + 1) print("{}else: # if {} > {}".format(indent, name, threshold)) recurse(tree_.children_right[node], depth + 1)else: print("{}return {}".format(indent, tree_.value[node]))
recurse(0, 1)tree_to_code(clf,X.columns)return [[161. 0.]]

’可以看得出来,虽然提取出来了策略,但是并不是很完美,还是需要人为拆解策略,于是我继续研究。

2、新方法提取策略

不仅仅对对二叉树的所有路径进行遍历,还需要进行回溯并组合成变量,根据决策树的输出,构建规则提取函数,需要用到二叉树遍历和回溯算法,本人数据结构不是很好,干了两个晚上,真是编程偷不了懒,出来混迟早要还的。代码比较混乱,大家将就看,还好这个部分对效率没啥要求。如果有更好的代码,不吝赐教。
  
from sklearn.tree import _treedef XiaoWuGe_Get_Rules(clf,X): n_nodes = clf.tree_.node_count children_left = clf.tree_.children_left children_right = clf.tree_.children_right feature = clf.tree_.feature threshold = clf.tree_.thresholdvalue = clf.tree_.value
node_depth = np.zeros(shape=n_nodes, dtype=np.int64) is_leaves = np.zeros(shape=n_nodes, dtype=bool) stack = [(0, 0)]
while len(stack) > 0:
node_id, depth = stack.pop() node_depth[node_id] = depth
is_split_node = children_left[node_id] != children_right[node_id]
if is_split_node: stack.append((children_left[node_id], depth+1)) stack.append((children_right[node_id], depth+1))else: is_leaves[node_id] = True feature_name = [ X.columns[i] if i != _tree.TREE_UNDEFINED else "undefined!"for i in clf.tree_.feature]
ways = [] depth = [] feat = [] nodes = [] rules = []for i in range(n_nodes): if is_leaves[i]: while depth[-1] >= node_depth[i]: depth.pop() ways.pop() feat.pop() nodes.pop()if children_left[i-1]==i:#当前节点是上一个节点的左节点,则是小于 a='{f}<={th}'.format(f=feat[-1],th=round(threshold[nodes[-1]],4)) ways[-1]=a last =' & '.join(ways)+':'+str(value[i][0][0])+':'+str(value[i][0][1]) rules.append(last)else: a='{f}>{th}'.format(f=feat[-1],th=round(threshold[nodes[-1]],4)) ways[-1]=a last = ' & '.join(ways)+':'+str(value[i][0][0])+':'+str(value[i][0][1]) rules.append(last)
else: #不是叶子节点 入栈if i==0: ways.append(round(threshold[i],4)) depth.append(node_depth[i]) feat.append(feature_name[i]) nodes.append(i) else: while depth[-1] >= node_depth[i]: depth.pop() ways.pop() feat.pop() nodes.pop()if i==children_left[nodes[-1]]: w='{f}<={th}'.format(f=feat[-1],th=round(threshold[nodes[-1]],4))else: w='{f}>{th}'.format(f=feat[-1],th=round(threshold[nodes[-1]],4)) ways[-1] = w ways.append(round(threshold[i],4)) depth.append(node_depth[i]) feat.append(feature_name[i]) nodes.append(i)return rules

函数构建好了,我就开始策略的提前
  
#训练一个决策树,对规则进行提取clf = tree.DecisionTreeClassifier(max_depth=10,min_samples_leaf=50)clf = clf.fit(X, Y)Rules = XiaoWuGe_Get_Rules(clf,X)
Rules[0:5] # 查看前5条规则['GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE<=663.54 & DKYE<=67419.1094:45.0:8.0', 'GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE<=663.54 & DKYE >67419.1094:61.0:3.0', 'GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE >663.54 & GRZHYE<=45622.4883 & DKYE<=1825.5625:63.0:2.0', 'GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE >663.54 & GRZHYE<=45622.4883 & DKYE >1825.5625:188.0:0.0', 'GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE >663.54 & GRZHYE >45622.4883:46.0:4.0']len(Rules) # 查看规则总数182

我们可以导出成表格的形式,更加清晰

提高树的深度再看看,max_depth=15,可以看到规则数从182变成了521条,规模更大
  
clf = tree.DecisionTreeClassifier(max_depth=15,min_samples_leaf=20)clf = clf.fit(X, Y)Rules = Get_Rules(clf,X)Rules[0:5]['GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE<=663.54 & GRZHSNJZYE<=19428.9082 & DKFFE<=142737.0 & CSNY<=600926400.0:54.0:0.0','GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE<=663.54 & GRZHSNJZYE<=19428.9082 & DKFFE<=142737.0 & CSNY >600926400.0:18.0:2.0','GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE<=663.54 & GRZHSNJZYE<=19428.9082 & DKFFE >142737.0:19.0:4.0','GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE<=663.54 & GRZHSNJZYE >19428.9082:15.0:5.0','GRZHZT<=1.5 & DWSSHY<=14.5 & DWJJLX<=177.0 & DWJJLX<=115.0 & DKYE<=111236.2852 & DWSSHY<=4.5 & DWYJCE >663.54 & GRZHYE<=73608.0156 & DKYE<=1825.5625 & GRZHSNJZYE<=9524.7949:21.0:2.0']len(Rules)521
#可以遍历所有的规则for i in Rules:print(i)
到此为止,我们完成了基础规则的挖掘,面对实际业务,我们还需要更丰富,更灵活的挖掘方式。

六、策略结果整理保存

刚刚的结果,都是打印出来的,是一个列表形式的,不方便我们看看,一般我们都会导出来,可以按下面的代码进行进行整理,得到标准的表格格式。
  
# 结果格式整理df = pd.DataFrame(Rules)df.columns = ['allrules']df['Rules'] = df['allrules'].str.split(':').str.get(0)df['good'] = df['allrules'].str.split(':').str.get(1).astype(float)df['bad'] = df['allrules'].str.split(':').str.get(2).astype(float)df['all'] = df['bad']+df['good']df['bad_rate'] = df['bad']/df['all']
df = df.sort_values(by='bad_rate',ascending=False)del df['allrules']



七、特征采样

有些场景,特征特别多,直接去挖掘,出来的也不够丰富。所以要涉及到一些采样的思路,这里提供两种。也可以根据业务判断,对某类特征单独进行挖掘。
1、随机采样特征
上面仅仅进行了初步的挖掘,我们还可以对特征进行抽样,然后进行更大规模的抽样,最后从决策树变成了决策森林,感觉有种随机深林的感觉,大家可以试试。如果还有不懂得,可以咨询我。

2、根据重要性采样

根据树模型的特征重要性排序,去重要性高的特征进行学习策略,可能出来的效果更好。

八、软件安装及

可视化前,需要安装graphviz,相对比较麻烦。最好按下面的方法安装,我之前就各种方法都不成功,就下面这个很顺利就成功了
  
pip install dtreevizconda install python-graphviz


了解更多数据分析知识、与更多优秀的人一起进群交流请扫码


群码过期或者群满请添加客服微信 CDAshujufenxi 后拉您进群

【声明】内容源于网络
0
0
CDA数据分析师
🌸全国30万数据分析从业人员,有10万在CDA数据分析师 🌺CDA会员俱乐部有1000个数据库,成为持证人即可获得相关数据信息 🌹未来两样东西最有价值:一个是数据,一个是GPU
内容 9451
粉丝 0
CDA数据分析师 🌸全国30万数据分析从业人员,有10万在CDA数据分析师 🌺CDA会员俱乐部有1000个数据库,成为持证人即可获得相关数据信息 🌹未来两样东西最有价值:一个是数据,一个是GPU
总阅读1.4k
粉丝0
内容9.5k