本文是《智能风控原理、算法及工程》第一章学习笔记。
互联网金融风控体系主要由三大部分构成:
工业界完整的机器学习模型流程如下:
在风控业务中,只有欺诈检测不是二分类任务,因为欺诈手段多变,应该属于多分类任务。欺诈检测可以使用异常检测的方法,如局部异常因子、孤立森林等方法。
Y变量的选取需要根据模型的目的以及具体的业务形态、数据状况来确定。假定将逾期超过15天视为负样本。则一般不会直接将逾期小于15天作为正样本,而是将逾期小于5天和没有逾期作为正样本,将逾期5-15天作为“灰样本”,放入测试集中。这是因为逾期15天和逾期14天本质上很接近,正负样本的区别不是很明显,去掉中间一部分样本可以使样本分布更趋近于二项分布。
评分卡建模通常要求正负样本的数目都不少于1500个,随着样本量的增加模型的效果会显著提升。
数据集在建模前需要划分为3个子集,训练集、测试集、跨时间验证集(OOT)。通常,训练集和测试集的比例为6:4或7:3,跨时间验证集用建模样本中时间切片的最后一段样本。
抽样分为欠采样和过采样。由于负样本通常较少,因此常对正样本进行欠采样。欠采样的方法分为:
采样后需要为正样本添加权重,比如正样本采样为原来的1/4,则采样后的正样本权重为4。因为后续计算模型的检验指标或者预期坏账时,需要将权重带入计算逻辑。
当负样本过少时,需要进行代价敏感加权或者过采样处理。
KS取得最大值的箱越靠前,模型的效果越好。
KS值为累计坏样本占坏样本比率-累计好样本占好样本比率,越靠前说明低分段积累的坏样本数相对越多,即捕获率就越大。所以这里的模型效果越好是指阈值以下的捕获率大(捕获率常用来度量模型抓取负样本的能力)。
这部分问题也是面试过程中被问到较多的。
模型训练效果差
模型训练效果差最直观的表现就是KS值低,出现这种情况的主要问题在于特征,其次就是数据质量差。这个时候应该想办法衍生新的特征,尝试扩充数据集。
训练集效果好,跨时间验证集效果不好
如果测试集和跨时间验证集效果都不好,说明模型存在过拟合。可以尝试减少模型复杂度,比如减少特征数量等。
如果在测试集上表现较好但是在跨时间验证集上效果不好,这种情况为模型的跨时间稳定性较差。通常是因为特征的跨时间稳定性不好造成的,即随着时间的推移单个特征的取值分布有较大波动,需要提出一些稳定性较差的特征。
测试集和跨时间验证集效果都较好,上线之后效果不好
一种可能是过拟合。还有一种可能是线上模型的特征和线下逻辑不一致,需要仔细核对特征逻辑。
上线之后效果好,几周之后分数分布逐步失效
这种情况基本认为是特征的稳定性问题,解决方案在特征的跨时间稳定性。通常需要进行模型重构。
没有明显问题,但模型每个月逐步失效
这是业界普遍存在的问题,解决方法是模型迭代,一直使用较新的样本就可以保证未来几个月的效果。
使用CART树进行规则挖掘的原因,因为在二分类任务下,决策树对叶节点的输出是当前节点标签的均值,这与负样本占比的意义相同。这也是风控场景下的主要优化目标,因此符合业务要求。
import toad
import pandas as pd
import numpy as np
import pydotplus
from IPython.display import Image
from sklearn.externals.six import StringIO
import os
from sklearn import tree
class auto_tree(object):
def __init__(self,datasets,ex_lis,dep='bad_ind',min_samples=0.05,min_samples_leaf=200,min_samples_split=20,max_depth=4,is_bin=True):
'''
datasets:数据集 dataframe格式
ex_lis:不参与建模的特征,如id,时间切片等。list格式
min_samples:分箱时最小箱的样本占总比 numeric格式
max_depth:决策树最大深度 numeric格式
min_samples_leaf:决策树子节点最小样本个数 numeric格式
min_samples_split:决策树划分前,父节点最小样本个数 numeric格式
is_bin:是否进行卡方分箱 bool格式(True/False)
'''
self.datasets = datasets
self.ex_lis = ex_lis
self.dep = dep
self.max_depth = max_depth
self.min_samples = min_samples
self.min_samples_leaf = min_samples_leaf
self.min_samples_split = min_samples_split
self.is_bin = is_bin
self.bins = 0
def fit_plot(self):
os.environ["PATH"] += os.pathsep + 'D:/Program Files/Graphviz2.38/bin'
dtree = tree.DecisionTreeRegressor(max_depth=self.max_depth,
min_samples_leaf=self.min_samples_leaf,
min_samples_split=self.min_samples_split)
x = self.datasets.drop(self.ex_lis,axis=1)
y = self.datasets[dep]
if self.is_bin:
#分箱
combiner = toad.transform.Combiner()
combiner.fit(x,y,method='chi',min_samples = self.min_samples)
x_bin= combiner.transform(x)
self.bins = combiner.export()
else:
x_bin = x.copy()
dtree = dtree.fit(x_bin,y)
df_bin = x_bin.copy()
df_bin[dep] = y
with open(path + "dt.dot", "w") as f:
tree.export_graphviz(dtree, out_file=f)
dot_data = StringIO()
tree.export_graphviz(dtree, out_file=dot_data,
feature_names=x_bin.columns,
class_names=[dep],
filled=True, rounded=True,
special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
return df_bin,self.bins,combiner,graph.create_png()
【作者】:Labryant
【原创公众号】:风控猎人
【简介】:某创业公司策略分析师,积极上进,努力提升。乾坤未定,你我都是黑马。
【转载说明】:转载请说明出处,谢谢合作!~