评分卡模型(二)基于评分卡模型的用户付费预测

小P:小H,这个评分卡是个好东西啊,那我这想要预测付费用户,能用它吗

小H:尽管用~

(本想继续薅流失预测的,但想了想这样显得我的业务太单调了,所以就改成了付费预测。哈哈~)

数据探索

导入相关库

import pandas as pd
import numpy as np
import math
from sklearn.model_selection import train_test_split,cross_val_score  # 数据分区库
import xgboost as xgb
from sklearn.metrics import accuracy_score, auc, confusion_matrix, f1_score, \precision_score, recall_score, roc_curve, roc_auc_score, precision_recall_curve  # 导入指标库
from imblearn.over_sampling import SMOTE  # 过抽样处理库SMOTE
import matplotlib.pyplot as plt
import prettytable  # 导入表格库
from pandas_profiling import ProfileReport # 自动eda
import sweetviz as sv # 自动eda
import matplotlib.pyplot as plt
from matplotlib import ticker
import seaborn as sns
import os
import shutil
import toad
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
from toad.plot import  bin_plot, badrate_plot
from sklearn.preprocessing import LabelEncoder
from collections import defaultdict
from sklearn.linear_model import LogisticRegression
from scipy.stats import scoreatpercentile
from toad.scorecard import ScoreCard
%matplotlib inline
pd.set_option('display.max_columns', None) # 显示所有列
# 风格设置
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文
sns.set(style="ticks") # 设置风格# 导入自定义模块
import sys
sys.path.append("/Users/heinrich/Desktop/Heinrich-blog/数据分析使用手册")
from keyIndicatorMapping import *

数据准备

上述自定义模块keyIndicatorMapping如果有需要的同学可关注公众号HsuHeinrich,回复【数据挖掘-自定义函数】自动获取~

以下数据如果有需要的同学可关注公众号HsuHeinrich,回复【数据挖掘-评分卡02】自动获取~

# 读取数据
raw_data = pd.read_csv('train_set.csv')  # 读取数据文件
raw_data.head()

# 生成好坏定义列
raw_data['target']=1-raw_data['y'] # 1表示bad客户(即未购买),0表示dood客户(即购买了)
raw_data.drop('y', axis=1, inplace=True)
# 定义id列
ids_col = ['ID']
# 定义排除的特征列:一般包括ID列、日期列、目标列
ex_lis = ['ID', 'target']
# 定义排除列不含y
ex_lis_noy = ['ID']
# 定义y列
y_col = 'target'
# 查看变量统计信息
toad.detector.detect(raw_data)

# 查看变量价值信息
toad.quality(raw_data.drop(ex_lis_noy, axis=1), y_col, iv_only=True)

# 数据审查
na_count = raw_data.isnull().any().sum() # 缺失值样本量
n_samples, n_features = raw_data.shape  # 总样本量,总特征数
print('samples: {0}| features: {1} | na count: {2}'.format(n_samples, n_features, na_count))
samples: 25317| features: 18 | na count: 0

特征工程

样本拆分

# 样本拆分:训练样本、测试样本
train, test = train_test_split(raw_data, test_size=.3, random_state=0)

特征初筛

# 缺失率>0.7,IV<0.1(一般认为iv低于0.1的特征区分度较弱),相关系数>0.7
train_s, drop_lst= toad.selection.select(train, train[y_col], empty=0.7, iv=0.1, corr=0.7, return_drop=True, exclude=ex_lis)
print("keep:", train_s.shape[1],  "drop empty:", len(drop_lst['empty']), "drop iv:", len(drop_lst['iv']),  "drop corr:", len(drop_lst['corr']))
keep: 14 drop empty: 0 drop iv: 4 drop corr: 0

变量分箱

# 得到切分节点 卡方分箱
combiner = toad.transform.Combiner()
combiner.fit(train_s, train_s[y_col], method='chi',min_samples=0.05, exclude=ex_lis)
# 导出箱的节点
bins = combiner.export()
# 变量分箱
train_t = combiner.transform(train_s)
test_t = combiner.transform(test[train_s.columns])
print(bins)
{'age': [], 'job': [['student', 'retired'], ['unemployed', 'management'], ['self-employed', 'admin.', 'unknown', 'technician'], ['services', 'housemaid'], ['blue-collar', 'entrepreneur']], 'balance': [-45, 61, 874, 1693], 'housing': [['no'], ['yes']], 'contact': [['cellular'], ['telephone'], ['unknown']], 'day': [5, 10, 17, 21, 28], 'month': [['mar', 'dec', 'sep', 'oct', 'apr', 'feb'], ['jan', 'aug', 'nov', 'jun', 'jul', 'may']], 'duration': [75, 114, 206, 366, 654], 'campaign': [2, 3, 4, 5, 8], 'pdays': [9, 211], 'previous': [1, 3], 'poutcome': [['success', 'other', 'failure', 'unknown']]}

WOE编码

