【金融风控项目-07】:业务规则挖掘案例

文章目录

  • 1.规则挖掘简介
  • 2 规则挖掘案例
    • 2.1 案例背景
    • 2.2 规则挖掘流程
    • 2.3 特征衍生
    • 2.4 训练决策树模型
    • 2.5 利用结果划分分组

1.规则挖掘简介

  • 两种常见的风险规避手段:
    • AI模型
    • 规则
  • 如何使用规则进行风控
    • **使用一系列逻辑判断(以往从职人员的经验)**对客户群体进行区分, 不同群体逾期风险有显著差别
    • 比如:多头借贷是否超过一定的数量,设定一个值,如果超过这个值则拒绝借贷
    • 采用一条规则就可以将用户进行分组,可以将用户划分到高风险组,在高风险组中的用户则直接进行拒绝;如果不在高风险组就进入到下一条规则的判断
  • 规则和AI模型的优点:
    • 规则:可以快速使用,便于业务人员理解,但是判断相对简单粗暴,单一维度不满条件直接拒绝
    • AI模型:开发周期长,对比使用规则更复杂,但是更加灵活,用于对于风控精度要求更高的场景。
  • 可以通过AI模型辅助建立规则引擎,决策树很适合规则挖掘的场景。

2 规则挖掘案例

2.1 案例背景

某互联网公司拥有多个业务板块,每个板块下都有专门的贷款产品。

  • 外卖平台业务的骑手可以向平台申请“骑手贷”

  • 电商平台业务的商户可以申请“网商贷”

  • 网约车业务的司机可以向平台申请“司机贷”

公司有多个类似的场景,共用相同的规则引擎及申请评分卡,贷款人都是该公司的兼职人员
近期发现,“司机贷”的逾期率较高

  1. 整个金融板块30天逾期率为1.5%
  2. 司机贷”产品的30天逾期达到了5%

期望解决方案:

  • 现有的风控架构趋于稳定
  • 希望快速开发快速上线,解决问题
    • 尽量不使用复杂的方法
    • 考虑使用现有数据挖掘出合适的业务规则

数据:
在这里插入图片描述

  • 常用的数据分为两类:数值型数据和类别型数据
  • 原始数据中有些数据需要进行处理,有些数据不需要进行处理

2.2 规则挖掘流程

加载数据

import pandas as pd
import numpy as np
data = pd.read_excel('../data/rule_data.xlsx')
data.head()

在这里插入图片描述

data.shape

在这里插入图片描述

# 查看有多少类别
data.class_new.unique()

在这里插入图片描述

data.info()

在这里插入图片描述

  • create_dt - 有很多缺失值,需要进行处理

2.3 特征衍生

原始数据的特征太少,考虑在原始特征基础上衍生出一些新的特征来,将特征分成三类分别处理

  • 数值类型变量:按照id分组后,采用多种方式聚合,衍生新特征
    • 最终得到每个特征按照id分组聚合之后的df
  • 分类类型变量,按照id分组后,聚合查询条目数量,衍生新特征
  • 其它:日期时间类型,是否违约(标签),用户评级等不做特征衍生处理
# 原始数据中有19个特征
# org_list - 不用于进行特征衍生的列
# agg_list - 数值类型的特征,需要进行分组聚合
# count_list - 类别型特征,需要进行分组计数
org_list = ['uid','create_dt','oil_actv_dt','class_new','bad_ind']
agg_list = ['oil_amount','discount_amount','sale_amount','amount','pay_amount','coupon_amount','payment_coupon_amount']
count_list = ['channel_code','oil_code','scene','source_app','call_source']
  • 对原始数据进行copy,防止操作出错,需要重新加载数据
df = data[org_list].copy()
df[agg_list] = data[agg_list].copy()
df[count_list] = data[count_list].copy()
# 查看数据是不是又缺失值
df.isna().sum()

在这里插入图片描述

  • 缺失值填充
# 按照uid和create_dt进行降序排序
df.sort_values(['uid','create_dt'],ascending = False)
  • 对creat_dt做补全,用oil_actv_dt来填补
# 传入两个值
ef time_isna(x,y):if str(x) == 'NaT':x = yreturn x
df2 = df.sort_values(['uid','create_dt'],ascending = False)
# apply返回一个由自定函数返回值组成的series
# axis = 1 将df2的行送入到series中 ,df传入的虽然是行,但是结构仍然是series
df2['create_dt'] = df2.apply(lambda x: time_isna(x.create_dt,x.oil_actv_dt),axis = 1)
# df2.apply(lambda x: time_isna(x.create_dt,x.oil_actv_dt),axis = 1)

