【金融风控项目-09】:特征变换

文章目录

  • [1 分箱](#1 分箱)
    • [1.1 分箱概念](#1.1 分箱概念)
    • [1.2 分箱的作用](#1.2 分箱的作用)
    • [1.3 常用的分箱方法](#1.3 常用的分箱方法)
      • [1.3.1 等频分箱](#1.3.1 等频分箱)
      • [1.3.2 等距分箱](#1.3.2 等距分箱)
      • [1.3.3 卡方分箱](#1.3.3 卡方分箱)
      • [1.3.4 卡方分箱(toad库)](#1.3.4 卡方分箱(toad库))
      • [1.3.5 各种分箱方法对比](#1.3.5 各种分箱方法对比)
  • [2 多值无序特征编码](#2 多值无序特征编码)
    • [2.1 One-Hot Encoding](#2.1 One-Hot Encoding)
    • [2.2 Label Encoding](#2.2 Label Encoding)
    • [2.3 WOE Encoding](#2.3 WOE Encoding)
    • [2.4 编码方式总结](#2.4 编码方式总结)
  • [3 多值有序特征编码](#3 多值有序特征编码)

1 分箱

1.1 分箱概念

特征构造的过程中,对特征做分箱处理时必不可少的过程

分箱 就是将连续变量离散化合并成较少的状态

1.2 分箱的作用

  • 离散特征的增加和减少都很容易,易于模型的快速迭代;

n稀疏向量内积乘法运算速度快,计算结果方便存储,容易扩展;

  • 分箱(离散化)后的特征对异常数据有很强的鲁棒性
  • 单变量分箱(离散化)为N个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力
  • 分箱(离散化)后可以进行特征交叉,由M+N个变量变为M*N个变量,进一步引入非线性,提升表达能力;
  • 分箱(离散化)后,模型会更稳定,如对年龄离散化,20-30为一个区间,不会因为年龄+1就变成一个新的特征。
  • 特征离散化以后,可以将缺失作为独立的一类带入模型

    需要解决的问题:
  • 怎么离散化(分箱)比较好?
  • 对于一个连续型的特征,如何进行划分区间?等频?等距?还是其他
  • 分成几箱?10箱?100箱?..
  • 分箱时缺失值怎么办?

1.3 常用的分箱方法

  • 卡方分箱(最常用的方法)
  • 决策树分箱
  • 等频分箱
  • 聚类分箱

1.3.1 等频分箱

特征数据:

  • 按数据的分布,均匀切分,每个箱体里的样本数基本一样

  • 在样本少的时候泛化性较差

  • 在样本不均衡时可能无法分箱

  • 特征分析常用等频分箱

1.3.2 等距分箱

  • 按数据的特征值的间距((max-min)/步长)均匀切分,每个箱体的数值距离一样

  • 一定可以分箱

  • 无法保证箱体样本数均匀

  • 信用分统计时常用等距分箱

1.3.3 卡方分箱

卡方分箱原理:

  • 卡方分箱是自底向上的(即基于合并的)数据离散化方法。它依赖于卡方检验:具有最小卡方值的相邻区间合并在一起,直到满足确定的停止准则。

卡方分箱基本思想:

  • 对于精确的离散化,相对类频率在一个区间内应当完全一致。因此,如果两个相邻的区间具有非常类似的类分布,则这两个区间可以合并;否则,它们应当保持分开。低卡方值表明它们具有相似的类分布。
  • 卡方检验可以用来评估两个分布的相似性,因此可以将这个特性用到数据分箱的过程中。
  • 理想的分箱是在同一个区间内标签的分布是相同的 。卡方分箱就是不断的计算相邻区间的卡方值(卡方值越小表示分布越相似),将分布相似的区间(卡方值最小的)进行合并,直到相邻区间的分布不同,达到一个理想的分箱结果

卡方分箱流程:

  • 卡方分箱的过程可以拆分为初始化和合并两步

初始化:根据连续变量值大小进行排序,构建最初的离散化

合并:遍历相邻两项合并的卡方值,将卡方值最小的两组合并,不断重复直到满足分箱数目要求

步骤:

  1. 将连续数据进行排序
  2. 将数据按等频或等距分箱后,统计每个箱子中的样本分布
  3. 计算卡方值,将卡方值较小的两个相邻箱体合并
  4. 不断进行合并,直到相邻相邻箱子中样本分布较大

卡方值越小,表明相邻的两个区间的数据分布越相似;相似的分布区间可以进行合并

使得不同箱体的好坏样本比例(样本分布)区别放大,容易获得高IV

IV (Information Value):用于衡量区分度好坏,好坏用户的特征值差别大

卡方值计算示例:


1.3.4 卡方分箱(toad库)

案例:使用toad库进行分箱处理,数据集使用germancredit

  • Toad 是专为工业界模型开发设计的Python工具包,特别针对评分卡的开发
  • Toad 的功能覆盖了建模全流程,从 EDA、特征工程、特征筛选到模型验证和评分卡转化
  • Toad 的主要功能极大简化了建模中最重要最费时的流程,即特征筛选和分箱。

字段说明:

分箱流程:

  • 导包和加载数据
python 复制代码
import pandas as pd
import numpy as np
import toad

data = pd.read_csv('../data/germancredit.csv')
  • data.shape为(1000,21)表示数据集有1000个样本,20个特征,一个标签列
  • 将标签列中的good和bad替换为0和1
python 复制代码
data.replace({'good':0,'bad':1},inplace=True)
  • toad进行分箱处理
python 复制代码
# 1.初始化一个combiner类对象
combiner = toad.transform.Combiner()
print(combiner) # <toad.transform.Combiner at 0x25776051ac0>

# 2.训练数据并指定分箱方法,其它参数可选  
# min_samples: 每箱至少包含样本量,可以是数字或者占比
# data - 指定要学习的数据集
# y - 指定标签列的名称
# method="chi" - 表示使用卡方分箱
combiner.fit(data,y='creditability',method='chi',min_samples = 0.05)

# 3.以字典形式保存分箱结果,得到分箱边界
bins = combiner.export() 
python 复制代码
data['status.of.existing.checking.account'].value_counts()
python 复制代码
#查看分箱结果
print('duration.in.month:', bins['duration.in.month'])
  • 使用bin_plot()画图对分箱进行调整
python 复制代码
import matplotlib.pyplot as plt
%matplotlib inline
from toad.plot import bin_plot
c2 = toad.transform.Combiner()  

# data[['duration.in.month','creditability']]
# 选择duration.in.month进行分箱处理
c2.fit(data[['duration.in.month','creditability']],
        y='creditability', method='chi',n_bins=7) 

# labels = True 将样本值转化为卡方分箱之后的区间
# 不指定labels的值,直接将特征值转化为对应的分箱编号
# transformed = c2.transform(data[['duration.in.month','creditability']],labels=True) 
transformed = c2.transform(data_[['duration.in.month','creditability','type']])


  • 查看分箱之后,每个箱子中数据多少
python 复制代码
transformed['duration.in.month'].value_counts()
python 复制代码
# trn
transformed.shape
  • 采用bin_plot()进行绘图
python 复制代码
#传给bin_plot的数据必须是分箱转化之后的
bin_plot(transformed, x='duration.in.month',target='creditability')

折线图表示在坏人比例在各个箱子中的比例

柱状图表示每个箱子中坏人比例在整体样本中的比例

折线图不是单调的,可解释性差,需要调整参数将折线图转变为单调曲线;中间降低,表示卡方值减小,所以可以和周边的区间合并

  • 调整箱数实现单调趋势,调整分箱数量
python 复制代码
c2 = toad.transform.Combiner()  
c2.fit(data[['duration.in.month','creditability']],
        y='creditability', method='chi',n_bins=5)  # 改成5箱
transformed = c2.transform(data[['duration.in.month','creditability']],labels=True)
#传给bin_plot的数据必须是分箱转化之后的
bin_plot(transformed,x='duration.in.month',target='creditability')

1.3.5 各种分箱方法对比

python 复制代码
# chi - 卡方分箱
# df - decision tree分箱
# quantile - 等频分箱
# step - 等距分箱
for method in ['chi', 'dt', 'quantile', 'step', 'kmeans']:  
    c2 = toad.transform.Combiner()  
    c2.fit(data[['duration.in.month','creditability']],
             y='creditability', method=method, n_bins=5)
    bin_plot(c2.transform(data[['duration.in.month','creditability']],labels=True),
                x='duration.in.month',target='creditability')




  • 卡方分箱 - IV值最大,不同分箱之间样本分布差异最大

2 多值无序特征编码

经过分箱,将连续特征进行了离散化,将样本分为几个箱体中,在进行机器学习训练的时候,需要给样本一个值,所以需要给样本的特征进行编码,常用的编码方式:one-hot encoding(独热码)、label encoding、WOE encoding

2.1 One-Hot Encoding

  1. 初始化向量(特征有多少类别,向量的位数就有几位)
  2. 每一位表示一个类别,是该类别,该位填1,其他位填0

one-hot编码优点:简单、易于处理、不用归一化

缺点:过于稀疏

2.2 Label Encoding

以每个箱体中,每个种类中坏样本的比率作为编码值

举例:统计出不同婚姻状态下的逾期率作为数值标签

数据量少的情况下,有可能会出现偏差

2.3 WOE Encoding

  • WOE(Weight of Evidence) 反映单特征在好坏用户区分度的度量

W O E k = l o g ( P k , g o o d / P k , b a d ) WOE_k = log(P_{k,good}/P_{k,bad}) WOEk=log(Pk,good/Pk,bad)

每个箱子中好用户比例/坏用户比例

Toad库实现WOE编码

python 复制代码
from sklearn.model_selection import train_test_split
# 划分训练集和测试集
X_train,X_test,Y_train,Y_test = train_test_split(data.drop('creditability',axis=1),data['creditability'],test_size=0.25,random_state=450)
# 将训练集的样本和目标值进行拼接,axis为1,表示左右拼接
data_train = pd.concat([X_train,Y_train],axis=1) 
#增加一列区分训练/测试的特征
data_train['type'] = 'train'

# 同样对测试集进行拼接,并增加一个type列
data_test = pd.concat([X_test,Y_test],axis=1)
data_test['type'] = 'test'

# 手动设置分箱边界
adj_bin = {'duration.in.month': [9, 12, 18, 33]}
c2 = toad.transform.Combiner()
c2.set_rules(adj_bin) # 将自定义的分箱边界给到Combiner()对象

# 将训练集和测试集上下拼接
data_ = pd.concat([data_train,data_test],axis = 0)

# 进行分箱,将对应特征转化为分箱之后的区间
temp_data = c2.transform(data_[['duration.in.month','creditability','type']])
  • 绘制badrate_plot图
python 复制代码
# 绘制badrate_plot图
from toad.plot import badrate_plot, proportion_plot
# temp_data - 传入数据集
# target - 表示标签列
# x - 指定类型列,这里type有两类
# by - 对哪个特征进行分箱
badrate_plot(temp_data, target = 'creditability', x = 'type', by = 'duration.in.month') 


  • 不同区间样本分布比例单调的优点:如果分布比例单调的条件下,新来一个样本落到某个箱子中,就可以根据该箱子中样本的分布情况直接得出新样本的好坏比率;如果不单调就不能直接得出,说明相邻箱子中样本分布情况有交叉,需要进行合并
python 复制代码
#绘制每一箱占比情况图
proportion_plot(temp_data['duration.in.month'])
python 复制代码
# 假定将第一箱、第二箱合并
# 调整分箱区间之后,重新进行分箱
adj_bin = {'duration.in.month': [9,18,33]}
c2.set_rules(adj_bin)

temp_data = c2.transform(data_[['duration.in.month','creditability','type']])
badrate_plot(temp_data, target = 'creditability', x = 'type', by = 'duration.in.month')
python 复制代码
#将特征的值转化为分箱的箱号。
binned_data = c2.transform(data_train)
  • 计算WOE
python 复制代码
#计算WOE
transer = toad.transform.WOETransformer()

#对WOE的值进行转化,映射到原数据集上。对训练集用fit_transform,测试集用transform.
data_tr_woe = transer.fit_transform(binned_data, binned_data['creditability'], exclude=['creditability','type'])
data_tr_woe.head()

2.4 编码方式总结

  • WOE理解:当前组中好用户和坏用户的比值与所有样本中这个比值的差异。差异通过对这两个比值取对数来表示

    • WOE越大,差异越大,这个分组里的好用户的可能性就越大
    • WOE越小,差异越小,这个分组里的好用户的可能性也就越小
  • 分箱结果对WOE结果有直接影响,分箱不同,WOE映射值也会有很大的不同

  • 箱的总数在5~10箱(可以适当调整,通常不超过10箱)

  • 并且将每一箱之间的负样本占比差值尽可能大作为箱合并的基本原则

  • 每一箱的样本量不能小于整体样本的5%,原则是每一箱的频数需要具有统计意义

3 多值有序特征编码

  • 多值有序类别型特征
    • 学历:高中以下,大专,本科,硕士,博士
    • 一定程度上学历高低能直接对应用户的信用风险,可以当做有序特征
    • 可以把多值有序特征转换为1,2,3...的数值
    • 高中以下 → 1, 大专 → 2 ,本科 → 3,硕士→4,博士→5

有序特征具有一定的含义,并且其含义也是有序的,可以将其转换为有序值

有序特征,其意义没有顺序,不将其转化为有序值,比如:男女类别,不用1,2表示,因为男女性别是平等的关系

相关推荐
fanstuck3 小时前
Prompt提示工程上手指南(七)Prompt编写实战-基于智能客服问答系统下的Prompt编写
人工智能·数据挖掘·openai
lovelin+v175030409663 小时前
安全性升级:API接口在零信任架构下的安全防护策略
大数据·数据库·人工智能·爬虫·数据分析
道一云黑板报3 小时前
Flink集群批作业实践:七析BI批作业执行
大数据·分布式·数据分析·flink·kubernetes
数据爬坡ing4 小时前
小白考研历程:跌跌撞撞,起起伏伏,五个月备战历程!!!
大数据·笔记·考研·数据分析
matlabgoodboy7 小时前
数据分析帮做spss数据代分析stata实证python统计R语言eviews处理
python·数据分析·r语言
云空10 小时前
《解锁 Python 数据挖掘的奥秘》
开发语言·python·数据挖掘
終不似少年遊*13 小时前
pyecharts
python·信息可视化·数据分析·学习笔记·pyecharts·使用技巧
陆沙13 小时前
生物信息学导论-北大-RNA-Seq数据分析
数据分析·生物信息·生信
Watermelo61713 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
落魄君子1 天前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