前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[1111]python scorecardpy(评分卡)使用

[1111]python scorecardpy(评分卡)使用

作者头像
周小董
发布于 2022-04-13 07:09:51
发布于 2022-04-13 07:09:51
3.4K00
代码可运行
举报
文章被收录于专栏:python前行者python前行者
运行总次数:0
代码可运行

文章目录

简介

随着互联网在传统金融和电子商务领域的不断渗透,风控+互联网的融合也对传统的风控提出了新的要求和挑战。以评分卡为例,互联网形态下的评分卡需要面临更多维数据、更实时数据、更异常数据的挑战。因此,懂得互联网业务下的风控评分卡已经成为互联网风控从业人员的新要求。

Python中信贷评分卡中常用的两个库有“scorecardpy”和“Toad”。其中scorecardpy是由谢士晨博士开发,该软件包是R软件包评分卡的python版本。它的目标是通过提供一些常见任务的功能,使传统信用风险计分卡模型的开发更加轻松有效。该包的功能及对应的函数如下:

  • 数据划分(split_df)
  • 变量选择(iv, var_filter)
  • 变量按权重(woe)分箱(woebin, woebin_plot, woebin_adj, woebin_ply)
  • 评分转换(scorecard, scorecard_ply)
  • 模型评估(perf_eva, perf_psi)

在命令台中使用以下代码,从PYPI中下载scorecardpy的最新发布版本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install scorecardpy

也可以使用以下指令从GitHub上下载的最新版本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install git+git://github.com/shichenxie/scorecardpy.git

注意,以上安装需要Pandas版本高于(包括)0.25.0,否则下载会失败!

使用

首先,导入germancredit数据。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import scorecardpy as sc
dat = sc.germancredit()

dt_s = sc.var_filter(dat, y="creditability")

这个函数可以根据指定的条件筛选变量,例如IV值、缺失率、一致性等,函数的参数如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def var_filter(dt, y, x=None, iv_limit=0.02, missing_limit=0.95, 
               identical_limit=0.95, var_rm=None, var_kp=None, 
               return_rm_reason=False, positive='bad|1')

var_rm:强制删除变量的名称 var_kp:强制保留变量的名称 return_rm_reason:是否返回每个变量被删除的原因 positive:坏样本的标签

数据划分

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
train, test = sc.split_df(dt_s, 'creditability').values()

def split_df(dt, y=None, ratio=0.7, seed=186)

该函数的ratio默认为0.7,即按照7:3对数据集进行分割。ratio可以随意进行设置,比如[0.5,0.2]

变量分箱

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bins = sc.woebin(dt_s, y="creditability")

def woebin(dt, y, x=None, 
           var_skip=None, breaks_list=None, special_values=None, 
           stop_limit=0.1, count_distr_limit=0.05, bin_num_limit=8, 
           # min_perc_fine_bin=0.02, min_perc_coarse_bin=0.05, max_num_bin=8, 
           positive="bad|1", no_cores=None, print_step=0, method="tree",
           ignore_const_cols=True, ignore_datetime_cols=True, 
           check_cate_num=True, replace_blank=True, 
           save_breaks_list=None, **kwargs):

返回的是每个变量的分箱结果组成的字典。

woebin支持决策树分箱、卡方分箱、自定义分箱,默认的WOE值计算是用坏样本率/好样本率,这个可以通过参数postive进行调整。如果某一箱只有好样本或者坏样本,会对缺失的类别赋予0.99进行调整,方便计算woe值。重要参数含义如下:

var_skip:指定不需要分箱的变量。 breaks_list:分割点的List。对分箱进行调整的时候用。可以进行自定义分箱 special_values:指定单独的箱。 count_distr_limit:分箱结果中最小占比。默认0.05 stop_limit:当IV值的增加值小于stop_limit或者卡方值小于qchisq(1-stoplimit, 1)时停止分割。 bin_num_limit:最大分箱数。 method:分箱方法,可以有"tree" or “chimerge”。 ignore_const_cols:是否忽略常数列。 check_cate_num:检查分类变量中类别数是否大于50。 replace_blank:将空值替换为None。

sc.woebin_plot()可以画出变量分箱之后的Bi_variate图,这里的坏样本率图展示了每一箱的好坏样本数、样本占比、坏样本率,比较清晰明了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.woebin_plot(bins)

分箱调整

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
breaks_adj = sc.woebin_adj(dt_s, "creditability", bins) 

def woebin_adj(dt, y, bins, adj_all_var=False, special_values=None, method="tree", save_breaks_list=None, count_distr_limit=0.05)

