特征衍生
特征衍生就是指对原始的数据特征进行一些加减乘除或者根据其业务场景来衍生出一些在原始数据集中不存在的特征。
IV值
IV的全称是Information Value,也就是信息价值或信息量的意思。
在我们对面数据有较多的特征时比如这次的数据有90个特征时,我们不会直接把这90个特征全放在模型中去训练,而是会选出一些来进行训练,那么我们选择的标准是什么呢。通常我们需要考虑的因素很多,比如:变量的预测能力,变量之间的相关性,变量的简单性(容易生成和使用),变量的强壮性(不容易被绕过),变量在业务上的可解释性(被挑战时可以解释的通)等等。但是,其中最主要和最直接的衡量标准是变量的预测能力。
我们需要一些具体的量化指标来衡量每自变量的预测能力,并根据这些量化指标的大小,来确定哪些变量进入模型。IV就是这样一种指标,他可以用来衡量自变量的预测能力。类似的指标还有信息增益、基尼系数等等。
这里的概念很多,本人也是小白,详情参见博客:https://blog.csdn.net/kevin7658/article/details/50780391
实现代码(参考了其他同学的实现)
import math
import numpy as np
from scipy import stats
from sklearn.utils.multiclass import type_of_target
def woe(x,y,event =1):
res_woe = []
iv_dict = {}
for feature in X.columns:
x = X[feature].values
# 1) 连续特征离散化
if type_of_target(x) == 'continuous':
x = discrete(x)
# 2) 计算该特征的woe和iv
# woe_dict, iv = woe_single_x(x, y, feature, event)
woe_dict, iv = woe_single_x(x, y, feature, event)
iv_dict[feature] = iv
res_woe.append(woe_dict)
return iv_dict
def discrete(x):
# 使用5等分离散化特征
res = np.zeros(x.shape)
for i in range(5):
point1 = stats.scoreatpercentile(x, i * 20)
point2 = stats.scoreatpercentile(x, (i + 1) * 20)
x1 = x[np.where((x >= point1) & (x <= point2))]
mask = np.in1d(x, x1)
res[mask] = i + 1 # 将[i, i+1]块内的值标记成i+1
return res
def woe_single_x(x, y, feature,event = 1):
# event代表预测正例的标签
event_total = sum(y == event)
non_event_total = y.shape[-1] - event_total
iv = 0
woe_dict = {}
for x1 in set(x): # 遍历各个块
y1 = y.reindex(np.where(x == x1)[0])
event_count = sum(y1 == event)
non_event_count = y1.shape[-1] - event_count
rate_event = event_count / event_total
rate_non_event = non_event_count / non_event_total
if rate_event == 0:
rate_event = 0.0001
# woei = -20
elif rate_non_event == 0:
rate_non_event = 0.0001
# woei = 20
woei = math.log(rate_event / rate_non_event)
woe_dict[x1] = woei
iv += (rate_event - rate_non_event) * woei
return woe_dict, iv
# 使用IV值进行特征选择
iv_dict = woe(x_train, y_train)
iv = sorted(iv_dict.items(), key = lambda x:x[1],reverse = True)
iv
def iv_choose(iv):
iv_list = []
for i, j in iv.items():
if (j > 0.02) & (j < 0.6):
iv_list.append(i)
return iv_list
iv_list = iv_choose(iv_dict)
print(len(iv_list))
iv_list
我这边在执行这段代码的时候就会报错,原我觉得type_of_target应该是一个封装函数,这里我没有定义,后续我将加上跑同这段代码
随机森林进行特征筛选代码实现
# 使用随机森林进行特征选择
from sklearn.ensemble import RandomForestClassifier
# 这里没有对参数进行较多的设置,可以改进
rfc = RandomForestClassifier(n_estimators = 500,random_state= 0)
rfc.fit(x_train,y_train)
importance = pd.Series(rfc.feature_importances_, index=x.columns).sort_values(ascending=False)
importance