在这里插入图片描述

  • 截取申请时间和放款时间不超过6个月的数据(考虑数据时效性)
# 两个时间相减得到的是timedelta类型的数据
# 需要通过x.days获取到具体的不带days的数据
df2['dtn'] = (df2.oil_actv_dt - df2.create_dt).apply(lambda x :x.days)
df = df2[df2['dtn']<180]
df.head()

在这里插入图片描述

  • 将用户按照id编号排序,并保留最近一次申请时间,确保每个用户有一条记录(每个样本送入到模型中都是一条数据)
base = df[org_list] # 不进行特征衍生的数据
base['dtn'] = df['dtn']
base = base.sort_values(['uid','create_dt'],ascending = False)
base = base.drop_duplicates(['uid'],keep = 'first')
base.shape 

在这里插入图片描述
在这里插入图片描述

  • 特征值衍生
    • 对连续统计型变量进行函数聚合
    • 方法包括对历史特征值计数、求历史特征值大于0的个数、求和、求均值、求最大/小值、求最小值、求方差、求极差等
gn = pd.DataFrame() # 创建一个空的dataframe
for i in agg_list: # 遍历需要进行特征衍生的特征# 按照uid进行分组,groupby()应用apply函数传入的是每个组的df# 获取长度tp = df.groupby('uid').apply(lambda df:len(df[i])).reset_index()tp.columns = ['uid',i + '_cnt']if gn.empty:gn = tpelse:gn = pd.merge(gn,tp,on = 'uid',how = 'left')#求历史特征值大于0的个数tp = df.groupby('uid').apply(lambda df:np.where(df[i]>0,1,0).sum()).reset_index()tp.columns = ['uid',i + '_num']if gn.empty:gn = tpelse:gn = pd.merge(gn,tp,on = 'uid',how = 'left')#求和tp = df.groupby('uid').apply(lambda df:np.nansum(df[i])).reset_index()tp.columns = ['uid',i + '_tot']if gn.empty:gn = tpelse:gn = pd.merge(gn,tp,on = 'uid',how = 'left')#求平均值tp = df.groupby('uid').apply(lambda df:np.nanmean(df[i])).reset_index()tp.columns = ['uid',i + '_avg']if gn.empty:gn = tpelse:gn = pd.merge(gn,tp,on = 'uid',how = 'left')#求最大值tp = df.groupby('uid').apply(lambda df:np.nanmax(df[i])).reset_index()tp.columns = ['uid',i + '_max']if gn.empty:gn = tpelse:gn = pd.merge(gn,tp,on = 'uid',how = 'left')#求最小值tp = df.groupby('uid').apply(lambda df:np.nanmin(df[i])).reset_index()tp.columns = ['uid',i + '_min']if gn.empty:gn = tpelse:gn = pd.merge(gn,tp,on = 'uid',how = 'left')#求方差tp = df.groupby('uid').apply(lambda df:np.nanvar(df[i])).reset_index()tp.columns = ['uid',i + '_var']if gn.empty:gn = tpelse:gn = pd.merge(gn,tp,on = 'uid',how = 'left')#求极差tp = df.groupby('uid').apply(lambda df:np.nanmax(df[i]) -np.nanmin(df[i]) ).reset_index()tp.columns = ['uid',i + '_ran']if gn.empty:gn = tpelse:gn = pd.merge(gn,tp,on = 'uid',how = 'left')
  • 查看衍生结果
gn.columns

在这里插入图片描述

  • 对dstc_lst变量求distinct个数
    • 对类别型的变量,按照uid进行分组之后,去重之后进行计数
gc = pd.DataFrame()
for i in count_list:tp = df.groupby('uid').apply(lambda df: len(set(df[i]))).reset_index()tp.columns = ['uid',i + '_dstc']if gc.empty:gc = tpelse:gc = pd.merge(gc,tp,on = 'uid',how = 'left')
  • 将三个部分的df进行拼接
fn = pd.merge(base,gn,on= 'uid')
fn = pd.merge(fn,gc,on= 'uid') 
fn.shape
  • merge过程中可能会出现缺失情况,填充缺失值
fn = fn.fillna(0)
fn.head(100)

2.4 训练决策树模型

  • 选择数据,训练模型