重要参数的含义:

adj_all_var:是否显示woe变量的单调性。

其它参数和woebin()函数一样,这里没有深入研读调整分箱的代码,而且运行过程中有报错。猜测调整的方向是坏样本率单调。 此外也可以手动进行分箱调整:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
breaks_adj = {
    'age.in.years': [26, 35, 40],
    'other.debtors.or.guarantors': ["none", "co-applicant%,%guarantor"]
}
bins_adj = sc.woebin(dt_s, y="creditability", breaks_list=breaks_adj)

woe转换

分箱之后需要对变量的原始值进行转换,将变量值转化成woe值,后续使用变量的WOE值入模进行训练。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
train_woe = sc.woebin_ply(train, bins_adj)
test_woe = sc.woebin_ply(test, bins_adj)

模型建立

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
y_train = train_woe.loc[:,'creditability']
X_train = train_woe.loc[:,train_woe.columns != 'creditability']
y_test = test_woe.loc[:,'creditability']
X_test = test_woe.loc[:,train_woe.columns != 'creditability']

# logistic regression ------
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(penalty='l1', C=0.9, solver='saga', n_jobs=-1)
lr.fit(X_train, y_train)
# lr.coef_
# lr.intercept_

# predicted proability
train_pred = lr.predict_proba(X_train)[:,1]
test_pred = lr.predict_proba(X_test)[:,1]

模型评估

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
train_perf = sc.perf_eva(y_train, train_pred, title = "train")
test_perf = sc.perf_eva(y_test, test_pred, title = "test")
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def perf_eva(label, pred, title=None, groupnum=None, plot_type=["ks", "roc"], show_plot=True, positive="bad|1", seed=186)

perf_eva()函数可以从KS、AUC、Lift曲线、PR曲线评估模型的效果。可以通过plot_type参数控制评估方法,可以选"ks", “lift”, “roc”, “pr”。s

评分映射

模型评估之后,需要对概率进行映射,转换成评分卡得分。得分包括每个客户的最终得分和单个变量的得分。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
card = sc.scorecard(bins_adj, lr, X_train.columns)

scorecard()返回一个字典,对应的是基础分和每个变量的得分。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def scorecard(bins, model, xcolumns, points0=600, odds0=1/19, pdo=50, basepoints_eq0=False)

scorecard()函数的参数含义如下:

bins:分箱信息。woebin()返回的结果。 model:模型对象。 points0:基础分,默认为600。 odds:好坏比,默认为1:19 pdo:比率翻番的倍数,默认为50。 basepoints_eq0:如果为True,则将基础分分散到每个变量中。

评分稳定性评估–PSI

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.perf_psi(
  score = {'train':train_score, 'test':test_score},
  label = {'train':y_train, 'test':y_test}
)

总结:对于想学习建模的新手来说,一套有效的脚本能够帮助快速建立一张评分卡。本人在自学的过程中看了几乎网上所有能找到的评分卡脚本,比较实用的还是之前github上的半自动建模包,自己也尝试写了一个评分卡脚本,终于算是入门完成。scorecardpy库虽然封装得很好,但是一旦运行过程中出现问题,调试起来仍然是件很麻烦的事情。对比起来,本人觉得半自动化建模的包更具有实用性,将链接附在下方,感兴趣者可以学习。 建立一个评分卡模型的代码包

运行示例

以下实例向您展示了如何开发一个通用的信用风险评分卡项目:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Traditional Credit Scoring Using Logistic Regression
# 基于逻辑回归的传统信用回归
import scorecardpy as sc

# data prepare ------
# 数据准备 -----
# load germancredit data
# 加载germancredit(德国信贷)数据
dat = sc.germancredit()

# filter variable via missing rate, iv, identical value rate
# 通过数据缺失率、IV值、相同值来过滤变量
dt_s = sc.var_filter(dat, y="creditability")

# breaking dt into train and test
# 将DataFrame分成训练集和测试集
train, test = sc.split_df(dt_s, 'creditability').values()

# woe binning ------
# 根据woe值进行分箱
bins = sc.woebin(dt_s, y="creditability")
# sc.woebin_plot(bins)

# binning adjustment
# 分箱调整
# # adjust breaks interactively
# # 有交互地进行重组调整
# breaks_adj = sc.woebin_adj(dt_s, "creditability", bins) 
# # or specify breaks manually
# # 或者手动进行重组调整
breaks_adj = {
    'age.in.years': [26, 35, 40],
    'other.debtors.or.guarantors': ["none", "co-applicant%,%guarantor"]
}
bins_adj = sc.woebin(dt_s, y="creditability", breaks_list=breaks_adj)

