使用toad库进行机器学习评分卡全流程

1 加载数据

导入模块

import pandas as pd
from sklearn.metrics import roc_auc_score,roc_curve,auc
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import numpy as np
import math
import xgboost as xgb
import toad
from toad.plot import bin_plot, badrate_plot
from matplotlib import pyplot as plt
from sklearn.preprocessing import StandardScaler
from toad.metrics import KS, F1, AUC
from toad.scorecard import ScoreCard

加载数据

 # 加载数据
df = pd.read_csv('scorecard.txt')
print(df.info())
df.head()

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

df.describe()

在这里插入图片描述

数据划分

feature_list = list(df.columns)
feature_drop = ['bad_ind','uid','samp_type']
for lt in feature_drop:feature_list.remove(lt)
df_dev = df[df['samp_type']=='dev']
df_val = df[df['samp_type']=='val']
df_off = df[df['samp_type']=='off']
print(feature_list)
print('dev',df_dev.shape)
print('val',df_val.shape)
print('off',df_off.shape)

在这里插入图片描述

简单数据分析

toad.detector.detect(df)

在这里插入图片描述
toad库能够同时处理数值型数据和分类型数据。由于没有缺失值,我们不用进行数据填充。

2 特征筛选

使用缺失率、IV和相关系数进行特征筛选。

# 根据缺失值、IV和相关系数进行特征筛选
dev_slt, drop_slt = toad.selection.select(df_dev, df_dev['bad_ind'], empty=0.7, iv=0.03, corr=0.7, return_drop=True, exclude=feature_drop)
print('keep:', dev_slt.shape,';drop empty:',drop_slt['empty'].shape,';drop iv:',drop_slt['iv'].shape,';drop_corr:',drop_slt['corr'].shape)

keep: (65304, 12) ;drop empty: (0,) ;drop iv: (1,) ;drop_corr: (0,)

3 卡方分箱

使用toad库,能够对所有特征切分节点,然后进行分箱

# 使用卡方分箱
# 使用卡方分箱
cmb = toad.transform.Combiner()
cmb.fit(dev_slt, dev_slt['bad_ind'], method='chi', min_samples=0.05, exclude=feature_drop)
bins = cmb.export()
print(bins)

{‘td_score’: [0.7989831262724624], ‘jxl_score’: [0.4197048501965005], ‘mj_score’: [0.3615303943747963], ‘zzc_score’: [0.4469861520889339], ‘zcx_score’: [0.7007847486465795], ‘person_info’: [-0.2610139784946237, -0.1286774193548387, -0.0537175627240143, 0.013863440860215, 0.0626602150537634, 0.078853046594982], ‘finance_info’: [0.0476190476190476], ‘credit_info’: [0.02, 0.04, 0.11], ‘act_info’: [0.1153846153846154, 0.141025641025641, 0.1666666666666666, 0.2051282051282051, 0.2692307692307692, 0.358974358974359, 0.3974358974358974, 0.5256410256410257]}

调整分箱

绘制Bivar图,观察该特征分享后是否单调性,不满足单调性需要调整分箱。

# 绘制bivar图,调整分箱
# 根据节点设置分箱
dev_slt2 = cmb.transform(dev_slt)
val2 = cmb.transform(df_val[dev_slt.columns])
off2 = cmb.transform(df_off[dev_slt.columns])# 观察分箱后的图像-act_info
bin_plot(dev_slt2, x='act_info', target='bad_ind')
bin_plot(val2, x='act_info', target='bad_ind')
bin_plot(off2, x='act_info', target='bad_ind')

开发样本
在这里插入图片描述
测试样本
在这里插入图片描述
验证样本
在这里插入图片描述
我们能看到前3箱出现上下波动,与整体的单调递减趋势不符,所以进行分箱合并。

# 没有呈现单调性,需要进行合并
bins['act_info']

