风控模型常用的算法总结
一、常用算法
- 监督算法
模型名称 | 英文名 | 简称 |
---|---|---|
线性回归模型 | LinearRegression | SKLOGIT |
决策树回归模型 | DecisionTreeRegressor | DT |
多层感知器回归模型 | MLPRegressor | |
打包回归模型 | BaggingRegressor | |
额外树回归模型 | ExtraTreesRegressor | |
广义线性回归 | GLMNET | |
MARS | ||
样条回归 | Spline regression | |
线性支持向量机回归模型 | LinearSVR | |
随机森林回归模型 | RandomForestRegressor | RF |
nu支持向量机回归模型 | NuSVR | |
支持向量机回归模型 | SVR | |
自适应提升回归模型 | AdaBoostRegressor | |
梯度提升回归模型 | GradientBoostingRegressor | GBM |
梯度提升分类模型 | GradientBoostingClassifier | GBM |
随机森林分类模型 | RandomForestClassifier | |
极致梯度提升回归模型(非sklearn) | Extreme GradientBoosting | XGBoost |
轻梯度提升机(非sklearn) | Light Gradient Boosting Machine | lightGBM |
逻辑回归(非sklearn,无L1/L2) | statsmodels.api.sm.Logit | SMLOGIT |
朴素贝叶斯 | GaussianNB | NB |
神经网络分类模型 | MLPClassifier | |
支持向量机分类模型 | SVM | |
评分卡模型 | CREDIT CARD | |
自然语言处理 | Natural Language Processing | NLP |
深度学习(适合大量数据) | keras |
随机森林采用投票机制,xgb则是弱学习机的集合。
随机森林关注方差,xgb关注偏差,xgb加入了l1,l2正则项,可以权衡模型复杂度和过拟合问题。
随机森林可以并行,xgb是串行的模型,下一次计算都修正了上一次计算的残差。
随机森林、xgboost/gbdt区别
- 无监督
模型名称 | 英文名 | 简称 |
---|---|---|
K均值 | kmean | |
主成分分析(用于降维) | Principal Component Analysis | PCA |
线性判别分析(fisher方法,用于降维) | Linear Discriminant Analysis | LDA |
局部线性嵌入(用于降维) | Locally linear embedding | LLE |
Hierarchy clustering | ||
Spectral clustering | ||
关联分析 | Apriori | |
自然语言处理 | Natural Language Processing | NPL |
- 几种模型效果或者准确性的指标(填坑)
- 特征选择
1)熵:
物理学概念,表示“一个系统的混乱程度”。系统的不确定性越高,熵就越大。
假设集合中的变量X={x1,x2…xn},它对应在集合的概率分别是P={p1,p2…pn}。pi是指总体各标签的概率,比如y=1的概率,y=0的概率。
一般数据分布得越均匀,数据越混乱,熵越大。
2)信息增益:
使用某个特征A划分数据集D的信息增益=划分前的熵-划分后的熵
ID3算法的特征选择标准,意思是某特征划分数据集前后的熵的差值。
信息增益越大,数据划分的效果越好。
问题是偏向于有较多取值的特征,如总体100个样本,50个good,50个bad,变量为x1,x2。此时x1的取值有100个(a,b,c,...a11,b11),用x1来划分,每个划分样本下都是0或者1(100%纯度),熵为0。这样划分有过拟合风险,没有泛化能力。
所以ID3不能处理连续特征,因为连续特征的每个值都算作一类,分类是过拟合不准确的,因此只能处理离散特征。
特征选择目标:使信息增益最大的特征和特征值。
3)信息增益比:
为了解决上述问题,C4.5算法增加一个惩罚因子,变量的类别越多,惩罚项越大。
使用某个特征A划分数据集D的信息增益=(划分前的熵-划分后的熵)/A变量分裂信息,A变量的分裂信息:
特征选择目标:使信息增益比最大的特征和特征值。
4)基尼系数:
不像熵有初始值。只有划分之后才能算基尼系数。被用于CART算法,cart是个二叉树当使用某个特征A划分样本集合只有两个集合:等于a_i的样本集合D1和不等于a_i的样本集合D2。
特征选择目标:使基尼系数最小的特征和特征值。 - 模型评估
估计值和真实值差值平方的期望,用于衡量精确度。
5)灵敏度(召回率):
描述识别出的所有正例占所有正例的比例
ROC曲线的纵轴
6)特异度:
描述识别出的负例占所有负例的比例
ROC曲线的横轴,一般在风险模型中关注差样本,所以更加关注特异度。
7)精确度:
判断为真的正例占所有判断为真的样例比重
8)准确度:
分类正确样本个数和总样本数的比值 - 关联分析
9)支持度:
A和B同时出现的概率
10)置信度:
A出现的条件下,B出现的概率
11)提升度:
包含A的时间中同时包含B的在总体B中的比例 - 常用损失函数
12)均方误差
13)
14)
二、选择算法
根据效果和场景不同,做不同选择。
- Ensemble Learning。
对同一数据使用不同算法,对不同算法结果按多数投票法输出结果;
将数据分为不同模块,对不同模块使用最优的算法,进行二次建模;XGB/LGBM在实际应用的表现通常都比较好,因此也会常用这类Boosting算法。
- 评分卡模型
对变量不多的情况下使用评分卡模型,评分卡容易解释和理解,便于业务应用,结果也较直观。使用过程是对变量进行最优分箱,IV值计算,WOE转换,变量选择,最终运用逻辑回归。得到各变量的参数。最终根据对应关系公示,对每个变量的每个箱给出一个分数,对所有变量得到一个总分。(具体过程和应用及对应代码后期单独写一篇)
- 无监督算法
无监督在风控模型中一般用在变量降维。PCA算法来对含义相近相关性强的变量进行降维。
import from sklearn.decomposition import PCA
pca = PCA(n_components=n, whiten=False)
pca.fit(tem_dat)
print('var_names',pca.explained_variance_ratio_)
n是最终保留主成分个数, explained_variance_ratio_是主成分的方差贡献度,我认为保留95%就很大了。
- boosting算法效率
数据量很大的情况下,LGBM的速度是XGB和GBM的十倍左右,虽然XGBOOST一般表现很好,但是从效率方面而言,使用相同时间重点去调参优化,LGBM也可以胜过XGBOOST。
目标函数:
image.png
相当详细必看
Xgboost的优点:
1)可以并行运算:特征列排序后以块的形式存储在内存中,在迭代中可以重复使用;虽然boosting算法迭代必须串行,但是在处理每个特征列时可以做到并行
2)考虑了训练数据为稀疏值的情况,可为缺失值或指定值指定分支的默认方向,大大提升算法的效率,约比R GBM包提升50倍效率
3)可以近似分割:在寻找最佳分割点时,考虑传统的枚举每个特征的所能分割点的贪心法效率太低,它实现了一种近似的算法。大致的思想是根据百分位法列举几个可能成为分割点的候选者,然后从候选者中根据上面求分割点的公式计算找出最佳的分割点。
- 建模时可以同时用多种算法。实际选择则根据test sample上准确性和模型运行效率等因素选择。
三、建模
参数设定
import pandas as pd
import numpy as np
import os
from collections import OrderedDict
import warnings
import copy
import statsmodels.api as sm
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier ## 梯度提升回归树
from LightGBMWrapper import LightGBM
from XGBoostWrapper import XGBoost
from xgboost import XGBClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.neural_network import MLPClassifier
from sklearn import svm,datasets
lightgbm_params = { }
跑模型
X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size=0.33, random_state=42)
'''
1. lgbm
'''
lgb = LightGBM(**lightgbm_params)
lgb = lgb.fit(X_train, Y_train)
'''
2. gbm
'''
gbm = GradientBoostingClassifier(**gbm_params)
gbm = gbm.fit(X_train, Y_train)
'''
3. xgb
'''
xgb = XGBClassifier(**xbg_params)
xgb = xgb.fit(X_train, Y_train)
'''
4. 机器学习逻辑回归:可添加L1,L2项
'''
sklogit = LogisticRegression(penalty='l2', C=1e5,solver='lbfgs', multi_class='ovr')
logit = sklogit.fit(X_train, Y_train)
'''
5. 随机森林
'''
rf = RandomForestClassifier(**rf_params)
rf = rf.fit(X_train, Y_train)
'''
6. 朴素贝叶斯
'''
nb = GaussianNB(priors=[0.8, 0.2])#默认priors=None,先验概率
nb = nb.fit(X_train,Y_train)
'''
7. 神经网络
'''
mlpc = MLPClassifier(solver='lbfgs', alpha=1e4, hidden_layer_sizes=(5,2), random_state=1)
mlpc = mlpc.fit(X_train,Y_train)
score__logit = logit.predict_proba(X_train)[:, 1]
score_te_logit = logit.predict_proba(X_test)[:, 1]
score_logit = logit.predict_proba(dat_tr.ix[:, 2:].values)[:, 1]
score__lgb = lgb.predict_proba(X_train)[:, 1]
score_te_lgb = lgb.predict_proba(X_test)[:, 1]
score_lgb = lgb.predict_proba(dat_tr.ix[:, 2:].values)[:, 1]
score__gbm = gbm.predict_proba(X_train)[:, 1]
score_te_gbm = gbm.predict_proba(X_test)[:, 1]
score_gbm = gbm.predict_proba(dat_tr.ix[:, 2:].values)[:, 1]
score__xgb = xgb.predict_proba(X_train)[:, 1]
score_te_xgb = xgb.predict_proba(X_test)[:, 1]
score_xgb = xgb.predict_proba(dat_tr.ix[:, 2:].values)[:, 1]
score__rf = rf.predict_proba(X_train)[:, 1]
score_te_rf = rf.predict_proba(X_test)[:, 1]
score_rf = rf.predict_proba(dat_tr.ix[:, 2:].values)[:, 1]
score_tr_nb = nb.predict_proba(X_train)[:, 1]
score_te_nb = nb.predict_proba(X_test)[:, 1]
score_nb = nb.predict_proba(dat_tr.ix[:, 2:].values)[:, 1]
score_tr_mlpc = mlpc.predict_proba(X_train)[:, 1]
score_te_mlpc = mlpc.predict_proba(X_test)[:, 1]
score_mlpc = mlpc.predict_proba(dat_tr.ix[:, 2:].values)[:, 1]
'''
8. 逻辑回归
'''
X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size=0.33, random_state=42)
X1=sm.add_constant(X_tr)
X2=sm.add_constant(X_te)
X3=sm.add_constant(dat_tr[temcolumn])
smlogit=sm.Logit(Y_tr,X1)
result=smlogit.fit()
score__smlogit = result.predict(X1)
score_te_smlogit = result.predict(X2)
score_smlogit = result.predict(X3)
'''
9. 深度学习
'''
from keras import backend as K
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD
from keras.optimizers import Adam
# 以上两个都属于优化器optimizer的方法类别
from keras.datasets import mnist
import numpy
'''
第一步:选择模型
'''
model = Sequential()# 选的单输入单输出相对简单的序贯模型
'''
第二步:构建网络层
对输入层、隐藏层、输出层分别定义参数
'''
# 1.输入层
model.add(Dense(100,input_shape=(9,))) # 输入层因为是二维数据n*p,直接将向量个数n输入就行。如果是三维数据n*m*p,input_shape则n*m
model.add(Activation('tanh')) # 激活函数是tanh
model.add(Dropout(0.5)) # 采用50%的dropout
# 2.隐藏层
model.add(Dense(100)) # 隐藏层节点100个
model.add(Activation('tanh')) # 激活函数是tanh
model.add(Dropout(0.5)) # 在训练过程中每次更新参数时随机断开一定百分比(rate)的输入神经元,防止过拟合。
# 3.输出层
model.add(Dense(2)) # 输出结果是2个类别,两个节点
model.add(Activation('softmax')) # 最后一层用softmax作为激活函数
'''
第三步:编译
优化器optimizer:该参数可指定为已预定义的优化器名,如rmsprop、adagrad,或一个Optimizer类的对象
损失函数loss:该参数为模型试图最小化的目标函数,它可为预定义的损失函数名,如categorical_crossentropy、mse,也可以为一个损失函数。
'''
model.compile(loss='binary_crossentropy', optimizer=Adam(), metrics=['accuracy']) # 使用交叉熵作为loss函数
'''
第四步:训练
.fit的参数
batch_size:对总的样本数进行分组,每组包含的样本数量
epochs :训练次数
shuffle:是否把数据随机打乱之后再进行训练
validation_split:拿出百分之多少用来做交叉验证
verbose:屏显模式 0:不输出 1:输出进度 2:输出每次的训练结果
'''
dat_tr = copy.deepcopy(dat_all)
dat_tr['good_bad'] = dat_tr['good_bad'].map(int)
Y_train = (numpy.arange(2) == Y_train).astype(int)
# 将Y值转化为哑变量数组
Y_test = (numpy.arange(2) == Y_test).astype(int)
## 将Y_train,Y_test转化成哑变量的形式才可以比如[[1],[0],[1]] 转化为[[0,1],[1,0],[0,1]]
model.fit(X_train,Y_train,batch_size=200,epochs=50,shuffle=True,verbose=0,validation_split=0.3)
model.evaluate(X_test, Y_test, batch_size=200, verbose=0)
'''
第五步:输出
'''
print("test set")
scores = model.evaluate(X_test,Y_test,batch_size=200,verbose=0)
# print("The test loss is %f" % scores)
# 输出损失得分
result = model.predict(X_test,batch_size=200,verbose=0)
# 预测结果([预测为0的概率,预测为1的概率])
result_max = numpy.argmax(result, axis = 1)
test_max = numpy.argmax(Y_test, axis = 1)
# 预测结果精度计算
result_bool = numpy.equal(result_max, test_max)
true_num = numpy.sum(result_bool)
print("预测精度")
print("The accuracy of the model is %f" % (true_num/len(result_bool)))
四、调整参数
格点搜索,交叉验证
from sklearn.grid_search import GridSearchCV
predictors = [x for x in df.columns if x not in ['y', 'id']]
param_test1 = {'n_estimators':list(range(20,81,10))}
gsearch1 = GridSearchCV(estimator = GradientBoostingClassifier(learning_rate=0.1, min_samples_split=500,
min_samples_leaf=50,max_depth=4,max_features='sqrt',subsample=0.8,random_state=10),
param_grid = param_test1, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch1.fit(df[predictors],df['y'])
gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_
五、评估和选择
- 根据AUC值
-
ROC和KS曲线
KS图的意义:
(1)在每个thred (0-1之间n个等分的分数阈值)上的true positive rate(真正率) 和false positive rate (假正率)之差,当然他们的差别越大越好。
QQ截图20180729182737.png
KS图和ROC图是一一对应的。
(2)KS图对应的垂直最大距离等于ROC图中roc曲线距离对角线距离对大的那一点,对应的TPR-FPR 。两线之间的距离先变大,到最大值后后变小。
(3)(0,0)表示,当好坏阈值等于1时,所有大于1的定义为positive,小于1的定义为negative,则positive中没有任何数据进来。对应的TPR和FPR都是0;当好坏阈值等于0时,所有大于0的定义为positive,小于0的定义为negative,则positive中进入所有数据。对应的TPR和FPR都是1。
(4)一般在信用评估模型中,bad=1 good=0,概率值越大,bad的概率越高。因此希望模型在识别坏的那部分更加精准(比如model_score>0.08)。所以如果模型在左下角部分的曲率更大(距离对角线的距离越远),我们就更倾向于选择这类模型。
-
推荐有关机器学习的原创博主:↓ ↓
gitlab最全的算法介绍
CSDN_专注机器学习/数据挖掘原理和实战
cnblogs_有关机器学习原理
网友评论