题目简述
见 House Prices: Advanced Regression Techniques
给出了可能和房价有关的79个变量,使用回归的方法预测房价
主要按照以下文章的思路,注意这篇文章只是做一个简单的笔记整理,供后查阅,因此是针对博主而言的:
数据分析:Comprehensive data exploration with Python
数据处理及线性回归在训练集上的比较:A study on Regression applied to the Ames dataset
xgboost+线性回归:Regularized Linear Models
stacking的使用:Stacked Regressions : Top 4% on LeaderBoard
最后简单的处理了一下数据成绩为0.11510
代码放在github上:
数据分析
这篇文章对数据的分析可谓经典,从中学到很多,但也有很多不是太明白
使用describe来判断DataFrame列的个数,均值,标准差,最小值,25%分位点,75%分位点,最大值
|
|
关于数据的偏度和峰度
散点图,绘制两个变量之间的关系,concat为连接,axis=1表示列上的连接
箱形图的绘制,由异常点,分位点组成,可以观察数据的集中程度,异常情况等,Plotting with categorical data中给出的解释是说散点图可以很好的绘制出两个连续变量(数值变量)之间的关系,但是对于类别变量和数值变量之间的关系就需要用到类似的箱型图了,无意中发现了知乎专栏对seaborn全部的翻译Seaborn(sns)官方文档学习笔记
下图中,我就不懂这个异常点是怎么回事,如果按照给出的文章箱形图中异常点的检测来看异常点的话,计算公式为Q1-k(Q3-Q1)和Q3+k(Q3-Q1),那么异常点应该离Q1点比较远的距离吧,但是图上为什么不是这样?
DataFrame中生成相关系数矩阵,sns通过热力图展现
上图可以清楚的显示有两个明显的淡黄块,即1stFlrSF与TotalBsmtSF,GarageCars和GarageArea,它们之间的相关性最强
这里提一下方差,协方差和相关系数,协方差是衡量两个变量的总体误差【这个解释好像并没有什么用?】,方差是协方差的特殊情况,衡量数据集离散程度,在协方差上有这么一句话:协方差作为描述X和Y相关程度的量,在同一物理量纲之下有一定的作用,但同样的两个量采用不同的量纲使它们的协方差在数值上表现出很大的差异,为此引入相关系数,我觉得这句话对于协方差的意义更容易理解。
对DataFrame中的指定列(Series)取前k个最大的行,对应的列的索引
使用np求协方差矩阵,并用热力图显示
使用sns中的pairplot绘制两两变量之间的散点图,至于在下面去掉了三对强相关中其中一个变量,强相关就是多重线性问题,在广义线性回归模型中讲到过多重线性问题的解决方案,其中之一是使用惩罚项(举到岭回归,为什么岭回归可以解决多重共线性问题,其中有公式推导,这里直观的理解就是如果有个变量是多余的,也就是说没有该变量也会达到同样的效果,而惩罚项的目的就是让权重变少或者变小,这样在惩罚项的作用下必然会将该多余变量的权重降为0),也提到删除其中之一的变量,我觉得最好不要删除而用惩罚项。
下面这个是计算DataFrame中各列空值的占比
删除缺失数据个数大于1的列
后面讲到数据的正态化我在其它文章中讲到过,这里就不重复了
在正态化中关于0值的处理直接不考虑感觉有点问题,而后续的文章中正态化处理使用的是log1p函数,即log(1+x),这样就没有这个问题了
关于将某列数据正态化后和价格列画散点图和之前没有正态化对比,变得不再是锥形了,这里不知道说明了什么?好像没写完一样…
数据处理及线性回归在训练集上的比较
这篇文章可以作为广义线性回归的实际篇,而且对数据处理上做的特别好
对空值的处理上做的很详细,分析每一列在添加空值,对数据集中有些分类特征列用数字表示,这样显然是不对的,因为这些数字大小并不能说明问题,这样的列是需要从数值列转换为字符串列(分类列)的
而有限类别类是可以用数值来表示的(表现在该特征的变化值),而不用最后使用独热编码(一个特征列变成多个特征了),如下
补一下,上面是直接对df操作,为了更清楚,下面用Series:
用下面三种方法创造新的特征(注意是增加列,而不是替换)
Simplifications of existing features
Combinations of existing features
Polynomials on the top 10 existing features
简化特征,将差别不大的归为一类
合并特征
在和价格相关性最大的十个特征上做多项式,注意对特征多项式的方法:可以看到一个特征被开根号,平方,三次方,最后都变为一列特征
偏度判断并正态化
最后独热编码
交叉验证,用方均根差来计算
线性回归模型
RMSE on Training set : 0.389629944224
RMSE on Test set : 0.4179630667
然后用岭回归模型,这里需要指定惩罚项前的系数,具体的方法是使用下面的函数
该函数会在给定的列表中选取最佳的惩罚项系数,这里获得最佳惩罚项系数后继续缩小范围,如下:
岭回归模型的结果如下:
Ridge RMSE on Training set : 0.115405723285
Ridge RMSE on Test set : 0.116427213778
可以看到相比于线性回归模型,方均误差已经小了很多,对比训练集结果和测试机结果可以看到模型的稳定性也得到了提高(即降低了过拟合)
用Lasso回归模型,该模型使用的是L1正则化,由于L1正则化没有使用平方,而导致最后拟合的结果中很多特征权重都会降为0,这对很多无关特征的高维数据集是有效的。同上原理,得出来得结果如下:
Lasso RMSE on Training set : 0.114111508375
Lasso RMSE on Test set : 0.115832132218
这个例子说明了对于高维无关数据集上的拟合Lasso回归模型更优于岭回归模型
最后提到了elasticNet模型,这里就不说明了
xgboost+线性回归
前面的数据分析及处理部分上面都包括了,这里主要讲一下xgboost的使用,如下使用xgboost做交叉验证,图中显示的是训练集误差和测试集误差的关系,显然越往后模型过拟合越明显:
test-rmse-mean test-rmse-std train-rmse-mean train-rmse-std
0 10.380138 0.007834 10.380139 0.003413
1 9.344810 0.008219 9.344813 0.003153
2 8.413089 0.008584 8.413092 0.002927
3 7.574992 0.008599 7.574618 0.002707
4 6.820292 0.008262 6.819935 0.002493
最后做了一下简单的模型相加,效果还不错,能够达到0.120
stacking的使用
这里需要继承scikit-learn的基类,BaseEstimator为估计的基础类,RegressorMixin是回归的基类,TransformerMixin是转换类的基类
其实下面这个自定义类就是将每个模型取个平均
使用上面的模型训练数据:
相对于单模型提高了进一个百分点,但是上面这个模型只是简单的对每个模型进行平均就能达到这样的效果
继续使用正宗的stacking方法,如下图所示,其原理就是用交叉验证的方法来预测训练集,比如5折,进行5次【这里代码中给出的是5个相同的模型,而图中显示的是不同的模型】,每次用其他的4部分训练,取预测剩下的一部分,这样5次后就会生成一个完整的对训练集的预测结果,分别用多个模型进行上面的步骤,就会得到多组对训练集预测的结果集,最后用基模型训练这个结果集,结果集作为自变量(x),训练数据的因变量(y)作为该模型的因变量。预测的时候,先使用5次中的模型来预测测试集,并取均值;然后再用多个模型进行上述过程,得到多组预测集,再使用基模型对预测集进行预测,即为最终的结果,如下图:
代码如下(此处对于5折并没有使用多模型,我觉得这样训练的模型更加稳定):
最后用了stacking后,将stacking的结果和Lightgbm和XGBoost的结果做了简单的加权:
确实觉得前面那篇数据处理部分做的太好了,只不过我改不过来了(太麻烦了),就只是简单的将第三部分的结果和第四部分的结果加权了一下,得出的结果由第四部分的0.1511变为0.1510
到此就先结束了。