[0.1153846153846154,
0.141025641025641,
0.1666666666666666,
0.2051282051282051,
0.2692307692307692,
0.358974358974359,
0.3974358974358974,
0.5256410256410257]

将其调整为3个分箱

adj_bins = {'act_info':[0.1666666666666666,0.358974358974359]}
cmb.set_rules(adj_bins)dev_slt3 = cmb.transform(dev_slt)
val3 = cmb.transform(df_val[dev_slt.columns])
off3 = cmb.transform(df_off[dev_slt.columns])# 观察分箱后的图像
bin_plot(dev_slt3, x='act_info', target='bad_ind')
bin_plot(val3, x='act_info', target='bad_ind')
bin_plot(off3, x='act_info', target='bad_ind')

开发样本
在这里插入图片描述
测试样本
在这里插入图片描述
验证样本
在这里插入图片描述

查看负样本占比关联图

# 绘制负样本占比关联图
data = pd.concat([dev_slt3, val3, off3], join='inner')
badrate_plot(data, x='samp_type', target='bad_ind', by='act_info')

在这里插入图片描述

其他特征分箱

person_info特征分箱

bins['person_info']

[-0.2610139784946237,
-0.1286774193548387,
-0.0537175627240143,
0.013863440860215,
0.0626602150537634,
0.078853046594982]

adj_bins = {'person_info':[-0.2610139784946237,-0.1286774193548387,-0.0537175627240143,0.078853046594982]}
cmb.set_rules(adj_bins)dev_slt3 = cmb.transform(dev_slt)
val3 = cmb.transform(df_val[dev_slt.columns])
off3 = cmb.transform(df_off[dev_slt.columns])data = pd.concat([dev_slt3, val3, off3], join='inner')
badrate_plot(data, x='samp_type', target='bad_ind', by='person_info')
# 观察分箱后的图像
bin_plot(dev_slt3, x='person_info', target='bad_ind')
bin_plot(val3, x='person_info', target='bad_ind')
bin_plot(off3, x='person_info', target='bad_ind')
bins['person_info']

负样本占比关联图
在这里插入图片描述
开发样本
在这里插入图片描述
测试样本
在这里插入图片描述
验证样本
在这里插入图片描述

credit_info特征

# credit_info
badrate_plot(data, x='samp_type', target='bad_ind', by='credit_info')# 观察分箱后的图像
bin_plot(dev_slt3, x='credit_info', target='bad_ind')
bin_plot(val3, x='credit_info', target='bad_ind')
bin_plot(off3, x='credit_info', target='bad_ind')
bins['credit_info']

负样本占比
在这里插入图片描述
开发样本
在这里插入图片描述
测试样本
在这里插入图片描述
验证样本
在这里插入图片描述
其他特征分箱分为两个,所以不需要单独看。

4 WOE编码,并验证IV

# WOE编码,验证IV
woet = toad.transform.WOETransformer()
dev_woe = woet.fit_transform(dev_slt3, dev_slt3['bad_ind'], exclude=feature_drop)
val_woe = woet.transform(val3[dev_slt3.columns])
off_woe = woet.transform(off3[dev_slt3.columns])
data_woe = pd.concat([dev_woe, val_woe,off_woe])
# 计算PSI
psi_df = toad.metrics.PSI(dev_woe,val_woe).sort_values(0)
psi_df = psi_df.reset_index()
psi_df = psi_df.rename(columns={'index':'feature', 0:'psi'})
psi_df

在这里插入图片描述
一般删除psi大于0.1的特征,但我们这里调整为0.13。

psi_013 = list(psi_df[psi_df.psi<0.13].feature)
# psi_013.extend(feature_drop)
data_psi = data_woe[psi_013]
dev_woe_psi = dev_woe[psi_013]
val_woe_psi = val_woe[psi_013]
off_woe_psi = off_woe[psi_013]
print(data_psi.shape)

(95806, 11)

由于卡方分箱后部分变量的IV降低,且整体相关程度增大,需要再次筛选特征。