w = toad.transform.WOETransformer()
#对WOE的值进行转化,映射到原数据集上。对训练集用fit_transform,测试集用transform.
train_w = w.fit_transform(train_t, train_t[y_col], exclude=ex_lis)
test_w = w.transform(test_t[train_t.columns])
data = pd.concat([train_w, test_w])

二次筛选

# psi筛选
np.seterr(divide='ignore',invalid='ignore') # 防止0/0产生的invalid value
psi_df = toad.metrics.PSI(train_w, test_w).sort_values(0)
psi_df = psi_df.reset_index()
psi_df = psi_df.rename(columns = {'index': 'feature', 0: 'psi'})
col_keep = list(set(list(psi_df[psi_df.psi<0.02].feature)).union(set(ex_lis))) # 保留低psi特征和不参与特征的并集
train_psi = train_w[col_keep]print("keep:", train_psi.shape[1])
keep: 14
# 因为特征WOE编码后,部分变量的IV变低,且整体相关性变大。故再次进行特征筛选
train_psi_s2, drop_lst = toad.selection.select(train_psi,train_psi[y_col],empty=0.7,   iv=0.1, corr=0.7, return_drop=True, exclude=ex_lis)
print("keep:", train_psi_s2.shape[1],  "drop empty:", len(drop_lst['empty']),  "drop iv:", len(drop_lst['iv']),  "drop corr:", len(drop_lst['corr']))
keep: 9 drop empty: 0 drop iv: 4 drop corr: 1
# 逐步回归筛选变量
train_stp = toad.selection.stepwise(train_psi_s2,  train_psi_s2[y_col],  exclude=ex_lis,  direction='both',   criterion='aic',  estimator='ols',intercept=False)  print("keep:", train_stp.shape[1])
keep: 9

生成最终数据集

test_stp = test_w[train_stp.columns]
data_finall = pd.concat([train_stp, test_stp])
print(data_finall.shape)
(25317, 9)

数据建模

模型训练

# 样本拆分
X, y = data_finall.drop(ex_lis, axis=1), data_finall[y_col]
X_train, y_train = train_stp.drop(ex_lis, axis=1), train_stp[y_col]
X_test, y_test = test_stp.drop(ex_lis, axis=1), test_stp[y_col]
# 模型训练
model_lr = LogisticRegression(C=0.1, class_weight='balanced')
model_lr.fit(X_train, y_train)
LogisticRegression(C=0.1, class_weight='balanced')

模型估

  • 核心指标评估
model_confusion_metrics(model_lr, X_test, y_test, 'test')
model_core_metrics(model_lr, X_test, y_test, 'test')
confusion matrix for test+----------+--------------+--------------+
|          | prediction-0 | prediction-1 |
+----------+--------------+--------------+
| actual-0 |     5336     |     1362     |
| actual-1 |     152      |     746      |
+----------+--------------+--------------+
core metrics for test+-------+----------+-----------+--------+-------+-------+
|  auc  | accuracy | precision | recall |   f1  |   ks  |
+-------+----------+-----------+--------+-------+-------+
| 0.881 |  0.801   |   0.972   | 0.797  | 0.876 | 0.631 |
+-------+----------+-----------+--------+-------+-------+
  • 模型区分与排序能力评估
fig = plt.figure(figsize=(18,12))
plt.subplot(221)
plot_roc(model_lr, X_test, y_test, name='test')
plt.subplot(222)
plot_ks(model_lr, X_test, y_test, name='test')
plt.subplot(223)
plot_pr(model_lr, X_test, y_test, name='test')
plt.subplot(224)
plot_lift(model_lr, X_test, y_test, name='test')
plt.tight_layout()
plt.show()

  • 模型泛化能力评估
fig = plt.figure(figsize=(18,12))
plt.subplot(221)
plot_cv_box(model_lr, X_test, y_test, name='test')
plt.subplot(222)
plot_learning_curve(model_lr, X_test, y_test, name='test')
plt.tight_layout()
plt.show()

  • 模型稳定性评估
# 模型PSI:小于10%,则无需更新模型;10%-20%, 需检查变化原因,加强监控频率;大于20%,则模型需要迭代
mpsi = model_psi(model_lr, X_train, X_test)
print('模型PSI:',mpsi)
模型PSI: 0.20931994818791816
  • 模型捕获报告评估
# 模型捕获率报告
y_test_prob = model_lr.predict_proba(X_test)[:, 1]
df_capture = capture_table(y_test_prob, y_test)
df_capture.columns=['KS', '负样本个数', '正样本个数', '负样本累计个数', '正样本累计个数', '捕获率', '负样本占比']
df_capture

结果展示

评分卡

# 计算odds
bad_total=raw_data[y_col].sum()
good_total=raw_data.shape[0]-bad_total
odds=round(bad_total/good_total,2)
base_odds=round(good_total/bad_total,0)
print('bad_total:{0}\ngood_total:{1}\nodds:{2}\nbase_odds:{3}\n'.format(bad_total,good_total,odds,base_odds))
bad_total:22356
good_total:2961
odds:7.55
base_odds:0.0
# 生成评分报告 # 注意ScoreCard方法里求解A=												

