本学习笔记为阿里云天池龙珠计划金融风控训练营的学习内容,学习链接为:AI训练营金融风控-阿里云天池
一、学习知识点概要
1、了解缺失值填充方法
2、了解时间格式特征的处理方法
3、了解类别特征处理方法
4、了解异常值处理方法
二、学习内容
1、首先将数据集按特征分为数值型和类别型,然后分别对数值型特征缺失值进行中位数或者均值填充,对类别型特征缺失值进行众数填充,且用训练集的值对测试集进行填充,以防信息泄露
2、将时间格式特征转化成整型
3、类别特征处理
- 将时间特征从类别特征列表中删除
- 将数值型类别特征增加到类别特征列表中
- 对类型值大于2的特征,且非高维稀疏的,进行dummies处理
三、学习问题与解答
1、为何文中用众数填充类别型缺失值时未生效?
类别型特征缺失值填充需逐个处理,并在返回的众数上加上索引:
data_train.employmentLength = data_train.employmentLength.fillna(data_train.employmentLength.mode()[0])
2、data_train['employmentLength'].apply(employmentLength_to_int)与data_train['employmentLength'].split()[0]有何区别?
前者是将Series里每行的字符串值传递到函数中处理,后者是直接在Series上应用split,会报错
3、为何不对grade特征进行get_dummies处理?
后续进行特征交互
4、在for循环里使用pd.get_dummies失效,需要直接在数据集上操作
5、如果异常值都属于为1的用户数据里面代表什么呢?
存在数据录入错误
6、如何进行卡方分箱?
7、LabelEncoder.fit()时需要加入测试集吗?
不需要
8、kf.split(train_x, train_y)只需要传递一个参数即可,train_x或者train_y
9、lightgbm执行train时报“ verbose_eval,early_stopping_rounds“ not expected,修改为:
callbacks = [lgb.log_evaluation(period=200), early_stopping(stopping_rounds=200)]
......
clf.train(...callbacks=callbacks)
10、num_boost_round、log_evaluation(period=200)、early_stopping(stopping_rounds=200)配合使用:num_boost_round定义最大迭代次数,log_evaluation定义打印日志的迭代周期,early_stopping定义连续多少次迭代性能没有提升就结束训练
11、卡方分桶代码(参考链接:https://zhuanlan.zhihu.com/p/647015148)
class ChiSquareMerge:
def __cal_chi2(self, df, col, target):
bindf = df.copy()
bad_rate = bindf['bad_cnt'].sum() / (bindf['bad_cnt'].sum() + bindf['good_cnt'].sum())
good_rate = 1 - bad_rate
bindf['expect_good_cnt'] = (bindf['bad_cnt'] + bindf['good_cnt']) * good_rate
bindf['expect_bad_cnt'] = (bindf['bad_cnt'] + bindf['good_cnt']) * bad_rate
bindf['chi2'] = (bindf['good_cnt'] - bindf['expect_good_cnt']) ** 2 / (bindf['expect_good_cnt'] + 1) + \
(bindf['bad_cnt'] - bindf['expect_bad_cnt']) ** 2 / (bindf['expect_bad_cnt'] + 1)
return bindf['chi2'].sum()
def chi2_merge(self, df, col, target, maxInterval=5, chi_threshold=None):
bindf = df[[col, target]].copy()
bindf = pd.crosstab(bindf[col], bindf[target]).reset_index()
bindf.columns = [col, 'good_cnt', 'bad_cnt']
bin_cnt = len(bindf)
bins = [[i] for i in bindf[col].values.tolist()]
if chi_threshold is None:
chi_threshold = 1e9
min_chiSquare = 0.
while (min_chiSquare < chi_threshold and bin_cnt > maxInterval):
bins_chi2 = []
for idx, val in enumerate(bins[:-1]):
start_index = bindf[bindf[col] == val[0]].index.tolist()[0]
end_index = bindf[bindf[col] == bins[idx+1][-1]].index.tolist()[0]
bins_chi2.append((idx, self.__cal_chi2(bindf.loc[start_index:end_index, :], col, target)))
min_idx, min_chiSquare = sorted(bins_chi2, key=lambda x: x[1])[0]
bins[min_idx] += bins[min_idx + 1]
bins.pop(min_idx + 1)
bin_cnt = len(bins)
return bins
chi2m = ChiSquareMerge()
bins = chi2m.chi2_merge(data_train, 'loanAmnt', 'isDefault')
bins = [b[-1] for b in bins]
bins = [-1e9,] + bins[:-1] + [1e9]
data_train['loanAmnt_bins'] = pd.cut(data_train['loanAmnt'], bins=bins, labels=['a', 'b', 'c', 'd', 'e'])
data_test_a['loanAmnt_bins']=pd.cut(data_train['loanAmnt'], bins=bins, labels=['a', 'b', 'c', 'd', 'e'])
四、学习思考与总结
1、在进行数值连续性特征图形化分析时,可以在distplot中使用参数fit=norm,查看特征分布是否服从正态分布,对明显不符合正态分布的特征进行对数化处理
2、因为异常值主要存在于数值连续型特征中,所以在处理异常值时,应该先将数值离散型特征和id从数值特征列表中删除
3、在删除异常值后,需要将辅助判断异常值的新增特征删除,否则后续进行协方差计算时会报错:
for fea in numerical:
data_train.drop([fea+'_outliers'], axis=1, inplace=True)