dev_woe_psi2,drop_lst = toad.selection.select(dev_woe_psi, dev_woe_psi['bad_ind'], empty=0.6, iv=0.001, corr=0.5, return_drop=True, exclude=feature_drop)
print('keep:',dev_woe_psi2.shape,';drop empty:',drop_lst['empty'].shape,';drop iv:',drop_lst['iv'].shape,';drop corr:',drop_lst['corr'].shape)

keep: (65304, 7) ;drop empty: (0,) ;drop iv: (4,) ;drop corr: (0,)

5 再次特征筛选

使用逐步回归进行特征筛选,这里为线性回归模型,并选择KS作为评价指标。

# 特征筛选,使用逐步回归法进行筛选
dev_woe_psi_stp = toad.selection.stepwise(dev_woe_psi2,dev_woe_psi2['bad_ind'],exclude=feature_drop,direction='both',criterion='ks',estimator='ols',intercept=False)
val_woe_psi_stp = val_woe_psi[dev_woe_psi_stp.columns]
off_woe_psi_stp = off_woe_psi[dev_woe_psi_stp.columns]
data_woe_psi_std = pd.concat([dev_woe_psi_stp, val_woe_psi_stp, off_woe_psi_stp])
print(data_woe_psi_std.shape)
print(data_woe_psi_std.columns)

(95806, 6)
Index([‘uid’, ‘samp_type’, ‘bad_ind’, ‘credit_info’, ‘act_info’,
‘person_info’],
dtype=‘object’)

6 模型训练

定义逻辑回归模型和XGBoost模型的函数

# 进行模型训练
def lr_model(x,y,valx,valy,offx,offy,c):model = LogisticRegression(C=c, class_weight='balanced')model.fit(x,y)# devy_pred = model.predict_proba(x)[:,1]fpr_dev, tpr_dev, _ = roc_curve(y,y_pred)dev_ks = abs(fpr_dev-tpr_dev).max()print('dev_ks:',dev_ks)y_pred = model.predict_proba(valx)[:,1]fpr_val, tpr_val, _ = roc_curve(valy,y_pred)val_ks = abs(fpr_val-tpr_val).max()print('val_ks:',val_ks)y_pred = model.predict_proba(offx)[:,1]fpr_off, tpr_off, _ = roc_curve(offy,y_pred)off_ks = abs(fpr_off-tpr_off).max()print('off_ks:',off_ks)plt.plot(fpr_dev, tpr_dev, label='dev')plt.plot(fpr_val, tpr_val, label='val')plt.plot(fpr_off, tpr_off, label='off')plt.plot([0,1],[0,1],'k--')plt.xlabel('False positive rate')plt.ylabel('True positive rate')plt.title('lr model ROC Curve')plt.legend(loc='best')plt.show()# xgb模型
def xgb_model(x,y,valx,valy,offx,offy):model = xgb.XGBClassifier(learning_rate=0.05,n_estimators=400,max_depth=2,min_child_weight = 1,subsample=1,nthread=-1,scale_pos_weight=1,random_state=1,n_jobs=-1,reg_lambda=300)model.fit(x,y)# devy_pred = model.predict_proba(x)[:,1]fpr_dev, tpr_dev, _ = roc_curve(y,y_pred)dev_ks = abs(fpr_dev-tpr_dev).max()print('dev_ks:',dev_ks)y_pred = model.predict_proba(valx)[:,1]fpr_val, tpr_val, _ = roc_curve(valy,y_pred)val_ks = abs(fpr_val-tpr_val).max()print('val_ks:',val_ks)y_pred = model.predict_proba(offx)[:,1]fpr_off, tpr_off, _ = roc_curve(offy,y_pred)off_ks = abs(fpr_off-tpr_off).max()print('off_ks:',off_ks)plt.plot(fpr_dev, tpr_dev, label='dev')plt.plot(fpr_val, tpr_val, label='val')plt.plot(fpr_off, tpr_off, label='off')plt.plot([0,1],[0,1],'k--')plt.xlabel('False positive rate')plt.ylabel('True positive rate')plt.title('xgb model ROC Curve')plt.legend(loc='best')plt.show()

