风控项目05---特征筛选

一:单特征分析:

问题: 什么是好的特征?
答: 覆盖度高的,区分度高的,相关性符合的,稳定性强的。

1.1: 覆盖度:

问题: 覆盖率你是如何计算的?
答: 计算,缺失率 和 零值率。缺失率 = 缺失的数量/带有标签的总数量。零值率 = 值为0的数量/带有标签的总数量。
在这里插入图片描述

1.2: 区分度:

问题: 你是如何判断区分度的好坏的?
答: 方法一: 计算单特征的AUC ,KS指标。
方法二: 计算单特征的IV值:
在这里插入图片描述
案例:计算IV值:
1: 计算每个标签下好人的概率 = p_good = good / good_总计
2:计算每个标签下坏人的概率 = p_bad = bad / bad_总计
3: 计算好人概率和坏人概率的差值 = p_good - p_bad
4: 计算ln(p_good/p_bad)的值。
5: 计算 IV = ln(p_good/p_bad) * (p_good - p_bad)
在这里插入图片描述
问题:IV值如何评估我们的区分度?
答: IV小于0.02 ,则认为区分度小,建模时应该抛弃。
IV在0.02到0.5之间,则认为区分度大,可以建模时使用。
IV大于0.5表示可以单独拿出来当做一个规则使用,不再参与训练了。

模型中尽可能使用区分度相对较弱的特征,将多个弱特征组合,得到评分卡模型
连续变量的IV值计算,先离散化再求IV,跟分箱结果关联很大(一般分3-5箱)

1.3:相关性:

  • 1: 需要对相关系数较大的特征进行筛选,只保留其中对标签区分贡献度最大的特征,即保留IV较大的。
  • 2: 如果一个特征可以用另外的集合特征通过线性计算得到,那么我们没必要用这个特征了。

问题: 如何判定特征与特征之间的相关性呢?
答:皮尔逊相关系数,斯皮尔曼相关系数,肯德尔相关系数

问题:如何选择用那个相关系数呢?
1:连续的数值类型 + 数据具有正态分布 = 皮尔逊系数
2:连续的数值类型 + 数据不具有正态分布 = 斯皮尔曼相关系数或者肯德尔相关系数。
3:有序分类变量 = 斯皮尔曼相关系数
4:一个分类一个连续 = 肯德尔相关系数

案例: 计算两列的三种系数:

import pandas as pd 
df = pd.DataFrame({'A':[5,91,3],'B':[90,15,66],'C':[93,27,3]})

在这里插入图片描述

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

1.4:使用toad库来过滤大量的特征:

1: 加载数据:

import pandas as pd
import toad 
data = pd.read_csv('data/germancredit.csv') 
data.replace({'good':0,'bad':1},inplace=True) 
data.shape

2: 使用toad.selection.select 来选出缺失率大于0.5,IV值小于0.05,相关性大于0.7的特征列:

#缺失率大于0.5,IV值小于0.05,相关性大于0.7来进行特征筛选 
selected_data, drop_list= toad.selection.select(data,target = 'creditability', empty = 0.5, iv = 0.05, corr = 0.7, return_drop=True) 
print('保留特征:',selected_data.shape[1],'缺失删除:',len(drop_list['empty']),'低iv删除:',len(drop_list['iv']),'高相关删除:',len(drop_list['corr']))

在这里插入图片描述

1.5 : 稳定性:

如何评估一个特征的稳定性呢 ?
答: 特征稳定性主要通过计算不同时间段内同一类用户特征的分布的差异来评估。常用的度量手段是:PSI
在这里插入图片描述

二:多特征筛选:

  • 特征筛选的方法有: 星座特征,Boruta, 方差膨胀系数, 后向筛选, L1惩罚系数, 业务逻辑。

2.1: 星座特征:

在这里插入图片描述

2.2: Boruta算法:

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

Boruta算法的案例:

1:安装boruta算法包:
在这里插入图片描述
2: 加载数据:

import numpy as np
import pandas as pd 
import joblib 
from sklearn.ensemble import RandomForestClassifier
from boruta import BorutaPy 

#加载数据 
pd_data = joblib.load('data/train_woe.pkl')
pd_data

3:获取特征列和标签列:

#1: 处理数据,去掉id 和 目标值 
pd_x = pd_data.drop(['SK_ID_CURR', 'TARGET'], axis=1)
# 2: 拿到所有的特征列
x = pd_x.values 
# 3: 拿到目标列
y = pd_data[['TARGET']].values 
# 4: 将多维数组降位一维
y = y.ravel() 

4:使用Boruta,选择features:

# 1:先定义一个随机森林分类器
# 用于拟合和预测的并行运行的工作(作业)数量。如果值为-1,那么工作数量被设置为核的数量。
# class_weight='balanced',指定随机森林的的平衡性
# max_depth = 5 : 设置树的最大深度是5
rf = RandomForestClassifier(n_jobs=-1, class_weight='balanced', max_depth=5) 