# converting train and test into woe values
# 将测试集和训练集转换为woe值
train_woe = sc.woebin_ply(train, bins_adj)
test_woe = sc.woebin_ply(test, bins_adj)

y_train = train_woe.loc[:,'creditability']
X_train = train_woe.loc[:,train_woe.columns != 'creditability']
y_test = test_woe.loc[:,'creditability']
X_test = test_woe.loc[:,train_woe.columns != 'creditability']

# logistic regression ------
# 逻辑回归 -----
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(penalty='l1', C=0.9, solver='saga', n_jobs=-1)
lr.fit(X_train, y_train)
# lr.coef_
# lr.intercept_

# predicted proability
# 可能性预测
train_pred = lr.predict_proba(X_train)[:,1]
test_pred = lr.predict_proba(X_test)[:,1]

# performance ks & roc ------
# ks 和 roc 的性能表现 -----
train_perf = sc.perf_eva(y_train, train_pred, title = "train")
test_perf = sc.perf_eva(y_test, test_pred, title = "test")

# score ------
# 得分 -----
card = sc.scorecard(bins_adj, lr, X_train.columns)
# credit score
# 信用得分
train_score = sc.scorecard_ply(train, card, print_step=0)
test_score = sc.scorecard_ply(test, card, print_step=0)

# psi
# 
sc.perf_psi(
  score = {'train':train_score, 'test':test_score},
  label = {'train':y_train, 'test':y_test}
)