定义模型函数的使用函数,在函数中分别进行正向调用和逆向调用,验证模型的效果上限。如逆向模型训练集KS值明显小于正向模型训练集KS值,说明当前时间外样本分布与开发样本差异较大,需要重新划分样本集。

start_train(data_woe_psi_std,target='bad_ind', exclude=feature_drop)

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

  • XGBoost的效果没有好于逻辑回归模型,因此特征不需要进行再组合;
  • 反向lr模型的结果没有显著好于正向调用的结果,因此该模型在当前特征空间下没有优化的空间;
  • lr正向训练和反向训练的ks值在5%以内,所以不需要调整时间稳定性较差的变量。
    计算训练集、测试集和验证集的ks、F1和auc值

7 计算指标评估模型,生成模型报告

 # 分别计算ks,F1和auc值
target = 'bad_ind'
lt = list(data_woe_psi_std.columns)
for i in feature_drop:lt.remove(i)devv = data_woe_psi_std[data_woe_psi_std['samp_type']=='dev']
vall = data_woe_psi_std[data_woe_psi_std['samp_type']=='val']
offf = data_woe_psi_std[data_woe_psi_std['samp_type']=='off']
x,y=devv[lt], devv[target]
valx,valy = vall[lt],vall[target]
offx,offy = offf[lt], offf[target]
lr = LogisticRegression()
lr.fit(x,y)prob_dev = lr.predict_proba(x)[:,1]
print('训练集')
print('F1:',F1(prob_dev,y))
print('KS:',KS(prob_dev,y))
print('AUC:',AUC(prob_dev,y))prob_val = lr.predict_proba(valx)[:,1]
print('测试集')
print('F1:',F1(prob_val,valy))
print('KS:',KS(prob_val,valy))
print('AUC:',AUC(prob_val,valy))prob_off = lr.predict_proba(offx)[:,1]
print('验证集')
print('F1:',F1(prob_off,offy))
print('KS:',KS(prob_off,offy))
print('AUC:',AUC(prob_off,offy))# 验证集的模型PSI和特征PSI
print('模型PSI:', toad.metrics.PSI(prob_dev,prob_off))
print('特征PSI:\n', toad.metrics.PSI(x,offx).sort_values(0))

训练集
F1: 0.02962459026532253
KS: 0.40665138719594446
AUC: 0.7683462756870743
测试集
F1: 0.03395860284605433
KS: 0.3709553758048945
AUC: 0.723771920780572
验证集
F1: 0
KS: 0.38288372897789186
AUC: 0.7447410631197128
模型PSI: 0.3372146799079187
特征PSI:
credit_info 0.098585
act_info 0.124820
person_info 0.127210
dtype: float64

生成验证集的ks报告

toad.metrics.KS_bucket(prob_off, offy, bucket=15, method='quantile')

在这里插入图片描述

8 生成评分卡

# 用toad生成评分卡
card = ScoreCard(combiner=cmb,transer=woet, C=0.1,class_weight='balanced',base_score=600,base_odds=35,pdo=60,rate=2)
card.fit(x,y)
final_card = card.export(to_frame=True)
final_card

在这里插入图片描述
对训练集、测试集和验证集应用评分卡,预测用户的分数。这里要注意要传入原始数据,不要传入woe编码转化后和分箱后的数据。

# 评分卡进行预测
df_dev['score'] = card.predict(df_dev)
df_val['score'] = card.predict(df_val)
df_off['score'] = card.predict(df_off)
plt.hist(df_dev['score'], label = 'dev',color='blue', bins = 10)
plt.legend()

在这里插入图片描述

plt.hist(df_val['score'], label = 'val',color='green', bins = 10)
plt.legend()

在这里插入图片描述

