积分卡模型建模流程总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hxcaifly/article/details/80296166

1.如何确定good和bad

这点很重要,是基于业务的深刻理解。比如我们是基于人是否有涉黄前科来区分bad和good的。

2.样本选择

这里容易发生一个问题,就是黑白名单分布不均匀问题。也就是样本不平衡问题。这会影响我们模型训练结果的准确率。对于这种样本不平衡问题,应该怎么处理。
加载样本数据

yxtz_data=pd.read_csv('/home/liuweitang/yellow_model/data/mk/train_opp_sex_feature_20180508.txt',sep='$')
f, ax = plt.subplots(1,2, figsize=(18,8))
yxtz_data['label'].value_counts().plot.pie(explode=[0,0.1], autopct='%1.1f%%',colors=['red','blue'], ax=ax[0],shadow=True)
ax[0].set_title('label')
ax[0].set_ylabel('')
sns.countplot('label',data=yxtz_data, ax=ax[1])
ax[1].set_title('label')
plt.show()

这里写图片描述

3.查看特征值的分布情况

对于特征值的分布最好是符合正态分布。

sns.distplot(yxtz_data[(yxtz_data['label']==1)].opp_sex_age_max_n3, color='red')
sns.distplot(yxtz_data[(yxtz_data['label']==0)].opp_sex_age_max_n3, color='blue')
plt.show()

这里写图片描述

如果不符合正态分布,结合具体场景,看需不需正态化转变。比如开平方,取对数等手段。唯一不好的地方,这样操作可能会影响特征值的可解释性。

4.缺失值处理,同值化处理,离群点检测

1. 直接通过感官认识,删除一些没有意义的特征。
2. 同值化处理
比如数据里面的98%的民族是汉族,那么这个民族特征就没有多大的表达意义,因此可以删除掉。
3. 缺失值处理。具体方法:
- 直接舍弃(一般缺失值占比较多的)
- 均值,中位数,众数等填充法(一般缺失值占比较少的),或者填充0
- 用上下数据进行填充
- 插值法(拉格朗日插值法)
- 机器学习算法拟合或预测缺失值(如使用随机森林进行缺失值预测)
4.离群点检测
- 可以采用箱体图或者散点图来感官地表达,但是要注意,离群点数据不一定是异常数据,要结合业务,不要轻易删掉。
5.无量纲化
- 数据进行无量纲化,通常的方法有:标准化和极值化两种方式。
- kmeans 聚类,并且TNSE降维,可视化数据的聚类分布图。
6.特征衍生
根据业务理解,衍生出新的特征。
7.LabelEncoder
这个比较简单,就是直接将整数来替换类别,例如在性别中用 1 替换男,用 2 替换女。对于基础的类别特征可以这样处理。

5. 筛选变量

根据提供的特征值,这里还需要进行一些筛选,筛选出最相关的特征值。
1. 协同关系图
逻辑回归对相关性比较高的特征非常敏感,所以需要研究特征之间协同相关性。

sns.heatmap(openning_data.corr(), annot=True, cmap='RdYlGn', linewidths=0.2)
fig=plt.gcf()
fig.set_size_inches(20,16)
plt.show()

这里写图片描述

如果任意两个特征值之间的协同值很大,那么可以考虑只保留其一。

2. 连续变量分箱
对连续变量分箱的好处多多,具体为什么,可以见我的博客[分箱算法]。具体的分箱方法有无监督分箱和有监督分。无监督分箱通常有等频,等距和聚类等方法。有监督分箱通常有卡方分箱和Best-KS分箱。
如果为了快速,可以选择初步尝试无监督分箱方法:

#等距分箱
pd.cut(x,bins=10)

#等频分箱
pd.qcut(x,bins=10)

但在实际应用中,为了达到最大优化的分箱方法,我们一般会选择有监督分箱方法。卡方分箱的代码还有待优化,Best-KS 分箱的自动化脚本已经跑通。

3. 分箱效果衡量指标
分箱之后,通常按照WOE值,IV值和KS值等指标来衡量分箱之后特征的预测能力。WOE,IV,KS的计算代码已经有了。然后对数据按照IV大小顺序进行排序,以便于删除相关性较高里面IV值低的变量。
IV和KS的具体含义可以参考我之前的博客 。
4.初步模型结果
我们要将iv中分组的WOE值根据最优分箱的结果,按照划分的区间大小回填到原始的数据样本中,将原始数据进行替换,然后做逻辑回归拟合。
将数据集中变量的category取值用其对应的woe值替换,并返回替换后的数据集。有的实验称用woe替换后训练的分类器能会更好,所以提供了这么个函数

6.训练模型

先略

7. 效果评估

评分卡模型训练好之后,需要对其训练的结果进行验证。通常来说需要从准确性,稳定性和可解释性等三个方面对模型训练结果进行评估。
其中,准确性指标包括感受性曲线下面积(ROC_AUC)和区分度指标(KS);稳定性指标主要参考群体稳定指数(Population Shift Index, PSI);可解释性可通过指标重要度来进行评估,其中指标重要度用于衡量各个解释变量对算法预测结果影响的程度。

1. 感受性曲线下面积(ROC_AUC)