x = fn.drop(['uid','oil_actv_dt','create_dt','bad_ind','class_new'],axis = 1)
y = fn.bad_ind.copy()
from sklearn import tree
dtree = tree.DecisionTreeRegressor(max_depth = 2,min_samples_leaf = 500,min_samples_split = 5000)
dtree = dtree.fit(x,y)
  • 输出决策树图像
import pydotplus 
from IPython.display import Image
from six import StringIO
# import os
# os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'
# with open("dt.dot", "w") as f:
#     tree.export_graphviz(dtree, out_file=f)
dot_data = StringIO() # 开辟内存空间
# dtree - 指定模型
# out_file - 指定空间
# feature_name - 指定特征矩阵x的列名 x.columns
# class_name - 指定y标签列的列名
tree.export_graphviz(dtree, out_file=dot_data,feature_names=x.columns,class_names=['bad_ind'],filled=True, rounded=True,special_characters=True)
dot_data.getvalue()
graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) 

在这里插入图片描述
在这里插入图片描述

2.5 利用结果划分分组

group_1 = fn.loc[(fn.amount_tot>48077.5)&(fn.amount_cnt>3.5)].copy()
group_1['level'] = 'past_A'
group_2 = fn.loc[(fn.amount_tot>48077.5)&(fn.amount_cnt<=3.5)].copy()
group_2['level'] = 'past_B'
group_3 = fn.loc[fn.amount_tot<=48077.5].copy()
group_3['level'] = 'past_C'
  • 如果拒绝past_C类客户,则可以使整体负样本占比下降至0.021
  • 如果将past_B也拒绝掉,则可以使整体负样本占比下降至0.012
  • 至于实际对past_A、past_B、past_C采取何种策略,要根据利率来做线性规划,从而实现风险定价

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/61165.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实时监控,智能分析:输电线路多目视频监控装置提升运维效率

在快速变迁的现代社会中&#xff0c;安全监控技术已成为各行各业安全管理体系的核心组成部分。无论是工厂生产线的安全保障&#xff0c;城市治安的维护&#xff0c;还是偏远区域电力巡检的顺利进行&#xff0c;都离不开高效且智能的监控解决方案。 在高压输电线路的监测领域&am…

【MCU】GD32H7定时器使用外部时钟源

1、定时器可以使用系统内部的mcuclk&#xff0c;也可以通过管脚使用外部输入的时钟源 2、GD32H7怎么使用外部的源来驱动定时器呢 3、GD32H7通用定时器的框图如下&#xff1a; 这是官方手册上的图&#xff0c;不得不说&#xff0c;画的不够详细&#xff0c;只是一个大概的框图…

vue下载后端提供的文件/播放音频文件