github项目:https://github.com/amphibian-dev/toad https://github.com/ShichenXie/scorecardpy https://github.com/chengsong990020186/CreditScoreModel https://github.com/taenggu0309/Scorecard–Function

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/03/14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Python编程思想(12):for-in循环
for-in循环可以用于遍历范围、列表、元素和字典等可迭代对象包含的元素。for-in循环的语法格式如下:
蒙娜丽宁
2020/06/16
3.7K0
【Python入门第十讲】字典
字典(Dictionary)是 Python 中常用的数据结构之一,用于存储键值对(key-value pairs)。字典的特点是可变的、无序的,且键(key)必须是唯一的,但值(value)可以重复。
不惑
2024/02/01
2350
【Python入门第十讲】字典
python中字典的排序(Ordered
Help on built-in function sorted in module builtins:
py3study
2020/01/06
2.6K0
Python字典不是不可以排序,是你方法没用对!
摘要:排序是个古老的话题,不过对于字典的排序,常常会让 小白手足无措。好像没有找到可以排序字典的函数呢!到底是按key排序,还是按value排序呢?字典到底可不可以按value排序呢?排完序后,还可以通过key检索吗?当然,还会抛出很多问题,而本文将完美地给出了这些问题的答案!
蒙娜丽宁
2021/02/19
1.1K0
网络工程师学Python-5-Python 字典
Python 字典(Dictionary)是一种可变、无序、键值对(Key-Value Pair)的数据结构,用于存储和管理一组数据。字典通过键(Key)来访问对应的值(Value),类似于实际生活中的字典,可以通过关键词找到对应的解释或定义。
网络技术联盟站
2023/04/17
9830
网络工程师学Python-5-Python 字典
Python全网最全基础课程笔记(八)——字典,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
get() 方法提供了一种更安全的访问字典项的方式,如果指定的键不存在,则返回一个默认值(默认为 None),而不是抛出 KeyError。
小白的大数据之旅
2024/11/20
1720
Python全网最全基础课程笔记(八)——字典,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
Python之有序字典(OrderedDict)与 普通字典(dict)
之前我认为python中的字典是无序的,因为它是按照hash来存储的,最近开发过程中对数据序列化之后,返回了OrderedDict类型数据,返回数据格式如下
SEian.G
2021/10/22
3.2K0
day08-字典
字典(Dict)是一种可变、无序的数据类型;那等等...我们回忆一下,字符串列表元祖是什么样的?
似小陈吖
2024/01/18
1480
13 个非常有用的 Python 代码片段,建议收藏!
假设我们在 Python 中有两个列表,我们希望将它们合并为字典形式,其中一个列表的项作为字典的键,另一个作为值。这是在用 Python 编写代码时经常遇到的一个非常常见的问题
周萝卜
2022/09/28
7370
13 个非常有用的 Python 代码片段,建议收藏!
详解Python中列表、元组、字典,所有操作,一网打尽
列表(List)是Python中最常用的数据结构之一,它是一个可变的、有序的元素集合。
统计学家
2024/09/23
1420
详解Python中列表、元组、字典,所有操作,一网打尽
Python内置数据结构之字典(完整版)
今天主要讲解上次未完成的内置数据结构-字典。小白这几天比较忙,忙的忘记了健身及写作,特发此文以作补偿。 Python字典简介 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 这种key-value存储方式,在放进去的时候,必须根据key算出value的存放位置,这样,取的时候才能根据key直接拿到value。 请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。 和list比较,di
1846122963
2018/03/09
8790
python 字典一些常见的魔法方法以及遇到的面试题
dict 类型不但在各种程序里广泛使用,它也是 Python 语言的基石。模块的命名空间、实例的属性和函数的关键字参数中都可以看到字典的身影。跟它有关的内置函数都在__builtins__.__dict__模块中。正是因为字典至关重要,Python 对它的实现做了高度优化,而散列表则是字典类型性能出众的根本原因。
用户4945346
2020/07/20
7620
[编程经验] Python之collections模块
collections模块是一个不用不知道,一用就上瘾的模块。因为它提供了几种非常方便的数据结构和方法,在有些情况下特别好用。今天给大家总结一下其中的OrderDict和Counter两个方法,在平时我经常用的方法,希望你也能喜欢它。然后还有比如deque,namedtuple,defaultdict等也是很有的方法,了解了以后重点是熟练的使用,灵活的应用到你的具体任务中,是需要掌握的。 1. OrderDict # Example 1 dict_1 = dict() dict_1['A'] = "I lo
用户1622570
2018/04/11
6800
[PYthon] 字典
Python 中的字典(Dictionary)是一种非常强大且常用的数据结构,它提供了键-值对之间的映射
DevKevin
2024/03/19
1070
[PYthon] 字典
零基础学习 Python 之字典
大家好,这里是零基础学习 Python 系列,在这里我将从最基本的Python 写起,然后再慢慢涉及到高阶以及具体应用方面。我是完全自学的 Python,所以很是明白自学对于一个人的考验,所以在这里我会尽我最大的努力,把 Python 尽可能简单的表述清楚,让更多想要学习 Python 的朋友能够入门。同时写这个教程也算是对自己之前所学知识的一个巩固和提高,喜欢的朋友们可以点个关注,有问题欢迎随时和我交流。本文所有的代码编写均是Python3 版本。
编程文青李狗蛋
2019/11/07
4160
Python学习——collections系列
一 ,计数器(counter) Counter是对字典类型的补充,用于追踪值得出现次数 ps:具备字典的所有功能 + 自己的功能 例: >>> from collections import Counter >>> c = Counter('aadsassdsdads') >>> print(c) Counter({'a':4,'d':4,'s':5}) 基本操作方法: >>> c = Counter('abcdeabcdabcaba') 1.most_common(N)数量从大到小排列,获取
zenRRan
2018/04/10
7100
Python 字典 dict
有时候为了方便起见,就算某个键在映射里不存在,我们也希望在通过 这个键读取值的时候能得到一个默认值。有两个途径能帮我们达到这个目的,一个是通过 defaultdict,这个类型而不是普通的 dict,另一个 是给自己定义一个 dict 的子类,然后在子类中实现 __missing__ 方法。
为为为什么
2022/08/09
8530
Python 字典 dict
13 个非常有用的 Python 代码片段
假设我们在 Python 中有两个列表,我们希望将它们合并为字典形式,其中一个列表的项作为字典的键,另一个作为值。这是在用 Python 编写代码时经常遇到的一个非常常见的问题
Python学习者
2023/03/18
7700
python简单的分析文本
import collections import re #读取tips.txt文件内容,type(mytips)=str with open("tips.txt","r",encoding="utf-8") as tip: mytips=tip.read().lower() #正则去除非中英文字符, strip_file=re.sub(r"\W+","",mytips) print("正则去除非中英文字符:\n{}".format(strip_file)) print() #筛选
py3study
2020/01/02
7280
#小手一抬学Python# Python字典已经掌握了【附源码】
已经学完了列表与元组,那这两个都是按照顺序排列的,所以可以用索引取到值,本篇博客要学习的是字典,由上文可知,字典肯定就是不能按照索引取到值,就是没顺序,非序列的数据结构。
程序员迪迪
2022/01/04
7330
相关推荐
Python编程思想(12):for-in循环
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档