自学内容网 自学内容网

机器学习与金融风控项目篇-day01-风控业务

一. 整体项目介绍

1.风控业务和风控报表

零售金融产品相关的指标风控建模流程

2.特征工程

特征构造特征筛选

3.评分卡模型构建

逻辑回归集成学习 XGBoost LightGBM模型评估

4.样本不均衡问题/异常点检测

二. 信贷与风控介绍

信贷业务

信贷业务,就是贷款业务,是商业银行和互联网金融公司最重要的资产业务和主要赢利手段

  1. 通过放款收回本金和利息,扣除成本后获得利润。

  2. 贷款平台预测有信贷需求用户的还款情况,然后将本金借贷给还款概率大的用户

信贷的风险控制

  1. 信贷业务中,使用信用来预支金钱,在小额贷业务中往往没有抵押物,那么贷款方就会承担一定风险(用户不还钱)

  2. 风控就是对用户的信用风险进行管理与规避,对于预测信用较差的人,不向其放款,即便放款,也会是较小的贷款额度和较高的利率

  3. 信贷领域有两类风险

    • 信用风险:借款人的的还款能力和还款意愿在贷款后出现问题的风险

    • 欺诈风险:借款人压根没想还钱,以诈骗为目的

  4. 风控业务主要针对这两类风险

    • 信用评分系统:针对信用风险

    • 反欺诈系统:针对欺诈风险

  5. 基于机器学习的人工智能风控模型对比传统人工审批

    • 人工审批:效率低,对人员业务能力要求高,不适合金融零售业务场景

    • 机器学习模型:批量,迅速,准确,同时处理大量贷款请求(几万,几十万,上百万/天)

三. 信贷产品及风险介绍

信贷产品

信贷产品介绍

个人信贷产品
大额借贷房贷车贷
小微企业贷
小额借贷消费贷蚂蚁花呗,京东白条
现金贷蚂蚁借呗,京东金条,微粒贷,各类网贷
数据服务信用分服务芝麻信用分,京东小白分
信用数据服务同盾数据,百融,集奥,大峰...

现金贷

申请借款->放款给客户->客户还款

额度500~3000
利率24%~36%
期限714,30天
放款形式借给现金,不限场景
可选功能订单展期
现金贷产品年化利率现金贷产品年化利率
苏宁金融24%国美易卡34%
蚂蚁借呗24%马上消费35%
微粒贷24%招联金融36%
有钱花24%桔子分期36%
京东金条24%拍拍贷36%
360借条24%趣店36%
小米金融24%捷信36%
美团生活费24%宜人贷44%
分期乐24%玖富50%

消费贷

信用卡,花呗,白条等产品,有账单日,还款日

申请消费贷 -> 额度授信->客户使用消费贷消费

额度1000~10000
利率24%
账期30天
放款形式指定消费场景
可选功能最低还款,账单展期,账单分期,停息挂账,临时额度,备用金

产品类型

  • 单期产品

  • 多期产品

  • 循环额度产品

还款方式

  • 砍头息:短期产品, (服务费)

  • 等额本金

    每月还款额度依次递减,

  • 等额本息

    每月还款额度一样, 整个贷款利息要比等额本金多一些

信贷领域风险类别

  • 信用风险:借款人的的还款能力和还款意愿在贷款后出现问题的风险

  • 欺诈风险:借款人压根没想还钱,以诈骗为目的

常见风险形式

  1. 冒名顶替,黑产骗贷

  2. 多头借贷,借新还旧

    客户:工行信用卡,招商信用卡... n张信用卡,网贷平台1,网贷平台2,网贷平台n

    用新借来的钱还已有的负债:负债变多 -> 需新借更多 -> 设法提额 -> 信用资质不够 -> 出现流动性风险 -> 逾期

    特点:第三方数据:多头申请记录

    APP安装:大量借款类APP

    短信:大量申请短信,提醒还款,催收短信

  3. POS机套现,以少换多

    购买有支付牌照机构的POS机进行套现,手续费0.6%

  4. 针对风控模型,制作数据

    使用花呗在天猫购物,对花呗账单做分期

    买入存金宝,一个礼拜后追加存金宝资金

    购买***元基金

    保持余额宝XXX元不动,余额宝累计收益做到 XX元

    购买XXXX保险

四. 风控相关术语

术语解释
※DPDDay past due 逾期天数 DPD0为到期当日,DPD1为逾期一日,DPD7为逾期一周
※FPDFirst time past due 首次逾期天数
F/S/T/QPD首次 二次 三次 四次 逾期天数
※M1逾期 [1, 30)天 M 是英文“Months”的首写字母
※M1+逾期[30, inf]天
default坏账
delinquency拖欠
flow rate流动率 一般指M1向M2,M2向M3转移的比例
bad rate坏账率 当月不良资产数/总资产数
vintage账龄分析