''' 
BorutaPy function
estimator : 所使用的分类器 
n_estimators : 分类器数量, 默认值 = 1000 
max_iter : 最大迭代次数, 默认值 = 100 
''' 
# 1:定义一个BorutaPy对象
feat_selector = BorutaPy(rf, n_estimators='auto', random_state= 1, max_iter=10)
# 2: 进行训练
feat_selector.fit(x, y)

5:展示选择出来的feature:

pd_ft_select = pd.DataFrame({'feature':pd_x.columns.to_list(), "selected": feat_selector.support_})
pd_ft_select

显示结果:
在这里插入图片描述

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

2.3: 方差膨胀系数:

  • 1: 描述一个特征跟另一个特征之间的线性关系。
  • 2:膨胀系数越大,和别的线性越强,越可以被剔除。

在这里插入图片描述
案例:计算方差膨胀系数:
1: 安装膨胀系数包:
在这里插入图片描述
2:加载数据:

import numpy as np
import pandas as pd 
import joblib 
from statsmodels.stats.outliers_influence import variance_inflation_factor 

pd_data = joblib.load('./data/train_woe.pkl') 

#去掉ID和目标值 
pd_x = pd_data.drop(['SK_ID_CURR', 'TARGET'], axis=1)

3: 计算方差膨胀系数:

#定义计算函数 
def checkVIF_new(df): 
    lst_col = df.columns # 获取dataframe的列
    x = np.matrix(df)# 将df转换成矩阵
    # variance_inflation_factor(x,i),传入x是矩阵, i 是第几列,从0 到shape[1]-1,得到每个计算得到的方差膨胀系数。
    VIF_list = [variance_inflation_factor(x,i) for i in range(x.shape[1])] 
    # 创建新的dataframe :一列是原来的列名,另一列是方差膨胀系数
    VIF = pd.DataFrame({'feature':lst_col,"VIF":VIF_list}) 
    # 获取最大的方差膨胀系数: inf无穷大
    max_VIF = max(VIF_list)
    print(max_VIF) 
    return VIF

df_vif = checkVIF_new(pd_x) 
df_vif

在这里插入图片描述

2.4: RFE递归特征消除:

  • 递归特征消除的思路: 使用排除法的方式训练模型,把模型性能下降最少的那个特征去掉,反复上述训练直到达到指定的特征个数。

案例:

1: 导入数据:

import numpy as np 
import pandas as pd
import joblib 
from sklearn.feature_selection import RFE 
from sklearn.svm import SVR 
pd_data = joblib.load('data/final_data.pkl')
pd_data

在这里插入图片描述

2: 数据进行处理:

pd_x = pd_data.drop(['SK_ID_CURR', 'TARGET'], axis=1) # 干掉标签列和索引列
x = pd_x.values # 转换成数组格式
y = pd_data[['TARGET']].values # 标签列,也转换成标签列
y = y.ravel() # 去掉外面的一层列

3: 使用RFE,选择features:

#定义分类器 
estimator = SVR(kernel="linear") # 创建SVR模型对象
selector = RFE(estimator, 3, step=1) # step 一次去掉几个特征 ,最后只留3个。
selector = selector.fit(x, y) # 进行训练
pd_ft_select = pd.DataFrame({'feature':pd_x.columns.to_list(), "selected": selector.support_}) 
pd_ft_select

4: 显示结果:

2.5: 基于L1的特征选择 (L1-based feature selection)

  • 1: 使用L1范数作为惩罚项的线性模型(Linear models)会得到稀疏解:大部分特征对应的系数为0。
  • 2:希望减少特征维度用于其它分类器时,可以通过 feature_selection.SelectFromModel 来选择不为0的系数。
from sklearn.svm import LinearSVC 
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel 
iris = load_iris() 
X, y = iris.data, iris.target 
X.shape
# 进行L1正则化
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y) 

# 选择不系数为0的列
model = SelectFromModel(lsvc, prefit=True)

X_new = model.transform(X) 

X_new.shape

三:内部特征的监控:

3.1: 授信之前的监控:

  • 1: 大多数情况下,随着业务越来越稳定,缺失率应该呈现逐渐降低的趋势
  • 2:如果缺失率突然增大,大概率是数据采集过程或者数据传输过程出现问题。
  • 3: PSI ,特征维度的PSI,如果大于0.1,可以观察一段时间。

案例:要求能够根据这个看出异常信息:分析出异常信息的原因:
在这里插入图片描述

3.2:放款之后的监控:

1:特征区分度监控:
首先看AUC指标和KS指标波动是否在10%以内。
KS 如果是线上A卡 0.2是合格的水平
IV值的波动稍大可以容忍,和分箱相关,每周数据分布情况可能不同,对IV影响大一些

案例:看看是否异常:发现都挺正常的:
在这里插入图片描述
案例:看看分箱是否异常:
1:每一箱 的bad_rate有波动,容忍度相对高一些。
2:要高度重视不同箱之间风险趋势发生变化,如分箱1,分箱2,在week2和week3 风险趋势发生了变化
3:如果风险趋势单调性发生变化,要考虑特征是不是要进行迭代
在这里插入图片描述

四:外部特征的评估:

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奈何碎银没有几两

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值