ROC_AUC曲线是一个从整体上评价模型准确性的指标,是感受性曲线(ROC)与横轴之间的面积。具体ROC的讲解,可以参考我之前的博客ROC曲线的理解。相比于其他评价指标,ROC具有一定的稳定性,它不会因为正负样本分布的变化而产生不同的曲线。ROC曲线通过真阳率(True Positive Rate, TPR)和假阳率(False Positive Rate, FPR)两个指标进行绘制。感受性曲线下面积取值范围一般在[0.5,1],取值越大,代表模型整体准确性越好。
附上代码

这里写代码片

2. 区分度指标(KS)
区分度指标(KS)是度量具体模型下正常样本和违约样本分布的最大差距。首先按照样本的信用分数或预测违约率从小到大进行排序,然后计算每一个分数或违约率下好坏样本的累积占比。正常和违约样本的累计占比差值的最大值即为区分度指标(KS)。区分度指标(KS)的值小于0.2代表模型准确性差,超过0.75则代表模型准确性高。

KS求解方法

KS需要TPR和FPR两个值:TPR=TP/(TP+FN) 刻画的是分类器所识别出的正实例占所有正实例的比例; FPR=FP/(TN+FP)刻画的是分类器错认为正类的负实例占所有负实例的比例。KS=max(TPR-FPR)。
计算具体过程:
1.按照分类模型返回的概率降序排列,也可以直接是数据,根据某一阈值判断为1或0即可。
2.把0-1之间等分N份,等分点为阈值,计算TPR,FPR(可以将每一个都作为阈值)
3. 对TPR,FPR描点画图即可。(以10%*k(k=1,2,3,….,9))为横坐标,分别以TPR和FPR的值作为纵坐标,就可以画出两个曲线,这就是K-S曲线。KS值即为max(TPR-FPR)。
附上代码

#-*- coding:utf-8 -*-  
#自己实现计算ks与调包  
from sklearn.metrics import roc_curve  
import matplotlib.pyplot as plt  
import seaborn as sns  
#%matplotlib inline  
#%config InlineBackend.figure_format = 'retina'  
plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文字体设置-黑体  
plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题  
sns.set(font='SimHei')  # 解决Seaborn中文显示问题  

class BinJianAna:  
    def __init__(self):  
        pass  

    def ComuTF(self,lst1,lst2):  
        #计算TPR和FPR    
        #lst1为真实值,lst2为预测值  
        TP = sum([1 if a==b==1 else 0 for a,b in zip(lst1,lst2)])#正例被预测为正例  
        FN = sum([1 if a==1 and b==0 else 0 for a,b in zip(lst1,lst2)])#正例被预测为反例  
        TPR = TP/(TP+FN)   
        TN = sum([1 if a==b==0 else 0 for a,b in zip(lst1,lst2)])#反例被预测为反例  
        FP = sum([1 if a==0 and b==1 else 0 for a,b in zip(lst1,lst2)])#反例被预测为正例  
        FPR = FP/(TN+FP)  
        return TPR - FPR  

    def Getps_ks(self,real_data,data):  
        #real_data为真实值,data为原数据  
        d = []  
        for i in data:  
            pre_data = [1 if line >=i else 0 for line in data]  
            d.append(self.ComuTF(real_data,pre_data))  
        return max(d),data[d.index(max(d))]  

    def GetKS(self,y_test,y_pred_prob):  
        #y_test为真实值,y_pred_prob为预测出来的概率  
        fpr,tpr,thresholds = roc_curve(y_test,y_pred_prob)  
        #画ROC曲线  
        plt.plot([0,1],[0,1],'k--')  
        plt.plot(fpr,tpr)  
        plt.xlabel('False Positive Rate')  
        plt.ylabel('True Positive Rate')  
        plt.show()  
        #画ks曲线  
        plt.plot(tpr)  
        plt.plot(fpr)  
        plt.plot(tpr-fpr)  
        plt.show()  
        return fpr,tpr,thresholds  


if __name__ == '__main__':  
    a = BinJianAna()  
    data = [790,22,345,543,564,342,344,666,789,123,231,234,235,347,234,237,178,198,567,222]#原始评分数据  
    real_data = [1,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0]  
    y_pred_prob = [0.42,0.73,0.55,0.37,0.57,0.70,0.25,0.23,0.46,0.62,0.76,0.46,0.55,0.56,0.56,0.38,0.37,0.73,0.77,0.21,0.39]  
    print(a.Getps_ks(real_data,data))#自己实现  
    print(a.GetKS(real_data,y_pred_prob))#代码实现  

3. 群体稳定指数(PSI)
型是在特定时间开发的,是否对外部样本有效需要经过稳定性测试。群体群定性指数(PSI)是最常用的模型稳定性评价指标。群体稳定指数(PSI)的计算公式:
这里写图片描述
其中预期占比(Expected%)和实际占比(Actual%)分别表示在模型训练样本和测试样本中,对应分数段或者违约段内的人群占比。一般而言,群体稳定指数(PSI)小于0.1代表稳定性高,PSI大于0.1小于0.25代表模型稳定性中等,PSI大于0.25代表模型稳定性较差。

8. 应该注意的问题

略,还没总结

猜你喜欢

转载自blog.csdn.net/hxcaifly/article/details/80296166