五. 风控业务案例

案例背景

数据集说明

  • 从开源数据改造而来,基本反映真实业务数据

  • 销售,客服可以忽略

  • 账单周期,放款日期

  • 账单金额-实收金额 = 未收金额

  • 应付日期为还款时间

  • 账期分成两种:60天和90天

  • 实际到账日为空白,说明没还钱

业务分析

  1. 每个季度账单金额和坏账率(逾期90天以上)

    所有未收金额/所有账单金额

    未收金额 = 账单金额-实收金额

  1. 每个季度60天账期的入催率,90天账单的入催率

    入催率 = 入催金额/账单金额

  1. 历史逾期天数的回款情况(回收账单数)

    历史逾期天数:历史有逾期,但是相对现在来说,钱已经还完了

    当前逾期天数:现在还欠着钱,也就是说钱没还完

代码实现

导包

import pandas as pd
from pyecharts.charts import *
from pyecharts import options as opts
import os 
os.chdir(r'D:\CodeProject\05JRFK_Project\my_project\day01-风控相关业务')
os.getcwd()

查看数据

df1 = pd.read_excel('../data/业务数据.xls')
df1.info()
df1.describe()
df1.head(100)

数据预处理

当前日期

准备当前日期, 已数据中的实际倒找到账日最大值为当前日期

# 准备当前日期, 已数据中的实际倒找到账日最大值为当前日期
# pd.to_datetime(df1['实际到账日']).max()    # Timestamp('2019-05-17 00:00:00')
# 用实际还款日的最大值表示数据统计时间
today_time = pd.to_datetime(df1['实际到账日'].fillna('0').max())  # 效果同上
today_time
缺失值
# 填充缺失值
df1['实收金额'] = df1['实收金额'].fillna(0)
df1['开票金额'] = df1['开票金额'].fillna(0)
df1['未收金额'] = df1['未收金额'].fillna(0)
df1.info()
时间类型转换
# 时间类转换
df1['应付日期'] = pd.to_datetime(df1['应付日期'])   # 还款日期
df1['账单周期'] = pd.to_datetime(df1['账单周期'])   # 放款日期
# 实际到账日有缺失, 可以填充也可以过滤, 最终看需求
# 如果到账日等于当前日期, 则说明没还钱(实际到账日为实际还款日)
df1['实际到账日'] = pd.to_datetime(df1['实际到账日']).fillna(today_time)  
df1.info()

构造中间字段

是否到期
df2 = df1.copy()
# 添加是否到期列
df2['是否到期'] = df2.apply(lambda x: 0 if x['应付日期'] > today_time else 1, axis=1)
# df2.['应付日期'].apply(lambda x: 0 if x > today_time else 1)  # 效果同上
是否到期90天
# 添加是否到期90天字段
df2['是否到期90天'] = (today_time - df2['应付日期']).map(lambda x: 1 if x.days > 90 else 0)
df2.是否到期90天
未收金额
# 构造未收金额2(原始未收金额字段有误)
df2['未收金额2'] = (df2['账单金额'] - df2['实收金额'])
历史逾期和当前逾期
# 历史逾期
# 等于0时计算还款时是否逾期(小于0表示: 提前还款)
# 未还金额不等于0表示到统计日期还未归还完毕(当前逾期天数)
df2['历史逾期天数'] = df2.apply(lambda x:(x['实际到账日'] - x['应付日期']).days if x['未收金额2'] == 0 else (today_time - x['应付日期']).days, axis=1)
​
# 当前逾期天数
# (负数表示统计日期还没到还款日期)
df2['当前逾期天数'] = df2.apply(lambda x: x['历史逾期天数'] if x['未收金额2'] > 0 else 0, axis=1)
df2.tail(100)

需求1:坏账率

每个季度账单金额和坏账率(逾期90天以上)

所有未收金额/所有账单金额

未收金额 = 账单金额-实收金额

构造季度字段
# 构建季度字段
df3['账单季度'] = df3['账单周期'].apply(lambda x: x.to_period('Q'))
df3.head()
过滤季度

2019Q1和2019Q2到统计日期大概率不会有逾期90天的数据

# 过滤季度
df3['账单季度'].value_counts()
df3 = df3[(df3['账单季度'] >= '2017Q3') & (df3['账单季度'] <= '2018Q4')]
df3.shape
统计指标

账单金额, 到期90天金额, 当前到期90+金额

