问题描述:
整体任务就是用深度学习做一个回归任务,通过CMU的一组源自美国的数据来预测新冠病毒阳性案例数。
数据:


一个很简单的回归任务,难点在于筛选特征和调参
作业代码思路:
1.simple baseline就是助教提供的代码,直接运行即可。
2.medium baseline两个实现方法:一个采用特征选择 另一个采用模型融合 + 借鉴一些调参3. Strong baseline 暂定思路:先从所有特征中抽取5+5+4(最后一天的阳性比例是label,去除),然后在做模型融合
4. 整体代码的逻辑如下图所示:![]()
![]()
Trick 1:特征抽取
code来源,代码有些许错误,小节末会提出
1.1 代码整体思路
在整张表上做相关系数分析,看哪些特征和我们要预测的目标tested_positive.2最相关,相关系数的阀值设为0.8,没有要求随便设建议0.4以上
- 实现
feature = target_col[target_col > 0.8] #在最后一列相关性数据中选择大于0.8的行,这个0.8是自己设的超参,大家可以根据实际情况调节
feature_cols = feature.index.tolist() #将选择特征名称拿出来
feature_cols.pop() #去掉test_positive标签
pp.pprint(feature_cols) #得到每个需要特征名称列表 **pp**是个包 我反正很少
feats_selected = [cols.index(col) for col in feature_cols] #获取该特征对应列索引编号,后续就可以用feats + feats_selected作为特征值
feats_selected
- 结果
参考上文的特征输出,接下来依葫芦画瓢数据加载器,网络构建,训练测试验证,结果可视化,即可完成。
参数我没有调太多,没有太多话语权,不推荐了。
建议大家能够简单调参,把精力花在重点上
Trick 2:模型融合
code来源,代码很淳朴,看起来思路很清晰,但是真的写起来很累的吧
2.1 读取数据
1.每条训练样本由95列构成,含义如下:
[0]:样本id,无有效信息,可删除
[1,40]:所在州的one-hot表示
[41,58]:2d前的特征
[59,76]:1d前的特征
[77,95]:当天特征
2.将样本重新组合成1d、2d、3d三种数据集,数据维度如下:
day | train | pred |
---|---|---|
1 | (9886,58) | (893,57) |
2 | (6293, 76) | (893, 75) |
3 | (2700, 94) | (893, 93) |
2.2 特征工程
特征归一化:将非one-hot特征缩放至0~1范围
样本shuffle:原始数据中样本按州排序,需要将样本随机打散
数据拆分:将数据集拆分为训练集和测试集,其中测试集占比10%
day | train | test |
---|---|---|
1 | (8897, 57) | (989, 57) |
2 | (5663, 75) | (630, 75) |
3 | (2430, 93) | (270, 93) |
2.3 模型构造与训练
使用dnn为三种数据集构建三个不同的模型,这边原code是用sklearn写的cpu版本,跑起来巨慢,我们可以在原来的code上修改数据加载器那一部分代码
2.4 模型融合
# 构造样本
def gen_merge_feature(train_3d_df):
part_d1_cols = cols[:40]+cols[-18:-1]
part_d2_cols = cols[:40]+cols[-36:-1]
part_d1_df = train_3d_df[part_d1_cols]
part_d2_df = train_3d_df[part_d2_cols]
part_d3_df = train_3d_df[cols[:-1]]
sc_d1_feature = scale_fea(sc_1d,part_d1_df,'test')
sc_d2_feature = scale_fea(sc_2d,part_d2_df,'test')
sc_d3_feature = scale_fea(sc_3d,part_d3_df,'test')
pred_1d = network_1d.predict(sc_d1_feature)
pred_2d = network_2d.predict(sc_d2_feature)
pred_3d = network_3d.predict(sc_d3_feature)
merge_feature = np.hstack([pred_1d,pred_2d,pred_3d])
return merge_feature
cols=list(train_3d_df.columns)
merge_feature = gen_merge_feature(train_3d_df)
merge_labels = train_3d_df[cols[-1]]
train_merge_x,test_merge_x,train_merge_y,test_merge_y = train_test_split(merge_feature,merge_labels,test_size = 0.1)
print(train_merge_x.shape)
"""输出 (2430, 3)"""
#训练模型
#效果检查
pred_merge = network_merge.predict(test_merge_x)
diff = pred_merge.reshape(1,-1)[0] - test_merge_y.values
weights = network_merge.get_weights()
print(np.mean(abs(diff)),np.var(diff))
print(weights)
plt.figure(figsize=(15,5))
plot_history(history_merge,1)
#提交结果
- 结果
总结:
基本上这两个trick在历年的实验中都是通用的做法,我记得之前PM2.5的回归任务也是这些方法,最后达到了不错的结果。特征抽取+模型融合yyds。
雁过还留声,我这条咸鱼最起码学过也该留点7788。俺的文笔下水道,文章不指望大家称赞,给找作业资料的宝们提供点线索,下个作业见。
特别鸣谢
- https://www.kaggle.com/kidnarcissus/hw1-20210624-merge-model#%E7%BB%98%E5%88%B6%E6%9B%B2%E7%BA%BF
- https://www.kaggle.com/kidnarcissus/hw1-20210624-merge-model#%E7%BB%98%E5%88%B6%E6%9B%B2%E7%BA%BF
- https://github.com/PolarisRisingWar/lihongyi-2021-colab/blob/main/HW1_strong_baseline.ipynb
- https://blog.youkuaiyun.com/PolarisRisingWar/article/details/117229529?spm=1001.2014.3001.5501