美文网首页
常用的算法总结

常用的算法总结

作者: 这是沸羊羊的干爹 | 来源:发表于2018-07-29 19:11 被阅读0次

    风控模型常用的算法总结

    一、常用算法

    • 监督算法
    模型名称 英文名 简称
    线性回归模型 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. 特征选择
      1)熵:H(X)=-\displaystyle\sum_{i=0}^{n} p_i*log_2(p_i)
      物理学概念,表示“一个系统的混乱程度”。系统的不确定性越高,熵就越大。
      假设集合中的变量X={x1,x2…xn},它对应在集合的概率分别是P={p1,p2…pn}。pi是指总体各标签的概率,比如y=1的概率,y=0的概率。
      一般数据分布得越均匀,数据越混乱,熵越大。
      2)信息增益:g(D,A)= H(D)-H(D|A)
      使用某个特征A划分数据集D的信息增益=划分前的熵-划分后的熵
      ID3算法的特征选择标准,意思是某特征划分数据集前后的熵的差值。
      信息增益越大,数据划分的效果越好。
      问题是偏向于有较多取值的特征,如总体100个样本,50个good,50个bad,变量为x1,x2。此时x1的取值有100个(a,b,c,...a11,b11),用x1来划分,每个划分样本下都是0或者1(100%纯度),熵为0。这样划分有过拟合风险,没有泛化能力。
      所以ID3不能处理连续特征,因为连续特征的每个值都算作一类,分类是过拟合不准确的,因此只能处理离散特征。
      特征选择目标:使信息增益最大的特征和特征值。
      3)信息增益比:g(D,A)= H(D|A)/SplitInfo
      为了解决上述问题,C4.5算法增加一个惩罚因子,变量的类别越多,惩罚项越大。
      使用某个特征A划分数据集D的信息增益=(划分前的熵-划分后的熵)/A变量分裂信息,A变量的分裂信息:SplitInfo=-\displaystyle\sum_{i=0}^{k} a_i*log_2(a_i)
      特征选择目标:使信息增益比最大的特征和特征值。
      4)基尼系数:Gini(x)=\displaystyle\sum_{i=0}^{k} p_i*(1-p_i)
      不像熵有初始值。只有划分之后才能算基尼系数。被用于CART算法,cart是个二叉树当使用某个特征A划分样本集合只有两个集合:等于a_i的样本集合D1和不等于a_i的样本集合D2。
      gini(D,A)=(D1/D)*Gini(x)+(D2/D)*Gini(x)
      特征选择目标:使基尼系数最小的特征和特征值。
    2. 模型评估
      估计值和真实值差值平方的期望,用于衡量精确度。
      5)灵敏度(召回率):TPR=TP/ (TP+ FN)
      描述识别出的所有正例占所有正例的比例
      ROC曲线的纵轴
      6)特异度:TNR=TP/ (FP+ TN)
      描述识别出的负例占所有负例的比例
      ROC曲线的横轴,一般在风险模型中关注差样本,所以更加关注特异度。
      7)精确度:accuracy=TP/ (TP+ FP)
      判断为真的正例占所有判断为真的样例比重
      8)准确度:precision=(TP+TN)/ (TP+TN+FP+ FN)
      分类正确样本个数和总样本数的比值
    3. 关联分析
      9)支持度:Support(A->B)=P(A U B)
      A和B同时出现的概率
      10)置信度:Confidence(A->B)=P(A | B)
      A出现的条件下,B出现的概率
      11)提升度:Lift=(P(AandB)/P(A))/P(B)
      包含A的时间中同时包含B的在总体B中的比例
    4. 常用损失函数
      12)均方误差MSE=(1/n)\displaystyle\sum_{i=0}^{n} (predicted-observed)^2
      13)
      14)

    二、选择算法

    根据效果和场景不同,做不同选择。

      1. Ensemble Learning。

    对同一数据使用不同算法,对不同算法结果按多数投票法输出结果;
    将数据分为不同模块,对不同模块使用最优的算法,进行二次建模;XGB/LGBM在实际应用的表现通常都比较好,因此也会常用这类Boosting算法。

      1. 评分卡模型

    对变量不多的情况下使用评分卡模型,评分卡容易解释和理解,便于业务应用,结果也较直观。使用过程是对变量进行最优分箱,IV值计算,WOE转换,变量选择,最终运用逻辑回归。得到各变量的参数。最终根据对应关系公示,对每个变量的每个箱给出一个分数,对所有变量得到一个总分。(具体过程和应用及对应代码后期单独写一篇)

      1. 无监督算法

    无监督在风控模型中一般用在变量降维。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%就很大了。

      1. boosting算法效率

    数据量很大的情况下,LGBM的速度是XGB和GBM的十倍左右,虽然XGBOOST一般表现很好,但是从效率方面而言,使用相同时间重点去调参优化,LGBM也可以胜过XGBOOST。
    目标函数:


    image.png

    相当详细必看
    Xgboost的优点
    1)可以并行运算:特征列排序后以块的形式存储在内存中,在迭代中可以重复使用;虽然boosting算法迭代必须串行,但是在处理每个特征列时可以做到并行
    2)考虑了训练数据为稀疏值的情况,可为缺失值或指定值指定分支的默认方向,大大提升算法的效率,约比R GBM包提升50倍效率
    3)可以近似分割:在寻找最佳分割点时,考虑传统的枚举每个特征的所能分割点的贪心法效率太低,它实现了一种近似的算法。大致的思想是根据百分位法列举几个可能成为分割点的候选者,然后从候选者中根据上面求分割点的公式计算找出最佳的分割点。

      1. 建模时可以同时用多种算法。实际选择则根据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)))
    

    四、调整参数

    格点搜索,交叉验证

    GBM调参指南
    XGB调参指南

    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_
    

    五、评估和选择

      1. 根据AUC值
      1. 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_有关机器学习原理

    相关文章

      网友评论

          本文标题:常用的算法总结

          本文链接:https://www.haomeiwen.com/subject/iwltvftx.html