评分卡模型(二)基于评分卡模型的用户付费预测相关推荐

  1. 差分方程模型(二):蛛网模型

    差分方程模型系列博文: 差分方程模型(一):模型介绍与Z变换 差分方程模型(二):蛛网模型 差分方程模型(三): 预测商品销售量 差分方程模型(四):遗传模型 目录 1 问题提出 2 模型假设:供应函 ...

  2. 逻辑回归模型小结--基于评分模型

    逻辑回归模型 一.优点和不足 二.对变量的要求 当用逻辑回归模型来构建评分模型时,入模变量需要满足以下条件: 1.变量间不存在较强的线性相关性和多重共线性.可在单变量分析和多变量分析过程中予以解决,删 ...

  3. 计算机软件模型改进,基于改进Kano模型的服务优化研究_樊根耀.docx 计算机软件及应用...

    第34卷第5期重庆理工大学学报(自然科学)2020年5月Vol. 34 No. 5Journal of Chongqing University of Technology (Natural Scie ...

  4. Django模型(二)

    Django模型(二) 文章目录 Django模型(二) 一.字段查询 1.查看mysql数据库日志 二.条件运算符 1.查询等 2.模糊查询 3.空查询 4. 范围查询 5. 比较查询 6).日期查 ...

  5. (二)使用预定义模型 QStringListModel例子

    目录: (一) Qt Model/View 的简单说明 .预定义模型 (二)使用预定义模型 QstringListModel例子 (三)使用预定义模型QDirModel的例子 (四)Qt实现自定义模型 ...

  6. Visformer: The Vision-friendly Transformer实现transformer和基于卷积的模型中的设计特性

    Visformer: The Vision-friendly Transformer 视觉友好型transformer 摘要 近年来,将transformer模块应用于视觉问题迅速发展.虽然一些研究人 ...

  7. 机动目标跟踪——目标模型概述(匀速运动CV模型)

    机动目标跟踪--目标模型概述 原创不易,路过的各位大佬请点个赞 WX: ZB823618313 机动目标跟踪--目标模型概述 机动目标跟踪--目标模型概述 1. 对机动目标跟踪的理解 2. 目标模型概 ...

  8. 差分方程模型(一):模型介绍与Z变换

    差分方程模型系列: 差分方程模型(一):模型介绍与Z变换 差分方程模型(二):蛛网模型 差分方程模型(三): 预测商品销售量 差分方程模型(四):遗传模型 差分方程是包含未知函数的差分及自变数的方程. ...

  9. 基于Tensorflow的神经网络解决用户流失概率问题

    沙韬伟,苏宁易购高级算法工程师. 曾任职于Hewlett-Packard.滴滴出行. 数据学院特邀讲师. 主要研究方向包括风控.推荐和半监督学习.目前专注于基于深度学习及集成模型下的用户行为模式的识别 ...

最新文章

  1. 智源发布 | 大规模并行训练效率提升神器 TDS
  2. Linux关闭防火墙、SELinux
  3. Android 出现“此用户无法使用开发者选项”问题
  4. V-rep对UR3机械臂仿真路径规划
  5. zcmu1133(dfs+判重)
  6. 负数如何归一化处理_小白的图像处理入门(一)
  7. java零碎要点013---JAVA执行js_java执行JavaScript_java执行js引擎不能识别document浏览器内置对象解决办法
  8. [2011诺贝我物理奖]超新星与暗能量的收现
  9. c java python go 哪种编程语言接近编程的本质_一图看懂编程语言迁移模式:终点站是Python、Go、JS...
  10. linux技术属于什么系,什么云计算技术?想学好这个必须了解的!
  11. vue 如何处理两个组件异步问题_Vue异步组件处理路由组件加载状态的解决方案...
  12. Android编码规范
  13. ios开发swift_10位Swift和iOS开发大师
  14. 计算机联锁 2x2,二乘二取二计算机联锁系统.pdf
  15. 维基百科语料库训练词向量
  16. 双十一最值得入手什么,盘点几款最实用的数码好物
  17. 驱动工程师面试题汇编
  18. [渝粤教育] 温州职业技术学院 纳税筹划 参考 资料
  19. 关于微信小程序自定义Picker样式的picker-view
  20. ati能备份linux格式吗,ATI备份TIB文件的另类用法

热门文章

  1. Java eclipse控制台按任意键返回主菜单 控制台清屏
  2. 数据库——数据库表和表的操作
  3. linux下制作linux系统的安装U盘
  4. 【UNR #6 B】机器人表演(DP)
  5. violate 修饰的用法
  6. You are using pip version 8.1.2, however version 21.3.1 is available pip安装docker-compose版本问题解决
  7. Abp Vnext修改密码强度
  8. python中set option_python的set_option选择
  9. 陈学智升任VMware全球副总裁、大中华区总裁,面临四个挑战
  10. jsTree插件简介(一)