时序预测赛-读书笔记2
Day 3 时序规则
时间序列规则法
本次时间序列规则法(按周提取周期因子)的步骤:
- 截取近半年的数据作为提取规则的时段period
total_balance = df.copy()
total_balance = total_balance[['date', 'total_purchase_amt', 'total_redeem_amt']]
total_balance = total_balance[(total_balance['date'] >= datetime.datetime(2014,3,1)) & (total_balance['date'] < datetime.datetime(2014, month_index, 1))]
# 加入时间戳
total_balance['weekday'] = total_balance['date'].dt.weekday # Monday=0, Sunday=6
total_balance['day'] = total_balance['date'].dt.day
total_balance['week'] = total_balance['date'].dt.week
total_balance['month'] = total_balance['date'].dt.month
- 按照weekday进行分组,统计每个weekday的购买赎回均值
mean_of_each_weekday = total_balance[['weekday','total_purchase_amt','total_redeem_amt']].groupby('weekday',as_index=False).mean()
for name in ['total_purchase_amt','total_redeem_amt']:
mean_of_each_weekday = mean_of_each_weekday.rename(columns={name: name+'_weekdaymean'})
- 每个weekday的购买和赎回量 / grand mean of the extractive period(提取时期内购买和赎回的总均值)
mean_of_each_weekday['total_purchase_amt_weekdaymean'] /= np.mean(total_balance['total_purchase_amt'])
mean_of_each_weekday['total_redeem_amt_weekdaymean'] /= np.mean(total_balance['total_redeem_amt'])
- 合并到total_balance
total_balance = pd.merge(total_balance, mean_of_each_weekday, on='weekday', how='left')
- 按日统计每日出现的weekday次数
weekday_count = total_balance[['day','weekday','date']].groupby(['day','weekday'],as_index=False).count()
weekday_count = pd.merge(weekday_count, mean_of_each_weekday, on='weekday')
- 依据频次对weekday因子进行加权,获得日期因子, 权重即为每个(1~31)号出现的weekday频率 / 统计周期内的月份
weekday_count['total_purchase_amt_weekdaymean'] *= weekday_count['date'] / total_balance['month'].nunique()
weekday_count['total_redeem_amt_weekdaymean'] *= weekday_count['date'] / total_balance['month'].nunique()
day_rate = weekday_count.drop(['weekday','date'],axis=1).groupby('day',as_index=False).sum()
最后得到的日期因子。
如下图所示:
获取更科学的base数据
如果base数据仅使用单一月或者某一段时间的数据,可能会无法避免异常数据(如某一时间段由于节日、营销或者舆情,导致购买赎回量异于往常)影响,因此为了获取更科学的base数据,需要去除周期。
# 将训练集中所有日期的均值剔除日期残差得到base
day_mean = total_balance[['day', 'total_purchase_amt','total_redeem_amt']].groupby('day',as_index=False).mean()
day_pre = pd.merge(day_mean, day_rate, on='day', how='left')
# 去除周期
day_pre['total_purchase_amt'] /= day_pre['total_purchase_amt_weekdaymean']
day_pre['total_redeem_amt'] /= day_pre['total_redeem_amt_weekdaymean']
Day 4 特征工程
特征工程从EDA中来。
根据EDA结论,特征工程主要添加了以下几种特征:
-
基于日期的静态特征提取
-
提取is特征
包括:
- 是否为节假日
- 是否为周末
- 是否为假日第一天/最后一天
- 是否为节假日后上班的第一天
- 是否不用上班
- 是否明天要上班
- 昨天是否上班
- 是否为放假前一天
- 是否周日要上班
- 是否是月初第一天
- 是否是月末第二天
- 是否是月初、月中、月末
- 是否是每月第一个、第二个、第三个、第四个周
-
-
基于距离特征提取
-
距离特征提取
包括:
- 距离放假还有多少天
- 距离上班还有多少天
- 距离节假日还有多少天
- 距离节假日最后一天还有多少天
- 距离月初(1号)还有多少天
- 距离月中心点(15号)还有多少天
- 距离星期的中心点(周3)还有多少天
- 距离星期日(weekday == 6)还有多少天
-
-
波峰波谷特征
- 绘制购买赎回月时序图,观察波峰波谷规律,并确定波峰波谷日期
- 距离波峰多少天
- 距离波谷多少天
- 绘制购买赎回月时序图,观察波峰波谷规律,并确定波峰波谷日期
-
加入周期因子特征
-
加入动态时序特征
- 按每个weekday来添加动态特征,包括:
- 中位数 median
- 均值 mean
- 最小值 mean
- 最大值 max
- 标准差 std
- 偏度 skew
- 按每个weekday来添加动态特征,包括:
特征相关性分析
使用方法:
-
相关系数(斯皮尔曼、皮尔逊)分析(低于设定阈值的特征舍弃)
-
kdeplot可视化剔除无法有效分割数据集的特征
-
使用MVTest挽回一些有依赖性但不相关的特征
-
剔除复共线特征
-
解释:
所谓多重共线性是指线性回归模型的解释变量之间由于存在精确相关关系或者高度相关关系而使模型评估失真或者不准确。
-
解决方法:
- 使用皮尔逊相关系数对各个特征进行检验,剔除相关性高于设定阈值的特征
-
-
使用shap包获得优胜特征
-
解释:
SHAP Value为正,表明变量对预测值有促进作用
SHAP Value为负,表明变量对预测值有抑制作用
绝对值越大 => 对预测影响越大
-
-
使用Permutation importance包获取优胜特征
-
解释:
一个特征被处理为随机数后,若模型效果下降明显,则认为该特征重要
-
最终选择特征
由上述方法分别筛选后的特征取交集,获得最终选择的特征。