信贷违约问题(二分类问题)python 总结"/>
lightGBM 信贷违约问题(二分类问题)python 总结
2021SC@SDUSC
实在是没啥好写的了,写点感兴趣的最近在做的工作
目录
- lightGBM 信贷违约问题(二分类问题)python 总结
- 推荐使用 Jupyter Notebook
- 前置工作-安装依赖
- 数据基本技巧
- 读数据
- 存数据
- 数据概览
- 缺失数量统计
- 查看特征有几种取值
- 查看特征分别有那些取值
- 查看特征不同取值的个数
- 查看特征和 target 取值的相关性
- 数据预处理
- 数据集拼接
- 时间格式转化
- 文字类型转化为数字类型
- 分类特征
- 特征选择
- 相关性
- 特征贡献
- 数据选择
- 训练模型实现
- 参数优化方法
- 在下一部分
lightGBM 信贷违约问题(二分类问题)python 总结
推荐使用 Jupyter Notebook
前置工作-安装依赖
pandas
不必多说,基本的数据结构以及操作
pip3 install pandas
或者
pip install pandas
lightgbm
主角
pip3 install lightgbm
如果像我一样用的 Anaconda “懒人包”
# 如果在C盘,管理员运行 shell
conda install lightgbm
bayesian-optimization
调参好帮手
pip3 install bayesian-optimization
数据基本技巧
读数据
dataframe = pd.read_csv('文件地址')
相对路径或绝对路径
注意:绝对路径需要转义符比如 (‘C:\\Users\\F\\Desktop\\data\\test_data.csv’)
存数据
dataframe.to_csv('地址格式同上', index=False, encoding='utf_8_sig')
数据概览
dataframe.describe()
缺失数量统计
dataframe.isnull().sum()
查看特征有几种取值
# 一般只对分类特征统计
dataframe[categorical_feature].nunique().sort_values()
查看特征分别有那些取值
# 只对取值少的某一列
dataframe['列名'].unique()
查看特征不同取值的个数
dataframe[['列名']].value_counts()
查看特征和 target 取值的相关性
correlations = dataframe.corr()['is_default'].sort_values()
print('相关性:\n', correlations.tail(100))
相关性值仅供参考,特别是对于分类特征来说
负数是负相关,正数是正相关
绝对值越大,相关性越强
值为 NaN 一般代表这一特征只有一种取值
数据预处理
因为这次拿到的数据集用到了一点点迁移学习的概念,有两个类似的训练集,需要把两个训练集简单的拼接起来
数据集拼接
# 列名变化
train_public = train_public.rename(columns = {'isDefault': 'is_default'})
# 统计特征的交集
common_cols = []
for col in train_public.columns:if col in train_internet.columns:common_cols.append(col)else: continue
len(common_cols)
# 只留下交集特征后的数据
train1_data = train_internet[common_cols]
train2_data = train_public[common_cols]
test_data = test[common_cols[:-1]]
时间格式转化
import datetime
# 转换为pandas中的日期类型
train1_data['issue_date'] = pd.to_datetime(train1_data['issue_date'])
# 提取多尺度特征
train1_data['issue_date_y'] = train1_data['issue_date'].dt.year
train1_data['issue_date_m'] = train1_data['issue_date'].dt.month
# 提取时间diff 经过了多少天
# 设置初始的时间
base_time = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
# 转换为天为单位
train1_data['issue_date_diff'] = train1_data['issue_date'].apply(lambda x: x-base_time).dt.days
# show
#train1_data[['issue_date', 'issue_date_y', 'issue_date_m', 'issue_date_diff']]
train1_data.drop('issue_date', axis = 1, inplace = True)
文字类型转化为数字类型
# 查看文字类型特征
train2_data.dtypes[train2_data.dtypes == 'object']
# 提取特征,用字典把文字和数字做一个映射
employer_type = train1_data['employer_type'].value_counts().index
industry = train1_data['industry'].value_counts().index
# 字典
emp_type_dict = dict(zip(employer_type, [0,1,2,3,4,5]))
industry_dict = dict(zip(industry, [i for i in range(14)]))
work_year_map = {'10+ years': 10, '2 years': 2, '< 1 year': 0, '3 years': 3, '1 year': 1,'5 years': 5, '4 years': 4, '6 years': 6, '8 years': 8, '7 years': 7, '9 years': 9}
class_map = {'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6}
train1_data['work_year'] = train1_data['work_year'].map(work_year_map)
train1_data['class'] = train1_data['class'].map(class_map)
train1_data['employer_type'] = train1_data['employer_type'].map(emp_type_dict)
train1_data['industry'] = train1_data['industry'].map(industry_dict)
在数据处理过程中结合字段含义描述,根据经验判断删除部分特征,比如
X_train1 = train1_data.drop(['earlies_credit_mon','loan_id','user_id'], axis = 1, inplace = False)
对于使用 lightgbm 模型,特征不需要归一化,不需要缺失值填充,不需要转化为 one-hot 编码,只需要指明分类特征,然后在训练的时候告诉模型即可
分类特征
categorical_feature = ['class', 'employer_type','censor_status', 'use','region', 'issue_date_y']
特征选择
特征选择最直接的方法是比较两种情况:使用该特征、删除该特征,两种数据集在训练时交叉验证中的表现。
具体操作就是:当前我的模型参数为 5,在数据集 A 中得分 0.8。删除 A 中的特征 c 后得到新的数据集 B,使用参数还是 5,在数据集 B 中重新训练一遍,比较新的得分和 0.8。一般来说如果新的得分高,则认为删除特征 c 是用帮助的(假设训练误差近似泛化误差)。
当然如果特征很多,考虑排列组合,我们会有很多很多种情况能考虑,所以需要有其他手段辅助我们选择特征删除,比如相关性低的特征,比如贡献小的特征等。
相关性
correlations = dataframe.corr()['is_default'].sort_values()
print('相关性:\n', correlations.tail(100))
对于相关性,一般认为统计特征(比如次数、钱数等)和类别之间的相关性可以作为参考;分类特征(比如公司类型、年份、邮政编码等)的相关性没有价值。
相关性绝对值小的特征更有可能没有价值。
但是不能只根据相关性判断,一般需要从多个方面考虑,比如结合下面说的特征的重要性 features_importance
特征贡献
模型参数 importance_type
# 记录每个特征作为节点分裂时选择的特征的次数
importance_type = 'split'
# 记录每个特征总分裂收益
importance_type = 'gain'
训练完后保存贡献记录
# clf_model 是模型
frea_gain = pd.DataFrame(clf_model.feature_importances_)
frea_split = pd.DataFrame(clf_model.feature_importances_)
# 单次分裂收益
frea_avg[0] = frea_gain[0] / frea_split[0]
# 简单可视化
frea_avg['feature'] = X_train1.columns
frea_avg.sort_values(0)
可以结合次数(split)、总得分(gain)、单位得分(avg)挑选剔除特征。
按照升序排列后,排名靠前的代表在模型中贡献较少。
结合上述相关性一起考量后,挑选出部分特征,挨个或者成批的删除,测试效果。
数据选择
训练模型实现
参数优化方法
在下一部分
更多推荐
lightGBM 信贷违约问题(二分类问题)python 总结
发布评论