【金融风控项目-07】:业务规则挖掘案例
文章目录
- 1.规则挖掘简介
- 2 规则挖掘案例
- 2.1 案例背景
- 2.2 规则挖掘流程
- 2.3 特征衍生
- 2.4 训练决策树模型
- 2.5 利用结果划分分组
1.规则挖掘简介
- 两种常见的风险规避手段:
- AI模型
- 规则
- 如何使用规则进行风控
- **使用一系列逻辑判断(以往从职人员的经验)**对客户群体进行区分, 不同群体逾期风险有显著差别
- 比如:多头借贷是否超过一定的数量,设定一个值,如果超过这个值则拒绝借贷
- 采用一条规则就可以将用户进行分组,可以将用户划分到高风险组,在高风险组中的用户则直接进行拒绝;如果不在高风险组就进入到下一条规则的判断
- 规则和AI模型的优点:
- 规则:可以快速使用,便于业务人员理解,但是判断相对简单粗暴,单一维度不满条件直接拒绝
- AI模型:开发周期长,对比使用规则更复杂,但是更加灵活,用于对于风控精度要求更高的场景。
- 可以通过AI模型辅助建立规则引擎,决策树很适合规则挖掘的场景。
2 规则挖掘案例
2.1 案例背景
某互联网公司拥有多个业务板块,每个板块下都有专门的贷款产品。
-
外卖平台业务的骑手可以向平台申请“骑手贷”
-
电商平台业务的商户可以申请“网商贷”
-
网约车业务的司机可以向平台申请“司机贷”
公司有多个类似的场景,共用相同的规则引擎及申请评分卡,贷款人都是该公司的兼职人员
近期发现,“司机贷”的逾期率较高
- 整个金融板块30天逾期率为1.5%
- 司机贷”产品的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采取何种策略,要根据利率来做线性规划,从而实现风险定价
相关文章:
【金融风控项目-07】:业务规则挖掘案例
文章目录 1.规则挖掘简介2 规则挖掘案例2.1 案例背景2.2 规则挖掘流程2.3 特征衍生2.4 训练决策树模型2.5 利用结果划分分组 1.规则挖掘简介 两种常见的风险规避手段: AI模型规则 如何使用规则进行风控 **使用一系列逻辑判断(以往从职人员的经验)**对客户群体进行区…...
退款成功订阅消息点击后提示订单不存在
问题表现: 退款成功发送的小程序订阅消息点击进入后提示订单不存在。 修复方法: 1.打开文件app/services/message/notice/RoutineTemplateListService.php 2.找到方法sendOrderRefundSuccess 3.修改图中红圈内的链接地址 完整方法代码如下 /*** 订…...
实验一 顺序结构程序设计
《大学计算机﹣C语言版》实验报告 实验名称 实验一 顺序结构程序设计 实验目的 (1)掌握C语言中常量和变量的概念。 (2)掌握C语言中常见的数据类型。 (3)掌握C语言中变量的定义和赋值方法。 …...
Elasticsearch搜索流程及原理详解
Elasticsearch搜索流程及原理详解 1. Elasticsearch概述1.1 简介1.2 核心特性1.3 应用场景2. Elasticsearch搜索流程2.1 搜索请求的发起2.2 查询的执行2.3 结果的聚合与返回3. Elasticsearch原理详解3.1 倒排索引3.2 分布式架构3.3 写入流程3.4 读取流程4. 技术细节与操作流程4…...
芯片之殇——“零日漏洞”(文后附高通64款存在漏洞的芯片型号)
芯片之殇——“零日漏洞”(文后附高通64款存在漏洞的芯片型号) 本期是平台君和您分享的第113期内容 前一段时间,高通公司(Qualcomm)发布安全警告称,提供的60多款芯片潜在严重的“零日漏洞”,芯片安全再一次暴露在大众视野。 那什么是“零日漏洞”?平台君从网上找了一段…...
【gitlab】gitlabrunner部署
1、下载镜像 docker pull gitlab/gitlab-runner:latest 2、启动gitrunner容器 docker run -d --name gitlab-runner --restart always \ -v /root/gitrunner/config:/etc/gitlab-runner \ ///gitlab-runner的配置目录,挂载在宿主机上方便修改,里面有config.…...
Flink监控checkpoint
Flink的web界面提供了一个选项卡来监控作业的检查点。这些统计信息在任务终止后也可用。有四个选项卡可以显示关于检查点的信息:概述(Overview)、历史(History)、摘要(Summary)和配置(Configuration)。下面依次来看这几个选项。 Overview Tab Overview选项卡列出了以…...
Ribbon 入门实战指南
Ribbon 是 Netflix 开发的一个开源项目,用于实现客户端负载均衡功能。它在微服务架构中广泛使用,并且是 Spring Cloud 生态中的重要组成部分。本文将带你从基础入门,逐步掌握如何在 Spring Cloud 项目中使用 Ribbon 实现客户端负载均衡。 1 负…...
uniapp: 微信小程序包体积超过2M的优化方法(主包从2.7M优化到1.5M以内)
一、问题描述 在使用uniapp进行微信小程序开发时,经常会遇到包体积超过2M而无法上传: 二、解决方案 目前关于微信小程序分包大小有以下限制: 整个小程序所有分包大小不超过 30M(服务商代开发的小程序不超过 20M) 单个…...
【百日算法计划】:每日一题,见证成长(026)
题目 给定一个包含正整数、加()、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。 表达式仅包含非负整数,, - ,,/ 四种运算符和空格 。 整数除法仅保留整数部分。 * * 示例 1: 输入: “32X2” 输出: 7 import…...
【大模型】prompt实践总结
文章目录 怎么才算是好的prompt设计准则基本原则精炼原则(奥卡姆剃刀准则)具体原则真实操作技巧指定角色增加fewshots列表化代码化强调需求真实迭代大模型优化情形任务的定义和评估标准似乎可以再明确一下出现了一些之前没有考虑过的特殊情况,可以重新组织语言优化Prompt来处…...
在Qt(以及C++)中, 和 * 是两个至关重要的符号--【雨露均沾】
在Qt(以及C)中,& 和 * 是两个至关重要的符号,它们用于处理引用和指针。我们将逐个解释这两个符号,并提供简单示例来说明它们的用法。 1. 引用(&) 定义: 引用是一种别名,它不…...
本地部署Apache Answer搭建高效的知识型社区并一键发布到公网流程
文章目录 前言1. 本地安装Docker2. 本地部署Apache Answer2.1 设置语言选择简体中文2.2 配置数据库2.3 创建配置文件2.4 填写基本信息 3. 如何使用Apache Answer3.1 后台管理3.2 提问与回答3.3 查看主页回答情况 4. 公网远程访问本地 Apache Answer4.1 内网穿透工具安装4.2 创建…...
Ubuntu常见命令
关于export LD_LIBRARY_PATHcmake默认地址CMakelists.txt知识扩充/home:挂载新磁盘到 /home 子目录 关于export LD_LIBRARY_PATH 程序运行时默认的依赖库的位置包括lib, /usr/lib ,/usr/local/lib 通过命令export LD_LIBRARY_PATHdesired_path:$LD_LIBRARY_PATH追加…...
网络安全领域的最新动态和漏洞信息
网络安全领域的最新动态和漏洞信息涉及多个方面,以下是对这些信息的详细归纳: 一、网络安全领域最新动态世界互联网大会乌镇峰会召开2024年11月19日至22日,以“拥抱以人为本、智能向善的数字未来——携手构建网络空间命运共同体”为主题的202…...
华为开源自研AI框架昇思MindSpore应用案例:人体关键点检测模型Lite-HRNet
如果你对MindSpore感兴趣,可以关注昇思MindSpore社区 一、环境准备 1.进入ModelArts官网 云平台帮助用户快速创建和部署模型,管理全周期AI工作流,选择下面的云平台以开始使用昇思MindSpore,获取安装命令,安装MindSpo…...
每日OJ题_牛客_天使果冻_递推_C++_Java
目录 牛客_天使果冻_递推 题目解析 C代码 Java代码 牛客_天使果冻_递推 天使果冻 描述: 有 n 个果冻排成一排。第 i 个果冻的美味度是 ai。 天使非常喜欢吃果冻,但她想把最好吃的果冻留到最后收藏。天使想知道前 x个果冻中,美味…...
独立站干货:WordPress主机推荐
WordPress作为全球最受欢迎的独立站建设平台,提供了灵活性和强大的功能,使得建站变得简单而高效。本文将为您详细介绍WordPress建站的流程,并推荐几款实测后觉得好用的主机商。 WordPress建站流程 域名注册 首先需要注册一个域名,…...
支持多种快充协议和支持多种功能的诱骗取电协议芯片
汇铭达XSP15是一款应用于手持电动工具、智能家居、显示器、音箱等充电方案的大功率快充协议芯片,支持最大功率100W给设备快速充电,大大缩短了充电时间。芯片支持通过UART串口发送电压/电流消息供其它芯片读取。支持自动识别连接的是电脑或是充电器。支持…...
Android中常见内存泄漏的场景和解决方案
本文讲解Android 开发中常见内存泄漏场景及其解决方案,内容包括代码示例、原因分析以及最佳实践建议。 1. 静态变量导致的内存泄漏 静态变量的生命周期与应用进程一致,如果静态变量持有了对 Activity 或其他大对象的引用,就可能导致内存泄漏…...
AI 短剧系统快速部署,轻量化搭建,小白也能轻松运营落地
当下 AI 短剧创业已成热门轻资产赛道,很多个人创业者、中小团队想入局,却卡在开发周期长、技术门槛高、后台复杂难运营等问题。 一套AI 短剧系统支持极速快速部署,无需专业技术功底,搭建流程极简,运营门槛极低…...
如何用3分钟搞定视频字幕提取?揭秘这款本地化硬字幕提取神器
如何用3分钟搞定视频字幕提取?揭秘这款本地化硬字幕提取神器 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检测、字…...
Claude智能优化器:提升大模型工具调用准确性的工程实践
1. 项目概述与核心价值最近在折腾大语言模型应用开发时,我一直在思考一个问题:如何让像Claude这样的顶级AI助手,在回答复杂问题时,能更稳定、更聪明地调用外部工具和函数?直接调用API,模型有时会“犯懒”或…...
2026年选系统门窗,认准专业工厂的三大理由
系统门窗作为现代建筑节能与安全的重要组成,在2026年迎来了更高的性能需求。面对市场上琳琅满目的门窗品牌,消费者如何做出选择?一个关键标准是:是否选择专业工厂生产的系统门窗。专业工厂意味着更高的产品品质、更严格的工艺标准…...
免费一键去图片水印的App有哪些?免费去图片水印软件推荐,2026实测好用工具盘点
免费一键去图片水印的App有哪些?免费去图片水印软件推荐,2026实测好用工具盘点 在日常用图的过程中,水印几乎是绕不开的麻烦——从网络下载的素材到平台截图,从拍摄叠加的文字标注到品牌Logo,各种形式的水印让图片用起…...
交完Essay才发现Turnitin更新了AI检测?我是这么应对的
上学期我的一个朋友被约谈了。 教授发邮件说:"你的Essay和AI生成文本相似度过高,请来办公室解释。" 他确实用了AI——谁没用呢——但他也认真改写了好几遍。问题是,Turnitin在2025年更新了AI检测模型,现在它不只看词汇…...
modbus 512 断线重连 db browser for sqlite
断线重连 private async Task HeartbeatLoopAsync(CancellationToken token) {// 监工一直循环干活,直到工长喊停工(token.IsCancellationRequested)while (!token.IsCancellationRequested){try{// 每隔一段时间检查一次(最少20…...
超声引导手术中的‘呼吸’难题:我们如何用体外标记法搞定肝部超声-CT的实时配准?
超声与CT影像实时配准:破解呼吸运动干扰的临床实战方案 在肝癌射频消融或穿刺活检手术中,影像引导的精准度直接决定治疗效果。超声凭借其实时性成为首选引导工具,但图像质量局限常需与高分辨率的CT影像融合。这一过程中,呼吸运动导…...
PICAXE单片机驱动DS18B20温度传感器:从硬件连接到数据处理
1. 项目概述:用PICAXE玩转DS18B20数字温度传感器如果你手头有一块PICAXE单片机,想快速实现一个温度监测项目,那么DS18B20这颗数字温度传感器绝对是你的绝佳拍档。它只需要一根数据线就能和MCU通信,抗干扰能力强,还能通…...
构建本地AI记忆系统:五大记忆库与心跳回忆机制详解
1. 项目概述:一个让AI助手真正“记住你”的本地记忆系统 如果你用过OpenClaw、Claude Code或者任何AI助手,肯定遇到过这样的场景:昨天刚跟它详细讨论了一个项目方案,今天再问,它要么含糊其辞,要么又得从头解…...