# 统计指标: 账单金额, 到期90天金额, 当前到期90+金额
​
# 账单金额
fn1 = df3.groupby('账单季度')[['账单金额']].sum()
fn1.columns = ['账单金额']
fn1
​
# 到期金额(90天)
df4 = df3[df3['是否到期90天'] == 1]
fn2 = df4.groupby('账单季度')[['账单金额']].sum()
fn2.columns = ['到期金额']
fn2
​
# 到期(90天+)金额
fn3 = df4.groupby('账单季度')[['未收金额2']].sum()
fn3.columns = ['到期90+金额']
fn3
拼接指标计算坏账率
# 合并上述的3DF对象
final1 = pd.concat([fn1, fn2, fn3], axis=1)
final1
​
# 计算净坏账率
final1['90+净坏账率'] = round(final1['到期90+金额'] / final1['到期金额'], 3)
final1
结果可视化
# 画图
bar = (
    Bar()
    .add_xaxis(list(final1.index.values.astype(str)))
    .add_yaxis(
        "账单金额",
        list(final1.账单金额),
        yaxis_index=0,
        color="#5793f3",
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="90+净坏账率"),
    )
    .extend_axis(
        yaxis=opts.AxisOpts(
            name="90+净坏账率",
            type_="value",
            min_=0,
            max_=0.014,
            position="right",
            axisline_opts=opts.AxisLineOpts(
                linestyle_opts=opts.LineStyleOpts(color="#d14a61")
            ),
            axislabel_opts=opts.LabelOpts(formatter="{value}"),
        )
    )
)
line = (
    Line()
    .add_xaxis(list(final1.index.values.astype(str)))
    .add_yaxis(
        "90+净坏账率",
        list(final1['90+净坏账率']),
        yaxis_index=1,
        color="#675bba",
        label_opts=opts.LabelOpts(is_show=False),
    )
)
bar.overlap(line).render()
结果图

需求2: 计算60天和90天的入催率

根据账单周期计算入催金额
# 60天账期数据
df4 = df3[df3['账期'] == 60]
fn1 = df4.groupby('账单季度')[['账单金额']].sum()
fn1.columns = ['60天到期账单金额']
fn2 = df4.groupby('账单季度')[['未收金额2']].sum()
fn2.columns = ['60天到期入催金额']
​
# 90天账期数据
df4 = df3[df3['账期'] == 90]
fn3 = df4.groupby('账单季度')[['账单金额']].sum()
fn3.columns = ['90天到期账单金额']
fn4 = df4.groupby('账单季度')[['未收金额2']].sum()
fn4.columns = ['90天到期入催金额']
合并计算入催率
# 60天入催率
final2['60天账期入催率'] = round(final2['60天到期入催金额'] / final2['60天到期账单金额'], 3)
# 90天入催率
final2['90天账期入催率'] = round(final2['90天到期入催金额'] / final2['90天到期账单金额'], 3)
final2
结果可视化
# 可视化绘图
line = (
    Line()
    .add_xaxis(list(final1.index.values.astype(str)))
    .add_yaxis(
        "60天账期入催率",
        list(final2['60天账期入催率']),
        yaxis_index=0,
        color="#675bba",
        label_opts=opts.LabelOpts(is_show=False),
    )
    .set_global_opts(
    title_opts=opts.TitleOpts(title="不同账期入催率"),
    )
    .add_xaxis(list(final1.index.values.astype(str)))
    .add_yaxis(
        "90天账期入催率",
        list(final2['90天账期入催率']),
        yaxis_index=0,
        color="#d14a61",
        label_opts=opts.LabelOpts(is_show=False),
    )
)
line.render()
结果图

需求3: 回收帐单数(不是被催收后的回收率)

数据过滤

筛选出未收金额等于0(到统计时没有待偿还的金额)切已经到期的数据(到期就会被记录)

df5 = df3[(df3['未收金额2'] == 0) & (df3['是否到期'] == 1)]
df5
cut分箱历史逾期天数
df5['历史逾期天数'] = pd.cut(
    df5['历史逾期天数'], 
    bins=[-999, 0, 5, 10, 15, 20, 30, 60, 90, 999], 
    labels=['0', '1-5', '6-10', '11-15', '16-20', '21-30', '31-60', '61-90', '91+']
)
final3 = df5.groupby('历史逾期天数')[['账期']].count()
final3.columns = ['回收账单数']
final3
结果可视化
ydata = final3['回收账单数'].values.tolist()
bar = (
    Bar()
    .add_xaxis(list(final3.index.values.tolist()))
    .add_yaxis("收回账单数",ydata,yaxis_index=0,color="#675bba")
    .set_global_opts(
    title_opts=opts.TitleOpts(title="不同逾期天数的已收回账单数"),
    )
)
bar.render()
结果图

业务解读

  1. 从数据中看出,在2018年Q2季度之前,运营策略比较保守,坏账金额和入催率都比较低,

  2. 2018年Q2之后,有可能是由于运营策略调整,给更多的人放贷,但坏账率和入催率均在3%一下,在合理范围内

  3. 不同逾期天数收回账单的数据看,30天内能收回绝大部分账单


原文地址:https://blog.csdn.net/m0_60916732/article/details/143083442

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!