Part 5:模型构建与总结
终于到了模型,前面折腾了这么多东西,其实模型已经不是什么障碍了。上一部分拿出了一个大佬的作品介绍特征工程,此处可以结合模型学习一个:糖尿病预测方案简介
模型构建这一块的流程想必筒子们在算法学习中学了不少,只是缺少的是数据预处理和特征工程的经验,这里对于建立模型的流程不啰嗦。经过前面的步骤我们得到了用于训练和预测的、具有大量有效的特征的数据集,各种模型的接口都很统一,在模型构建方面介绍几点如下:
1)根据具体情况选择合适的模型,但是这种竞赛那几种常用的、优秀的模型足矣,线性模型,决策树、SVM等原理还是要十分熟悉,但是模型的选择上基本是GBDT,XGBoost,lightGBM, 当然深度神经网络也有优势。
不熟悉这几种模型的去学习原理和应用,都是基于决策树的,若要真正掌握,还是要从决策树的理论和公式逐步推导、理解,是一份很有意义、也很难啃的工作。此处提供几个博客学习,这几篇博客实在很棒,还附有其他文献资料,鄙人才疏学浅不敢瞎讲,全看大佬的即可。
XGBoost和lightGBM是sklearn包之外的工具包,需要额外安装,linux系统安装会很爽,win系统xg不好弄,本人也没搞定,每次用模型还是要换到ubuntu,lgb可以在win上面安装,pip即可,也有对应的翻译好的中文文档供大家学习:
还有一种称为stack的集成模型,不建议初学者使用,不过我们可以看一看拓宽视野,有兴趣的可以找一些详细的资料和教程,亲自尝试一下。第二个是我们组使用的,感觉对于这种比赛的问题(数据量小,目标值不平衡),复杂的模型并不是关键,关键的是对题目的分析和正确的思路,所以此处并不推荐,仅作为一项知识提供出来。还是建议大家在特征上下功夫然后使用上面的模型。
Stacked Regressions to predict House Prices
XGBoost, LightGBM, and OLS and NN
2)模型的调参和交叉验证,用sklearn包的工具即可,xgb和lgb都有自带的cv函数,用起来也不错。比赛中线下交叉验证分数和线上分数(一天评测两次)如果相差很远应当反思模型的过拟合问题,甚至要反思所用数据和特征存在的问题。
3)鄙人小组所用的模型最后比较混乱,结合了先分类后回归的思想,6.1以下的用GBDT+LR的思路来做(代码如下),6.1以上的用stack模型的结果加以修正。这里面可以看到数据挖掘千变万化,一,选择6.1还是11.1作为切分点,依据什么划分,训练集中6.1以上的有1000个,11.1以上的有100个;二,我们并没有做分类模型,如果要做一个分离器又该怎么做(很可能数据的处理和特征构造都不同,比如血糖值38的就不能筛掉了,因为此时他是一个正样本),三,对于6.1以上的结果如何修正(加减乘除)。模型这一部分说到这份儿上其实也是一个复杂的问题,并不是简单的调包调参,当然这一部分和算法思路part-2密切相关,应该在对题目的分析和理解的基础上有个宏观的思路,在构建模型的时候微观调整。
4)我们这种后验修正不方便得到线下分数,靠感觉,(其他参赛的也有进行后验修正的,但是由于AB榜,到B榜分数并不理想)组内同学发现了不同模型得到的结果的特点,有点忘记了,大体上神经网络结果偏大,gdbt+lr这个偏小,什么原因我想我们在实践中对模型和特征深刻认识后方能解答。
这里只贴出gbdt+lr这个模型,可以参考这个博客:GBDT原理及利用GBDT构造新的特征-Python实现,这一方法构造了更多特征,弥补我当时不会构造特征的弊端。在part-4特征的基础上,模型部分代码如下:
n_estimator = 100 X, y = np.array(all_x) , np.array(train_y) y_pred_grd_lr = np.zeros(1000) score_t = 0 for i in [1, 2, 3, 4,5]: print('no.', i) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15) X_train, X_train_lr, y_train, y_train_lr=train_test_split(X_train,y_train,test_size=0.5) grd = GradientBoostingRegressor(n_estimators = n_estimator, max_depth = 3, min_samples_split = 2,min_samples_leaf = 3) grd_enc = OneHotEncoder(categorical_features='all') grd_lr = Lasso(alpha=0.01) grd.fit(X_train, y_train) # 训练GBDT A = grd.apply(X_train) print(A,A.shape) M1 = grd_enc.fit(A) print(M1) P_lr = grd_enc.transform(grd.apply(X_train_lr)).toarray() # 用于训练LR 的编码 print('P_lr:',P_lr.shape) M2 = grd_lr.fit(P_lr, y_train_lr) # LR 的训练 print(M2) y_pred = grd_lr.predict(grd_enc.transform(grd.apply(X_test))) # 验证集测试 score1 = mean_squared_error(y_test, y_pred) print('score:',score1/2) score_t += score1/2 y_pred_grd_lr += grd_lr.predict(grd_enc.transform(grd.apply(test_x))) # 出测试结果 print('avg:',score_t/5)
代码写的很丑,凑合看,期间print出来许多东西方便理解模型的原理。由于许多工具不会用,手动进行了五次训练。。
这一部分大概就介绍这么多吧,我们经过重重历练终于得到了不错的结果,最后啰嗦几句总结一下:
1)虽然常用的就是这几个模型,我们也应当尝试一些其他方法,其他的数据分析处理方法,其他的模型及模型的融合,对特征及模型的耦合关系多多体会,也要多学习新方法,学习大佬的思路。排行榜前几名的模型和特征不得而知。也因此,建议学习一些有详细教程的题目加强实践经验。天池有新人赛,鄙人正在学习,有几位大佬的详细教程;kaggle的Titanic题目也是如此,可供学习。
2)特征决定了模型的上限,当线下分数跑不上去(更别说线上了),应当回过头来分析数据,构造特征。数据-特征-模型的流程也要循环着来。
3)在这系列的总结中,逐渐学习到了应有的流程,养成整个流程的一套方法论,不应该跳过任何一个步骤;此外,每天付出应当有的时间也是十分必要的,否则你很难得到有效的特征。
4)一些感想,第一次接触这样的比赛,并做了漫长的博客总结,受益匪浅,希望看了博客的(尤其是几篇都看了的)对你有所帮助,并能帮助你参赛获得好成绩!
实际上新手入门的实战就介绍到这儿了。下面一部分是复赛相关的介绍和思路,有兴趣的可以看看,是一个二分类的问题。