机器学习 scikit-learn6 - 预测贷款用户是否会逾期 - 特征工程

说明

这次时间比较紧迫,还是按照以前的思路完成了这次小任务
参考链接: https://github.com/spareribs/kaggleSpareribs/tree/master/Overdue/ml/features

features 主要是数据的预处理

目前主要是简单的数据处理, 主要是模型上面的训练
1. 需要 直接删除 的数据, 这些都是唯一的id标识, 会过拟合
    - bank_card_no:只有一个值 '卡号1' , 无区分度
    - source:只有一个值 'xs' , 无区分度
    - 'Unnamed: 0': 与预测值无关 
    - custid: 与预测值无关 
    - id_name:与预测值无关 
    - trade_no:与预测值无关 
    
2. 【类别特征】需要 离散化处理 的数据
    - reg_preference_for_trad
    - regional_mobility
    - student_feature
    - is_high_user

3. 【日期】针对日期数据的处理(转换成年月日)
    - first_transaction_time
    - latest_query_time
    - loans_latest_time

4. 【删除部分特征】:统计各个列标准差,将标准差小于0.1的特征剔除
    
5. 【缺失值】缺失值的填充
    - 目前只是简单的众数填充 TODO
    - 缺失的数据作为一种新特征,衡量数据的完整度

6. 归一化处理所有数据
    - 目前直接使用StandardScaler方法处理, 没搞明白 TODO

核心代码说明

1 去掉一部分对结果没有影响的数据

def unique_drop(data):
    """ 
    1. count 跟 unique 一样,需要删除
    2. count 跟 unique 不一样,只有单一值也是要删除
    3. count 跟 unique 不一样,但是 nan统计后,count 跟 unique 一样 也需要删除
    """
    for col in data.columns:
        count = len(list(data[col].unique()))
        if count == 1 or count == data.shape[0]:
            print(col)
            train.drop([col], inplace=True, axis=1)

unique_drop(train)

这样直接删除这5列数据 Unnamed: 0, custid, trade_no, bank_card_no, source

2 字符特征处理

def missing_count(train, feature):
    """
    1. 统计缺失值
    2. 统计unique
    """
    all_count = len(train)
    missing = len(train[feature][pd.isnull(train[feature])])
    unique_object = list(train[feature].unique())
    print("缺失{1:>4}个  缺失率 {4:.2f}% 有{2:>4}个值 分别为 {3}等".format(all_count, missing, len(unique_object),unique_object[:7], missing/all_count, feature))

missing_count(train_object,"reg_preference_for_trad")
missing_count(train_object,"id_name")
  1. reg_preference_for_trad: 城市,使用0来填充 用 one-hot 编码
  2. id_name:名字,理论上需要对相同名字的人进行归类, 这种做法先搁置了, 没想到更好的解决方法,先删除这一列数据
  3. latest_query_time和loans_latest_time 当作时间特征来处理
# 缺失值2个,用众数填充
train_object['reg_preference_for_trad'] = train_object['reg_preference_for_trad'].fillna(train_object['reg_preference_for_trad'].mode()[0])
# 转换成数字
train_object['reg_preference_for_trad'] = train_object['reg_preference_for_trad'].map({'一线城市': 0, '二线城市': 1,'三线城市': 2,  '其他城市': 3, '境外': 4})
# one-hot编码
train_object = pd.get_dummies(train_object,columns=["reg_preference_for_trad"],prefix="reg_preference_for_trad")

3 日期/时间型特征

参考 https://blog.csdn.net/l75326747/article/details/84326897#字符型特征

  1. 取出日期,可分别构建如 年、月、日、工作日、周数 等;
  2. 如有时间,可分别构建如 小时、分钟 等;
  3. 两两日期或时间可根据业务知识相互做差,求出相差天数,小时数等
date_temp = pd.DataFrame()
date_temp['latest_query_time_year'] = pd.to_datetime(train_object['latest_query_time']).dt.year
date_temp['latest_query_time_month'] = pd.to_datetime(train_object['latest_query_time']).dt.month
date_temp['latest_query_time_day'] = pd.to_datetime(train_object['latest_query_time']).dt.day
date_temp['loans_latest_time_year'] = pd.to_datetime(train_object['loans_latest_time']).dt.year
date_temp['loans_latest_time_month'] = pd.to_datetime(train_object['loans_latest_time']).dt.month
date_temp['loans_latest_time_day'] = pd.to_datetime(train_object['loans_latest_time']).dt.day
date_temp.fillna(date_temp.median(), inplace=True)  # 使用中位数填充缺失值

4 数值特征

制图函数 - 与结果的关系

# 参考文章:
# https://zhuanlan.zhihu.com/p/33733586
# https://www.cnblogs.com/jin-liang/p/9011771.html
# https://blog.csdn.net/Jinlong_Xu/article/details/79769730
# https://www.jianshu.com/p/4b925654f506

import matplotlib.pyplot as plt

result = "status"
def sns_violinplot(train, feature, y_result=result):
    """ 类别特征对应的特征分布 - 提琴图 """
    sns.violinplot(x=y_result, y=feature, data=train)

sns_violinplot(train_num, "consfin_avg_limit") # 示例

确认缺失值的情况

train.isnull().sum().sort_values() / len(train) * 100

不难发现除了 student_feature 缺失值在 63% 以外,其余的都不是非常多,这里使用平均值来补充

  1. student_feature:使用0来填充
  2. other:使用均值来补充
train_num.fillna({'student_feature': 0}, inplace=True)
train_num.fillna(train_num.mode(), inplace=True) # 众数
# train_num.fillna(train_num.mean(), inplace=True) # 均值
# train_num.fillna(train_num.median(), inplace=True) # 中位数

问题

  1. 问题1:dtype=object使用的问题,会全部转换成字符型
train = pd.read_csv('{0}/data.csv'.format(PATH), encoding='gbk', dtype=object)  # 取消 dtype=object 的使用
  1. 问题2:时间日期的处理 有没有更好的方法直接转换
  2. 问题3:如何在一个for循环里面制作所有的提琴图,有待解决
for col in train_num.columns.tolist()
	sns_violinplot(train_num, "consfin_avg_limit") # 示例
  1. 整理文档1:各种图形分析
  2. 整理文档2:pandas学习:对series和dataframe
  3. 整理文档3:数据分析中常用数据类型的处理方法

参考文档


[1] Feature Engineering for Machine Learning - 书本翻译
[2] 特征处理 - 七月在线
[3] 特征选择
[4] 缺失值处理

猜你喜欢

转载自blog.csdn.net/q370835062/article/details/84436445