下载文件 doc 接口js文件里加一行这个responseType: ‘arraybuffer’, js文件 export function (data) {return request({url: "XXX",method: "post",data: data,baseURL: " ",responseType: arraybuffer,}); }vue文件 const time{"date…

IDEA2023 SpringBoot整合Web开发(二)

一、SpringBoot介绍 由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。SpringBoot提供了一种新的编程范式&#xff0c;可以更加快速便捷…

英伟达AI超大规模组网平台方案

英伟达GPU&#xff1a;AI超大规模组网 "英伟达&#xff0c;引领GPU技术革新&#xff0c;持续加速AI超大规模组网进程。自2024年起&#xff0c;英伟达每2年将推出一代新型GPU架构&#xff0c;如今的Blackwell芯片已投入生产。展望未来&#xff0c;2025年&#xff0c;我们将…

计算机网络:概述知识点及习题练习

网课资源&#xff1a; 湖科大教书匠 1、因特网 网络之间需要路由器进行互联&#xff0c;互联网是网络的网络&#xff0c;因特网是最大的互联网&#xff0c;连接到网络的设备称为主机&#xff0c;一般不叫路由器为主机。 因特网发展&#xff1a;ARPNET->三级结构因特网&am…

makefile速通

makefile速通 文章目录 makefile速通1.基础显式规则隐含规则%*通配符 赋值 伪目标CFLAGS 2.函数wildcardpatsubst 3.项目实例 1.基础 显式规则 目标文件&#xff1a;依赖文件 [TAB] 指令隐含规则 % 任意* 所有通配符 符号含义$^所有依赖文件$所有目标文件$<所有依赖文…

分数加减

#include <stdio.h> #include <stdlib.h>// 求最大公因数 int gcd(int a, int b) {return b 0? a : gcd(b, a % b); }// 化简分数 void simplify(int *num, int *den) {int g gcd(*num, *den);*num / g;*den / g;if (*den < 0) {*num * -1;*den * -1;} }//…

微分方程(Blanchard Differential Equations 4th)中文版Exercise 5.1

For the competing species population model d x d t = 2 x (

Misc_01转二维码(不是二进制)

例题ctfhub/隐写v2.0 打开是一张图片 文件分离得到zip&#xff0c;爆破密码得到7878 打开得到0和1&#xff0c; !!!不是二进制转图片&#xff0c;直接是二维码 缩小能看到 000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000…

Django数据库迁移与反向迁移处理方案分析

Django数据库迁移与反向迁移处理方案分析 目录 &#x1f4dd; Django数据库迁移的基本概念与应用⚙️ 如何实现Django的数据库反向迁移&#x1f504; Django数据库迁移的高级技巧与优化&#x1f6e0;️ 其他数据库迁移实现方案与应用场景⚖️ 不同迁移方案的优缺点分析 1. &a…

如何修改网络ip地址:一步步指南‌

在当今这个数字化时代&#xff0c;网络已成为我们日常生活与工作中不可或缺的一部分。无论是浏览网页、在线办公还是享受流媒体服务&#xff0c;稳定的网络连接和适当的IP地址管理都是确保良好体验的关键。然而&#xff0c;出于隐私保护、绕过地理限制或测试网络环境等需要&…

STL——vector(1)

博客ID&#xff1a;LanFuRenC系列专栏&#xff1a;C语言重点部分 C语言注意点 C基础 Linux 数据结构 C注意点 今日好题 声明等级&#xff1a;黑色->蓝色->红色 欢迎新粉加入&#xff0c;会一直努力提供更优质的编程博客&#xff0c;希望大家三连支持一下啦 目录 尾…

魔乐社区平台下载书生模型

魔乐社区平台 魔乐社区&#xff08;Modelers&#xff09;是一个提供多样化、开源模型的平台&#xff0c;旨在促进开发者和研究人员在最先进的模型和流行应用上进行协作。 书生浦语模型地址&#xff1a; https://modelers.cn/models/Intern/internlm2_5-1_8b-chat Git下载命令&…

Data governance, data literacy, and data quality management:A literature review

注意&#xff1a;这并不是正式发表的论文&#xff0c;只是一篇用来交作业的文章 Note: This is not a formally published paper, but just an essay for homework. Abstract With the rise of the data era, data governance, data literacy, and data quality management h…

ReactNative的环境搭建

写在前面 React Native (RN) 是一个由 Facebook 开发的开源框架&#xff0c;用于构建跨平台的移动应用程序。它允许开发者使用 JavaScript 和 React 来创建原生 iOS 和 Android 应用。RN 的出现极大地简化了移动应用的开发过程&#xff0c;使得开发者可以更快速、更高效地构建…

iOS 18 导航栏插入动画会导致背景短暂变白的解决

问题现象 在最新的 iOS 18 系统中,如果我们执行导航栏的插入动画,可能会造成导航栏背景短暂地变为白色: 如上图所示:我们分别向主视图和 Sheet 弹出视图的导航栏插入了消息,并应用了动画效果。可以看到,前者的导航栏背景会在消息插入那一霎那“变白”,而后者则没有任何…

GNU与开源:塑造数字世界的自由基石

引言 在信息技术的浩瀚星空中&#xff0c;GNU&#xff08;GNUs Not Unix&#xff09;项目犹如一颗璀璨的星辰&#xff0c;引领着开源运动的浪潮&#xff0c;深刻影响着全球软件开发的格局。自1983年由理查德斯托尔曼&#xff08;Richard Stallman&#xff09;创立以来&#xf…

【Swift】可选类型

文章目录 什么是可选类型&#xff1f;nilif 语句以及强制解析可选绑定隐式解析可选类型 什么是可选类型&#xff1f; Swift 的可选&#xff08;Optional&#xff09;类型&#xff0c;用于处理值缺失的情况。可选表示"那儿有一个值&#xff0c;并且它等于 x “或者"那…

SPP:空间金字塔池化

今天水一篇博客&#xff0c;讲讲SPP池化结构&#xff1b;那这是个什么东西呢&#xff1f;它的作用又是什么呢&#xff1f;在了解它之前我们先简单了解一下大部分的神经网络&#xff1b; 引入&#xff1a; 在大部分的神经网络中&#xff0c;都将神经网络分为Backbone主干网络、…