plt.hist(df_off['score'], label = 'off',color='orange', bins = 10)
plt.legend()

在这里插入图片描述
三组评分数据在一个图中

plt.hist(df_dev['score'], label = 'dev',color='blue', bins = 10)
plt.hist(df_off['score'], label = 'off',color='orange', bins = 10)
plt.hist(df_val['score'], label = 'val',color='green', bins = 10)
plt.legend()

在这里插入图片描述

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

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

相关文章

心理咨询预约管理系统javaweb医院挂号jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 心理咨询预约管理系统javaweb MVC模式&#xff0c;普…

活动发布会邀请媒体6步走

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 邀请媒体参加活动发布会对信息的传播&#xff0c;企业品牌建设有诸多的好处&#xff0c;今天就与大家分享下邀请媒体参加活动报道的6个步骤&#xff1a; 1. 策划与准备&#xff1a; -明…

构建Docker容器监控系统(Cadvisor +InfluxDB+Grafana)

目录 案例概述 Cadvisor InfluxDBGrafana 1.1、 Cadvisor 1.2、InfluxDB 1.3、Grafana 1.4、监控组件架构 1.5、开始部署 安装docker-ce 阿里云镜像加速器 创建自定义网络 创建influxdb容器 案例概述 Docker作为目前十分出色的容器管理技术&#xff0c;得到大量企业…

基于Java+SpringBoot+Vue的企业客户信息反馈平台设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

STM32 4G学习(二)

特性参数 ATK-IDM750C是正点原子开发的一款高性能4G Cat1 DTU产品&#xff0c;支持移动4G、联通4G和电信4G手机卡。 它以高速率、低延迟和无线数传作为核心功能&#xff0c;可快速解决应用场景下的无线数传方案。 它支持TCP/UDP/HTTP/MQTT/DNS/RNDIS/NTP协议&#xff0c;支持…

Clion开发Stm32之存储模块(W25Q64)驱动编写

前言 涵盖之前文章: Clion开发STM32之HAL库SPI封装(基础库) W25Q64驱动 头文件 #ifndef F1XX_TEMPLATE_MODULE_W25Q64_H #define F1XX_TEMPLATE_MODULE_W25Q64_H#include "sys_core.h" /* Private typedef ---------------------------------------------------…

STM32入门——定时器

内容为江科大STM32标准库学习记录 TIM简介 TIM&#xff08;Timer&#xff09;定时器定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时&…

广州VR制作 | 利用VR元宇宙平台开展林地管理培训的优势

在林业领域&#xff0c;实地调查是获取准确数据和深入了解森林生态的重要手段。然而&#xff0c;传统的实地调查方法存在诸多问题&#xff0c;如时间成本高、人力物力投入大、安全风险高等。为了解决这些教学痛点&#xff0c;我们引入了虚拟现实(VR)技术&#xff0c;通过虚拟林…

【JVM】 垃圾回收篇——自问自答(1)

Q什么是垃圾&#xff1a; 运行程序中&#xff0c;没用任何指针指向的对象。 Q为什么需要垃圾回收&#xff1f; 内存只分配&#xff0c;不整理回收&#xff0c;迟早会被消耗完。 内存碎片的整理&#xff0c;为新对象腾出空间 没有GC程序无法正常进行。 Q 哪些区域有GC&#…

react学习

1.react安装 2.react的使用 3.方法说明 4.初始化react脚手架 5.在脚手架中使用react 6.JSX 7.JSX需要注意的点 8.在JSX中使用JS 需要注意的点 9.条件渲染 10.列表渲染 11.样式处理 12.react组件 两种创建方式: 函数创建: 类组件: 13.事件 事件绑定 事件对象 14.有状态组件和…

2023年华数杯数学建模B题思路代码分析 - 不透明制品最优配色方案设计

