專 欄
2017年就要过去,这一年我花了很多业余时间在学习Python 和机器学习,主要的方法就是在Kaggle 上面刷各种比赛。2017年就要过去,就以此文作为,我在2017年的机器学习的一个告别文章。
Kaggle HousePrice 特征工程部分之统计检验
Kaggle搭积木式刷分大法:特征工程部分
Kaggle搭积木式刷分大法: LB 0.11666(排名前15%)
在开篇文章- 原理中,我谈到了要:
1、总结的搭积木式刷分大法。(即,利用Pandas 的Pipe 和 Sklearn的 Pipeline)
Pandas 的Pipe 在第二篇文章中已经介绍。本文将主要介绍 Sklearn 的Pipeline. Pipeline和 Gridsearch 或RandomedSearch 联合使用,可以组合多个转换和预测的算法,并且可以调参,选算法。 后文会说明。注:后文用Gridsearch 泛指(Gridsearch 或RandomedSearch)
2、特征工程中做法的自我理解。(例如:为什么要Log transfer,正态化等)
LogTransfer 在第二篇文章也已经介绍。本文也会谈到正态化。正态化有多种方法,StandardScaler(均值为0,标准差为1), RobustScaler(针对Outlier作了特别处理)等
3、将自己碰到的问题(特征工程导致的过拟合)分享出来,求高人解惑
这个问题主要是数据泄露的问题。在训练集中作了一个新特征(每平米单价),本地CV, 结果RMSE非常好(0.05 左右)。PB的成绩就非常差(0.3左右). 主要原因是简单的利用了销售价格来产生新特征,通常这种做法,即降低了泛化成绩,也是不可取的。
SkLearn的PipLine简介
如果说Pandas的Pipe是蒸汽火车的话,Sklearn的Pipeline就是电力火车加上调度中心。火车是各种算法,调度中心让火车的算法按照顺序进行,不多也不少,不快也不慢。
在数据准备好后训练时,最基本的就是要调整超参(Hypter Parameter),耗时耗力,并且会发生错误和遗漏情况。
我自己和Stackoverflow上常见的算法训练错误有:
1、算法预测的结果差异非常大。 其中一个可能就是训练时的标准化步骤,在预测时遗漏了。
2、算法的调参结果差异非常大。(有的是0.01,有的就是10)。其中的一个可能就是不同的训练步骤中采用的标准化算法不同(例如,一次用了StandardScaler, 另一次用了RobustScaler)
3、此外,繁多的超参数调整起来异常繁琐。比较容易错误或者写错。
我的解决方法:Pipeline + Gridsearch + 参数字典 + 容器。
使用Pipeline的例子
针对线形回归问题,Sklearn提供了超过15种回归算法。利用Pipeline 大法可以综合测试所有算法,找到最合适的算法。 具体步骤如下:
1、初始化所有希望调测线形回归。
2、建立一个字典容器。{"算法名称":[初始算法对象,参数字典,训练好的Pipeline模型对象,CV的成绩}
3、在调参步骤,将初始算法用Pipeline包装起来,利用Gridsearch进行调参。调参完成后可以得到针对相应的CV而获得的最后模型对象。 例如: lasso 算法的步骤如下:
包装 pipe=Pipeline([("scaler":None),("selector":None),("clf":Lasso())
① Pipe就是刚刚包装好的算法。可以直接用于 训练(fit)和预测(predict)
② 使用Pipe来处理训练集和测试集可以避免错误和遗漏,提高效率。
③ 但是Pipe中算法是默认的参数,直接训练出的模型RMSE不太理想。(例如:local CV, 0.12~0.14左右)。这是可以考虑调参。
调参第一步:准备参数字典:
① Params_lasso ={
"Scaler":[RobustScaler(),StandardScaler()], #两个标准化算法供调模型
"selector__threshold":np.logspace(-5,-4,3), #3个选择门限供选特征
"clf__alpha":np.logspace(-5,-1,10) , #10个alpha指供调参
② 调参第二步:暴力调参和生成模型 rsearch = GridSearchCV(pipe, param_grid=Params_lasso,scoring ='neg_mean_squared_error',verbose=verbose,cv=10,refit =True)
- GridSearch 是暴力调参。遍历所有参数组合,另外有一个RandomedSearch 可以随机选择参数组合,缩短调参时间,并且获得近似的调参性能
- Pipe就是刚刚包装好的算法。GridSearch把可选的参数和算法(放入,或者更好的组合。
- 调参的训练标准是“'neg_mean_squared_error", RMSE的负数。 这种处理方法,让最大值称为最小的MSE指。只需要对结果做一次np.sqrt( 结果负数)就能获得RMSE值。
- cv=10. Cross Validate 数据集为9:1。数据集小的情况,例如House Price. 3折和10折结果甚至比调参差异还大。
- refit =True. 在调参完成后,再做一次所有数据集的fit. 生成完整的训练模型
House Price 线形回归算法比较
尽管我自己花了大量时间尝试了所有的Sklearn回归算法,得出了Lasso,Ridge, Elasticnet,SVM和GradientBoost是RMSE成绩最好的算法。其实这个结果在Kaggle 上面大多数选手也是用了这些算法,并且Sklearn的流程图也给出了完全一样的建议。 下次看看这张图,可以节约许多时间和精力。
如上图:House Price数据不到5000个样本,不用SGD。如果某些特征比较重要,就用Lasso, ElasticNet。如果不能确定,就用Ridge,SVR的线形模式,效果不好,再加上SVR的高斯内核(RBF)或者集成模式(随机森林,XGBoost或者LightGMB)
回归问题之所有,优选Lasso,Elasticnet, Ridge, SVR(线形核)。 Sklearn没有给出解释。最近,我在一本Python 机器学习预测算法核心中看的观点是:
商业需要:量化交易,在线广告业务中线形回归算法提供的高速性能和近乎最优解得性能。 在按秒来计算的业务中,线形回归算法是必须的选项。
测试迭代需求:通常一个商业问题,需要做100~200个模型。在几十万数据量时,线形算法只要花几分钟可以得到近似最优解,而集成算法往往要几个小时甚至几天。线形算法可以用来快速过来大部分表现不佳的模型。
此外:sklearn的线形算法利用了BLAS算法库。效率和集成算法相比是十几倍的提高。例如:在做CrossValidate, Lasso只需要20秒左右,而GradientBoost等集成算法需要约200~300秒左右。关于House Price,我在Kaggle 上面看到了两个信息非常有启发意义:
1、Lasso model for regression problem 在做好特征工程后,只用Lasso 就获得了0.117的方法
2、Multivariate_Data_Analysis_(7th_edition):HousePrice的冠军得主说这本书提供了非常好的参考。 这是一个基于统计的商业分析书。相对一般的机器学习书,此书比较有深度,但又不知是理论推导。其中对数据,分布,离群点不但提供了原理推导,还提供了多种工程方法去假设和验证。 最棒的是,经验法则。例如:
missing date 多余50%时候怎么处理, 少于10%怎么处理。 是随机的missing data还是有规律的, 如何检测。
outlier的检测,统计工程方法
分布检测等
Python中文社区将在元旦节进行免费送书活动,
欢迎关注!
长按扫描下方二维码,
关注“编程狗”
编 程 狗
编程大牛技术分享平台
Python 中 文 社 区
Python中文开发者的精神部落
合作、投稿请联系微信:
pythonpost