目标
关于背景不详细叙述,可以根据标题直接去Kaggle平台搜索此次比赛。最终是要根据ELO(赞助方)给出的数据做一个用户忠诚度评分预测,本质上是个回归问题。
数据集探索
赞助商给的数据文件有七个:
其中Data_Dictionary是所有数据的数据字典,即包括了所有数据个字段的含义:
sample_submission是提交结果时的范例数据。要求RMSE作为评估指标:
然后就是完成比赛的必要数据,也就是train和test两个数据集。train数据集就是训练数据,test就是测试数据集,二者特征一致,极简情况下我们可以直接在train上训练模型,在test上进行预测,当然这样的话估计结果不会好。
test数据集在模型最终预测时输入只需要处理日期,train数据集:
查看数据集信息:# train.info()
可以看到card_id对于训练精度不影响最后输入模型训练时直接删除,first_active_month是日期,需要处理,target最后训练时取出作为标签,其他数据特征是数值型且没有缺失值不需要处理。
实际比赛过程中,由于测试集的标签“不可知”,所以需要在训练集train上划分出验证集来进行模型泛化能力评估。
merchant是商户信息表
查看数据信息:
这个就比较复杂,可以看到有缺失值和inf类型数据,不是数值型数据。都需要处理。
historical_transactions 和new_merchant_transactions,是信用卡交易记录,两个数据集字段类似,只是记录了不同时间区间的信用卡消费情况:
historical_transactions:信用卡消费记录
new_merchant_transactions:信用卡近期的交易信息
一个有3千万条数据,一个有2百万条数据,数据特征(字段)相同。
数据处理与特征工程目标
我们最终的目的是将三个附加表merchant、historical_transactions 和new_merchant_transactions中的信息提取并合并到train.csv中。然后处理并选择合适的特征输入模型训练。
数据预处理
离散变量字典编码:对离散变量进行字典编码,即将object对象类型按照sort顺序进行数值化(整数)编
码。例如原始category_1取值为Y/N,通过sort排序后N在Y之前,因此在重新编码时N取值会重编码为0、Y取值会重编码为1。以此类推。
需要注意的是,从严格角度来说,变量类型应该是有三类,分别是连续性变量、名义型变量
以及有序变量。连续变量较好理解,所谓名义变量,指的是没有数值大小意义的分类变量,例如
用1表示女、0表示男,0、1只是作为性别的指代,而没有1>0的含义。而所有有序变量,其也是
离散型变量,但却有数值大小含义,如上述most_recent_purchases_range字段,销售等级中
A>B>C>D>E,该离散变量的5个取值水平是有严格大小意义的,该变量就被称为有序变量。
# 字典编码函数
def change_object_cols(se):
value = se.unique().tolist()
value.sort()
return se.map(pd.Series(range(len(value)), index=value)).values
对训练集和测试集的日期编码:
se_map = change_object_cols(train['first_active_month'].append(test['first_active_month']).astype(str))
train['first_active_month'] = se_map[:train.shape[0]]
test['first_active_month'] = se_map[train.shape[0]:]
结果日期已变成数值型:
对商户信息(merchant数据集)预处理:
1、根据业务含义划分离散字段category_cols与连续字段numeric_cols。
category_cols = ['merchant_id', 'merchant_group_id', 'merchant_category_id',
'subsector_id', 'category_1',
'most_recent_sales_range', 'most_recent_purchases_range',
'category_4', 'city_id', 'state_id', 'category_2']
numeric_cols = ['numerical_1', 'numerical_2',
'avg_sales_lag3', 'avg_purchases_lag3', 'active_months_lag3',
'avg_sales_lag6', 'avg_purchases_lag6', 'active_months_lag6',
'avg_sales_lag12', 'avg_purchases_lag12', 'active_months_lag12']
2、对非数值型的离散字段进行字典排序编码:
for col in ['category_1', 'most_recent_sales_range', 'most_recent_purchases_range', 'category_4']:
merchant[col] = change_object_cols(merchant[col])
3、为了能够更方便统计,进行缺失值的处理,对离散字段的缺失值统一用-1进行填充:
merchant[category_cols] = merchant[category_cols].fillna(-1)
4、对连续型字段探查发现有正无穷值(inf),这是特征提取以及模型所不能接受的,因此需要对无限值进行处理,此处采用最大值进行替换。
inf_cols = ['avg_purchases_lag3',