出品人:东哥起飞
原创:👉原创大数据风控课程《100天风控专家》
一、迁徙率介绍
什么是迁徙率呢?
我们说,一个账户现在处于某一逾期状态(比如M1),一个月后,这个账户要么从良为M0状态,要么恶化为更坏的下一个逾期状态M2。迁徙率表示上一个阶段有多少比例的逾期金额会向下一个逾期阶段继续转化,它描述了逾期状态向后恶化的程度。
一般用 M(n-1)-M(n) 的形式表示,例如:
M0-M1 = 当月进入M1的贷款余额 / 上月末M0的贷款余额
M1-M2 = 当月进入M2的贷款余额 / 上月末M1的贷款余额
…
M(n-1)-M(n) = 当月进入M(n)的贷款余额 / 上月末M(n-1)的贷款余额
上面就是迁徙率报表的形式,横轴表示各个观察月,纵轴就是不同逾期状态的迁徙。这个报表要如何看呢?
迁徙的过程是随着时间的推移才发生的,因此我们要按照这个红色箭头的方向看迁徙率。
比如2022年4月时,M0-M1的迁徙率为1.24%,说明有1.24%的客户从3月份的M0未逾期变成了M1逾期,那么这M1逾期的客户是否会继续向后转化为M2呢?还是会变为M0呢?
那只有通过下个月5月份才能知道了,因此我们看5月份时M1-M2的迁徙率为93.46%,说明进入M1的客户基本很少有还钱的,大部分会继续逾期至M2,以此类推,只要在观察时间范围内,我们就可以一直观察到M7+,180天以上。
这样就可以看出3月放款的资产,它们逾期状态迁移的过程。其他月份也是同理的,也按着这红条线观察,可以观察到时间范围内所有月份的。这就是迁徙率的形式以及观察方式。
二、迁徙率应用
01 模型Y标签定义
迁徙率可以用来分析资产变化情况,能够形象的展示客户贷款账户在整个生命周期的变化轨迹,比如通过各月迁徙率的平均值情况来看,我们发现从M1到M2的迁徙率达到了71.37%,从M2到M3的迁徙率达到了79%,后面接近100%,说明客户从M1以后已经基本不会从良还款了,有70%的比例会继续向后逾期(如下图拐点)。
因此,我们可以将逾期M1及以上定义为坏客户,即DPD30+。这对做模型制定坏客户标准的时候是一个很好的数据支撑。
02 预测坏账损失
迁徙率也可以用来预测未来坏账损失。
假如我们定义逾期超过90天以上是坏账(即M4+),那么根据当前的资产分布情况,结合过往迁徙率数据可以分段的预估出M4+逾期率,即坏账的损失。坏账损失一般用于公司财务进行风险的计提。
我们根据各月迁徙率的平均值进行评估,可以分段的预估出现阶段各个逾期状态转化为未来M4+的金额有多少,以及逾期率。最后再进行求总即可,得到预估的总的M4+逾期金额和逾期率。
三、迁徙率报表底层计算逻辑
实现迁徙率报表所需要的底层变量与Vintage是相同的,同样基于还款计划表和借据表。
基于应还日期、实还日期、应还金额、实还金额、借款金额、期数等字段进行逾期判断以及逾期天数的计算,本质上还是根据客户还款和逾期的行为数据进行逾期状态的历史还原。但二者最终的展现形式是不同的,Vintage用于横向比较各月资产质量以及逾期走势,而迁徙率用于观察逾期状态的转移过程。
那么基于同样的底层变量,如何加工出迁徙率报表呢?
具体的操作步骤如下:
-
根据已计算好的逾期天数定义逾期状态,如M0、M1、M2…M(n)
-
将观察月和各逾期状态进行透视,对剩余未还金额(贷款余额)求和
-
计算各逾期状态之间的迁徙率,如M0-M1、M1-M2… M(n-1)-M(n)
比如2022年4月的M0贷款余额为113867000,到了4月份时进入M1的贷款余额有1413968,那么对于4月份来说 M0-M1= 1413968/113867000=1.24%,同理M1-M2,以及其他月份的迁徙率也就都计算出来了。
############################M逾期期数#########################################
# data_all_1['odu_status'] = ''
data_all_1.loc[data_all_1['odu_days']<1, 'odu_status'] = 'M0'
data_all_1.loc[(1<=data_all_1['odu_days'])&(data_all_1['odu_days']<=30), 'odu_status'] = 'M1'
data_all_1.loc[(30<data_all_1['odu_days'])&(data_all_1['odu_days']<=60), 'odu_status'] = 'M2'
data_all_1.loc[(60<data_all_1['odu_days'])&(data_all_1['odu_days']<=90), 'odu_status'] = 'M3'
data_all_1.loc[(90<data_all_1['odu_days'])&(data_all_1['odu_days']<=120), 'odu_status'] = 'M4'
data_all_1.loc[(120<data_all_1['odu_days'])&(data_all_1['odu_days']<=150), 'odu_status'] = 'M5'
data_all_1.loc[(150<data_all_1['odu_days'])&(data_all_1['odu_days']<=180), 'odu_status'] = 'M6'
data_all_1.loc[(180<data_all_1['odu_days'])&(data_all_1['odu_days']<=210), 'odu_status'] = 'M7'
data_all_1.loc[(210<data_all_1['odu_days'])&(data_all_1['odu_days']<=240), 'odu_status'] = 'M8'
data_all_1.loc[(240<data_all_1['odu_days']), 'odu_status'] = 'M9+'
data_all_1['obser_month'] = data_all_1['obser_month_end'].astype(str).map(lambda x:x[:7])# 生成迁徙率表格
migr_1 = pd.pivot_table(data_all_1, index='odu_status', columns='obser_month', values='balance', aggfunc='sum').sort_index()
migr_df = migr_1/migr_1.shift(1,axis=1).shift(1,axis=0)
migr_df = migr_df.iloc[1:,1:12]
migr_df.index = ['MO->M1','M1->M2','M2->M3','M3->M4','M4->M5','M5->M6','M6->M7','M7->M8','M8->M9+']
migr_df.iloc[:-1,:-1]
这里巧用pandas的shift
函数可直接加工出迁徙率报表。
# 迁徙率
import seaborn as sns
plt.figure(figsize=(15, 8))
plt.title('Migration Rate')
sns.heatmap(data=migr_df.iloc[:-1,:-1],annot = True,fmt = '.2%',cmap='YlOrRd')
plt.show()
以上内容是《100天风控专家》报表篇Vintage理论篇节选内容,本专栏共更新100期以上,涵盖业务、产品、策略、模型、数据、系统等6大核心模块,理论+Python代码实操,课件+数据+代码均支持下载学习。规则篇课件内容如下。
Vintage账龄报表,30页PPT,40min视频👇
感兴趣可VX搜:100天风控专家
我是东哥,我们下期再见