# 1 赛题 B 题 不透明制品最优配色方案设计 日常生活中五彩缤纷的不透明有色制品是由着色剂染色而成。因此&#xff0c;不透明 制品的配色对其外观美观度和市场竞争力起着重要作用。然而&#xff0c;传统的人工配色 存在一定的局限性&#xff0c;如主观性强、效率低下等。因此…

CentOS7 启动谷歌浏览器 java+Selenium+chrome+chromedriver

前言&#xff1a;自己想使用该技术实现自动化抓取音乐&#xff0c;目前在window上运行成功&#xff0c;需要在Linux Centos服务上跑&#xff0c;配置上出现了许多问题&#xff0c;特此记录。 参考文档&#xff1a;CentOS7 安装Seleniumchromechromedriverjava_远方丿的博客-CSD…

使用gitee创建远程maven仓库

1. 创建一个项目作为远程仓库 2. 打包项目发布到远程仓库 id随意&#xff0c;url是打包到哪个文件夹里面 在需要打包的项目的pom中添加 <distributionManagement><repository><id>handsomehuang-maven</id><url>file:D:/workspace/java/2023/re…

Prometheus-各种exporter

文章目录 一、 nginx-prometheus-exporter1 nginx 配置1.1 Nginx 模块支持1.2 Nginx 配置文件配置2 部署 nginx-prometheus-exporter2.1 二进制方式部署2.1.1 解压部署2.1.2 配置 systemd2.1.3 添加 prometheus 的配置2.1.4 Dashborad2.2 docker-compose 方式部署3 可配置的指标…

回归预测 | MATLAB实现POA-CNN-BiGRU鹈鹕算法优化卷积双向门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现POA-CNN-BiGRU鹈鹕算法优化卷积双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现POA-CNN-BiGRU鹈鹕算法优化卷积双向门控循环单元多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现POA-CNN-BiGRU鹈鹕…

.Net C# 免费PDF合成软件

最近用到pdf合成&#xff0c;发现各种软件均收费啊&#xff0c;这个技术非常简单&#xff0c;别人写好的库一大把&#xff0c;这里用到了PDFsharp&#xff0c;项目地址Home of PDFsharp and MigraDoc Foundation 软件下载地址 https://download.csdn.net/download/g313105910…

【redis】能ping通虚拟机但是端口无法访问

问题 虚拟机上有redis&#xff0c;能ping通虚拟机的ip&#xff0c;但是idea连不上虚拟机里的redis&#xff0c;telnet已启动的redis6379端口失败 基本情况 虚拟机网络模式是NAT模式&#xff0c;linux防火墙firewalld已关闭&#xff0c;没有iptables&#xff0c;主机和虚拟机…

Windows下安装Sqoop

Windows下安装Sqoop 一、Sqoop简介二、Sqoop安装2.1、Sqoop官网下载2.2、Sqoop网盘下载2.3、Sqoop安装&#xff08;以version&#xff1a;1.4.7为例&#xff09;2.3.1、解压安装包到 D:\bigdata\sqoop\1.4.7 目录2.3.2、新增环境变量 SQOOP_HOME2.3.3、环境变量 Path 添加 %SQO…

【LeetCode】剑指 Offer Ⅱ 第3章:字符串(7道题) -- Java Version

题库链接&#xff1a;https://leetcode.cn/problem-list/e8X3pBZi/ 题目解决方案剑指 Offer II 014. 字符串中的变位词双指针 数组模拟哈希表 ⭐剑指 Offer II 015. 找到字符串中所有字母异位词双指针 数组模拟哈希表 ⭐剑指 Offer II 016. 不含重复字符的最长子字符串双指针…

现代C++中的从头开始深度学习:【5/8】卷积

一、说明 在上一个故事中&#xff0c;我们介绍了机器学习的一些最相关的编码方面&#xff0c;例如 functional 规划、矢量化和线性代数规划。 现在&#xff0c;让我们通过使用 2D 卷积实现实际编码深度学习模型来开始我们的道路。让我们开始吧。 二、关于本系列 我们将学习如何…