金融风险预测赛 Task1
比赛地址:https://tianchi.aliyun.com/competition/entrance/531830/introduction
一、赛题
赛题以预测用户贷款是否违约为任务,数据集报名后可见并可下载,该数据来自某信贷平台的贷款记录,总数据量超过120w,包含47列变量信息,其中15列为匿名变量。为了保证比赛的公平性,将会从中抽取80万条作为训练集,20万条作为测试集A,20万条作为测试集B,同时会对employmentTitle、purpose、postCode和title等信息进行脱敏。
字段表
Field | Description |
---|---|
id | 为贷款清单分配的唯一信用证标识 |
loanAmnt | 贷款金额 |
term | 贷款期限(year) |
interestRate | 贷款利率 |
installment | 分期付款金额 |
grade | 贷款等级 |
subGrade | 贷款等级之子级 |
employmentTitle | 就业职称 |
employmentLength | 就业年限(年) |
homeOwnership | 借款人在登记时提供的房屋所有权状况 |
annualIncome | 年收入 |
verificationStatus | 验证状态 |
issueDate | 贷款发放的月份 |
purpose | 借款人在贷款申请时的贷款用途类别 |
postCode | 借款人在贷款申请中提供的邮政编码的前3位数字 |
regionCode | 地区编码 |
dti | 债务收入比 |
delinquency_2years | 借款人过去2年信用档案中逾期30天以上的违约事件数 |
ficoRangeLow | 借款人在贷款发放时的fico所属的下限范围 |
ficoRangeHigh | 借款人在贷款发放时的fico所属的上限范围 |
openAcc | 借款人信用档案中未结信用额度的数量 |
pubRec | 贬损公共记录的数量 |
pubRecBankruptcies | 公开记录清除的数量 |
revolBal | 信贷周转余额合计 |
revolUtil | 循环额度利用率,或借款人使用的相对于所有可用循环信贷的信贷金额 |
totalAcc | 借款人信用档案中当前的信用额度总数 |
initialListStatus | 贷款的初始列表状态 |
applicationType | 表明贷款是个人申请还是与两个共同借款人的联合申请 |
earliesCreditLine | 借款人最早报告的信用额度开立的月份 |
title | 借款人提供的贷款名称 |
policyCode | 公开可用的策略_代码=1新产品不公开可用的策略_代码=2 |
n系列匿名特征 | 匿名特征n0-n14,为一些贷款人行为计数特征的处理 |
二、预测指标
提交结果为每个测试样本是1的概率,也就是y为1的概率。评价方法为AUC评估模型效果(越大越好)。
AUC(Area Under Curve)被定义为 ROC曲线 下与坐标轴围成的面积。
混淆矩阵,精确度,召回率
- True Positive(真阳性):实际为1,预测为1。预测正确。
- False Positive(假阳性):实际为0,预测为1。预测错误。
- False Negative(假阴性):实际为1,预测为0。预测错误。
- True Negative(真阴性):实际为0,预测为0。预测正确。
F1 score是“准确率”和“召回率”的调和平均数
$$
Harmonic \ Mean \ of \ P \& R : F1 \ score = \frac{1}{\frac{1}{2} (\frac{1}{P} + \frac{1}{R}) } = 2 \frac{PR}{P+R}
$$ROC(Receiver Operating Characteristic)
ROC空间将假正例率(FPR)定义为 X 轴,真正例率(TPR)定义为 Y 轴
TPR:在所有实际为正例的样本中,被正确地判断为正例之比率
$$
TPR= \frac{TP}{TP+FN} = Recall
$$
FPR:在所有实际为负例的样本中,被错误地判断为正例之比率。
$$
FPR = \frac{FP}{FP+TN}
$$AUC(Area Under Curve)被定义为 ROC曲线 下与坐标轴围成的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。AUC越接近1.0,检测方法真实性越高;等于0.5时,则真实性最低,无应用价值。
- AUC值范围从0到1,表示模型区分正类和负类的能力:
- AUC = 1:完美分类器,能够完全区分正类和负类。
- AUC = 0.5:随机猜测水平,无法区分正类和负类。
- AUC < 0.5:比随机猜测还差,但这种情况很少见。
- AUC的优点:
- 不依赖于特定的阈值选择,因为它考虑了所有可能的阈值。
- 对不平衡数据集也有较好的表现。
- AUC值范围从0到1,表示模型区分正类和负类的能力:
KS(Kolmogorov-Smirnov)统计量是另一种用于评估分类模型性能的方法,尤其在金融风险评估等领域广泛应用。KS统计量衡量的是模型预测的概率分布中,正类和负类累积分布函数的最大差异。具体来说,它找到最大距离点来衡量两个分布之间的差异。累积分布函数(CDF):对于给定的阈值,计算出正类和负类样本的累积概率分布。
KS值的计算
假设我们有一个模型输出的概率或分数,分别对正类和负类样本进行排序并计算其累积分布。
KS值 = max(TPR - FPR),即在所有可能的阈值下,正类和负类累积分布函数的最大差异。
KS值范围:从0到1。
- KS = 1:模型能完美区分正类和负类。
- KS接近0:模型几乎没有区分能力,类似于随机猜测。
KS(%) 好坏区分能力 20以下 不建议采用 20-40 较好 41-50 良好 51-60 很强 61-75 非常强 75以上 过于高,疑似存在问题 KS的优点:
- 直观地反映了模型区分正类和负类的能力。
- 在金融领域常用于评估信用评分模型的表现。
比较AUC和KS
- 应用场景:
- AUC:广泛应用于各种分类任务,尤其是需要全面评估模型在不同阈值下的性能时。
- KS:特别适用于金融、保险等行业,用于评估模型区分高风险客户和低风险客户的能力。
- 解释性:
- AUC:提供了一个整体的模型性能度量,不依赖于具体的阈值选择。
- KS:强调了模型在某个特定阈值下的最佳区分能力,更直观地反映了模型在该点上的表现。
- 计算复杂度:
- AUC:需要计算所有可能的阈值下的TPR和FPR,并计算曲线下面积。
- KS:只需要找到正类和负类累积分布函数的最大差异点。
- 使用场景:
- 如果你关心模型在整个阈值范围内的表现,AUC是一个更好的选择。
- 如果你更关注模型在一个特定阈值下的最佳区分能力,KS可能更适合。
三、数据读取和分类指标计算测试
数据读取测试
import pandas as pd
# pandas 读取数据
train = pd.read_csv('./data/train.csv')
test = pd.read_csv('./data/testA.csv')
print(train.shape) #(800000, 47)
print(test.shape) #(200000, 46)
train.head()
分类指标计算测试
## 混淆矩阵
import numpy as np
from sklearn.metrics import confusion_matrix,accuracy_score
from sklearn import metrics
y_pred = np.array([0, 1, 0, 1])
y_true = np.array([0, 1, 1, 0])
print('混淆矩阵:\n',confusion_matrix(y_true, y_pred))
混淆矩阵:
[[1 1]
[1 1]]
## accuracy
print("ACC", accuracy_score(y_true,y_pred)) # 0.5
## Precision,Recall,F1-score
y_pred = [0, 1, 0, 1]
y_true = [0, 1, 1, 0]
print('Precision',metrics.precision_score(y_true, y_pred))
print('Recall',metrics.recall_score(y_true, y_pred))
print('F1-score:',metrics.f1_score(y_true, y_pred))
Precision 0.5
Recall 0.5
F1-score: 0.5
PR曲线
## P-R曲线
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve
y_pred = [0, 1, 1, 0, 1, 1, 0, 1, 1, 1]
y_true = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1]
precision, recall, thresholds = precision_recall_curve(y_true, y_pred)
plt.title("P-R curve")
plt.xlabel('precision')
plt.ylabel('recall')
plt.plot(precision, recall)
ROC 曲线
## ROC曲线
from sklearn.metrics import roc_curve
y_pred = [0, 1, 1, 0, 1, 1, 0, 1, 1, 1]
y_true = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1]
FPR,TPR,thresholds=roc_curve(y_true, y_pred)
plt.title('ROC')
plt.plot(FPR, TPR,'b')
plt.plot([0,1],[0,1],'r--')
plt.ylabel('TPR')
plt.xlabel('FPR')
AUC
## AUC
import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
print('AUC socre:',roc_auc_score(y_true, y_scores)) # 0.75
KS
## KS值 在实际操作时往往使用ROC曲线配合求出KS值
from sklearn.metrics import roc_curve
y_pred = [0, 1, 1, 0, 1, 1, 0, 1, 1, 1]
y_true = [0, 1, 1, 0, 1, 0, 1, 1, 1, 1]
FPR,TPR,thresholds=roc_curve(y_true, y_pred)
KS=abs(FPR-TPR).max()
print('KS值:',KS) #KS值: 0.5238095238095237
扩展 评分卡
评分卡是一张拥有分数刻度会让相应阈值的表。信用评分卡是用于用户信用的一张刻度表。以下代码是一个非标准评分卡的代码流程,用于刻画用户的信用评分。评分卡是金融风控中常用的一种对于用户信用进行刻画的手段哦!
#评分卡 不是标准评分卡
def Score(prob,P0=600,PDO=20,badrate=None,goodrate=None):
P0 = P0
PDO = PDO
theta0 = badrate/goodrate
B = PDO/np.log(2)
A = P0 + B*np.log(2*theta0)
score = A-B*np.log(prob/(1-prob))
return score
这段代码定义了一个用于计算信用评分(Score)的函数,基于给定的概率(prob
),并使用了类似于标准评分卡模型的方法。让我们逐步解析这个函数及其各个组成部分。
函数定义
def Score(prob, P0=600, PDO=20, badrate=None, goodrate=None):
- 参数:
prob
: 模型预测的违约概率。P0
: 基准分数,默认值为600。这是当违约概率为基准比率时的分数。PDO
: Points to Double the Odds (PDO),表示几率加倍所需的分数变化,默认值为20。例如,如果PDO为20,则意味着每增加20分,违约几率减半。badrate
: 坏样本(违约样本)的比例。goodrate
: 好样本(正常样本)的比例。
变量初始化和计算
P0 = P0
PDO = PDO
theta0 = badrate / goodrate
B = PDO / np.log(2)
A = P0 + B * np.log(2 * theta0)
score = A - B * np.log(prob / (1 - prob))
P0
和PDO
:- 这些是直接从输入参数传递过来的默认值或用户指定的值。
theta0
:theta0
是坏样本率与好样本率的比值(即违约几率)。它反映了在基准情况下(通常是训练数据集中的整体违约率)的违约概率。- 公式:
theta0 = badrate / goodrate
B
:B
是一个常数,用于将对数几率转换为分数。它是PDO除以自然对数2的结果,因为PDO定义了几率加倍时的分数变化。- 公式:
B = PDO / np.log(2)
A
:A
是一个偏移量,确保在基准违约概率下的分数等于基准分数P0
。- 公式:
A = P0 + B * np.log(2 * theta0)
- 这里的
np.log(2 * theta0)
是为了调整基准违约概率下的分数。
score
:score
是最终计算出的信用评分,基于输入的概率prob
。- 公式:
score = A - B * np.log(prob / (1 - prob))
- 这里
np.log(prob / (1 - prob))
是对数几率(log-odds),它衡量了某个事件发生的可能性相对于不发生的可能性的比率。
详细解释
对数几率(Log-Odds):
- 对数几率是指某个事件发生概率与其不发生概率之比的对数。公式为:
log(odds) = log(prob / (1 - prob))
- 在信用评分中,这通常表示某个人违约的可能性与其不违约的可能性之比。
- 对数几率是指某个事件发生概率与其不发生概率之比的对数。公式为:
PDO(Points to Double the Odds):
- PDO 表示当违约几率翻倍时,分数应增加多少。通过设置PDO,可以控制评分卡的灵敏度。
- 例如,如果PDO为20,则每增加20分,违约几率减少一半。
基准分数(P0):
- 基准分数是在基准违约概率下的分数。它通常设置为一个较高的值(如600),以便在实际应用中得到合理的分数范围。
示例
假设我们有一个违约概率 prob = 0.1
,并且我们知道 badrate = 0.2
和 goodrate = 0.8
:
import numpy as np
def Score(prob, P0=600, PDO=20, badrate=None, goodrate=None):
theta0 = badrate / goodrate
B = PDO / np.log(2)
A = P0 + B * np.log(2 * theta0)
score = A - B * np.log(prob / (1 - prob))
return score
# 示例调用
prob = 0.1
badrate = 0.2
goodrate = 0.8
score = Score(prob, P0=600, PDO=20, badrate=badrate, goodrate=goodrate)
print(f"Score: {score}")
在这个例子中,theta0
为 0.2 / 0.8 = 0.25
,然后根据上述公式计算出最终的信用评分。
总结
该函数通过给定的违约概率 prob
,结合基准分数 P0
、PDO、坏样本率 badrate
和好样本率 goodrate
,计算出一个信用评分。这个评分卡方法允许你灵活地调整评分卡的基准点和灵敏度,并且可以根据具体业务需求进行定制。