Kaggle机器学习实战(2)——房价预测(上)
kaggle房价预测是一个典型的回归问题。该问题提供了数千条房屋的房价和大量的特征变量,需要挑战者训练回归模型并预测测试集上房屋的房价,追求最小的均方误差。
这篇文章翻译自其中点赞数量最多的一篇kernel,它主要讲的是探索性数据分析这一方面。
导入数据
1 | # 调包 |
注意:%matplotlib inline
是一个魔法函数,可以让matplotlib在Jupter Notebook中直接绘图,否则要使用plt.show()
才能显示图片。
1 | # 读取csv格式的训练集 |
观察变量
训练集包含1460个样本,每个样本包含详细概括房子的各个信息的变量共计79个,以及它们的房价。
首先,搞清这79个变量是数值型(numerical)还是标称型(categorical)变量。然后我们根据生活中的实际经验,对可能影响房价的因素分成三大类:建筑本身,空间大小和区位。接着,对每个因子的重要性进行预估。
在依靠直觉对每个变量的重要性进行评估时,可以用三个问题作为标准:
- 假如你在买房,你会考虑这个因素吗?
- 如果你要考虑这个因素,你会把它摆在第几位?
- 这个因素是否和其他因素有些重合?
据此就可以筛选出主观上较重要的因子。
1 | # 显示变量名 |
主观上认定以下变量与房价存在显著的相关性:
OverallQual
(房屋的总体质量):代表房屋质量的一个重要变量。YearBuilt
(房龄):代表房屋质量的另一个重要变量。TotalBsmtSF
(地下室总面积)、GrLivArea
(地上居住面积):这个很容易理解。
除了“房屋本身的质量”和“面积”这两大因素之外,很显然“区位”也是影响房价必须考虑的一项,但原数据给出的区位相关变量都是诸如周围有哪些地标建筑、靠近哪些交通枢纽这些无法直接体现区位优劣的变量,并且它们难以可视化。我们暂时不考虑它们。
数据可视化
先观察预测变量Y:房价。它是一个连续型的变量。
1 | # 描述性统计 |
从图可知,训练集的房价呈现偏态分布。分析偏度和峰度:
1 | # 偏度和峰度 |
我们希望因变量能服从正态分布,因为这将大大提升线性模型的性能。之后会使之变换为正态分布。
接下来可视化“主观上认为比较重要的变量”。
与数值型变量的关系
1 | # 地上居住面积/房价散点图 |
以上两个图可以在Jupter Notebook中自行绘制。从图上可以直观的看出,这两个变量都与房价正相关。值得注意的是这两个散点图出现了很多零散的不符合规律的点(离群值)。
与标称型变量的关系
1 | # 房屋质量/房价箱型图 |
很显然,房价与房屋质量(OverallQual
)呈正相关。
1 | # 房子修建的年份/房价箱型图 |
这里,房屋的修建年份(YearBuilt
)和房价似乎只有微弱的正相关性,但仍可以认为绝大多数情况下,越新的房子越能卖个高价。
对以上四个变量的可视化做个总结:
- “地上居住面积”(
GrLivArea
)和“地下室面积”(TotalBsmtSF
)与房价呈显著的正相关,且“地下室面积”与房价拟合的直线斜率较大。 - “房屋质量”(
OverallQual
)和“修建年份”(YearBuilt
)与房价也具有相关性,其中“房屋质量”相关性更强。
接下来,观察其他变量。客观地讲,它们是同等重要的。
与其他变量的关系
1 | # 所有变量的相关性矩阵热图 |
seaborn
的热图是快速了解变量之间关系的极佳方法。我们主要关心浅色和深色区块,它表示两个变量之间具有强烈的正/负相关。在线性模型中,若自变量之间具有线性关系会对模型的性能产生影响,因为它们包含重复的信息,应当舍去。
从第一张图我们看出,“地下室面积”(TotalBsmtSF
)和“一楼面积”(1stFlrSF
)这两个变量高度正相关,以及车库系列变量(GarageCars
, GarageArea
)之间具有很强的关联(这些也符合我们的生活经验),我们将会只保留其中一个与房价相关性更高的变量。
第二张图主要是看与预测变量Y最相关的10个变量之间的相关性。我们可以更加清楚的看到这些变量之间的相关系数。这top10里面出现了地上面积、地下室面积、建筑质量和修建年份这些指标,证实了我们第一步的猜想;“地上居住面积”(GrLivArea
)和“地上房间总数”(TotRmsAbvGrd
)非常相关,因此我们只保留其中一个。
得到了与Y有较高关联性的特征(并剔除了一些相似的特征),我们接下来用散点图来进一步查看变量之间的联系。
1 | # 房价与一些变量的关系的散点图 |
我们发现“地下室面积”(TotalBsmtSF
)和“地上面积”(GrLiveArea
)的散点图上,有一串点可以连成一条直线。观察房价与修建年份的散点图,这些点云的上界和下界呈指数函数状分布,而近几年修建的新房的房价保持在指数函数上方,推测近几年房价涨的更快了。
至此我们初步完成了数据的可视化。
处理缺失值
在着手处理缺失值之前,我们要考虑清楚:
- 数据缺失的现象有多普遍?
- 丢失的数据是随机的,还是有规律可循的?
缺失值的处理要谨慎,我们显然不希望训练样本大量流失。此外,数据的缺失可能导致预测结果出现偏见以及歪曲事实。
首先,统计出缺失的变量及其频率。
1 | # 缺失值查看 |
Total | Percent | |
---|---|---|
PoolQC | 1453 | 0.995205 |
MiscFeature | 1406 | 0.963014 |
Alley | 1369 | 0.937671 |
Fence | 1179 | 0.807534 |
FireplaceQu | 690 | 0.472603 |
LotFrontage | 259 | 0.177397 |
GarageCond | 81 | 0.055479 |
GarageType | 81 | 0.055479 |
GarageYrBlt | 81 | 0.055479 |
GarageFinish | 81 | 0.055479 |
GarageQual | 81 | 0.055479 |
BsmtExposure | 38 | 0.026027 |
BsmtFinType2 | 38 | 0.026027 |
BsmtFinType1 | 37 | 0.025342 |
BsmtCond | 37 | 0.025342 |
BsmtQual | 37 | 0.025342 |
MasVnrArea | 8 | 0.005479 |
MasVnrType | 8 | 0.005479 |
Electrical | 1 | 0.000685 |
Utilities | 0 | 0.000000 |
通常情况下,我们考虑当某一个变量的缺失值超过15%,就直接删除这个变量,而不是尝试去填充它。按这个思路,“泳池质量”(PoolQC
)、“杂项(电梯等)”(MiscFeature
)、“屋旁小巷类型”(Alley
)、“栅栏质量”(Fence
)等几个变量就应当剔除。关键在于我们抛弃这些数据会错失一些有用信息吗?我认为不会,因为我们在买房时不会重视这些信息。所以可以放心删除它们。
在剩下来的变量中,车库系列变量(GarageX
)缺失的数目相同。考虑到有关车库的信息中最重要的是容量(GarageCars
),因此我们可以删除这些不怎么重要的变量。同理,我们对地下室系列变量(BsmtX
)做同样的处理。
对于“砌砖面积”(MasVnrArea
)及其材质(MasVnrType
)这两个变量,我们认为它不重要,并且它们与“修建年份”(YearBuilt
)和“房屋总体质量”(OverallQual
)有很强的相关性。因此,抛弃这两个变量不会丢失重要信息。
最后,在“电气系统”(Electrical
)这个变量中有一个确失值,我们选择删除包含这个缺失值的样本,并保留这一变量。
1 | # 缺失值处理 |
处理离群值
离群值就是指数据中偏离其他数值较大的数值。离群值可以显著地影响模型,并且提供了一些特例以供我们解读。这里就以预测变量Y——房价的标准差来分析。
单变量分析
我们要设定一个阈值,把部分观测值设定为离群值。首先,需要标准化数据。这里的标准化包括把数据的平均值化为0,同时标准差化为1。
1 | # 数据标准化 |
从结果中可以看出,最低的10个值偏离0都不太远,而最高的10个值中,距离0都较远。尤其是需要注意两个大于7的值。我们再做进一步的分析。
双变量分析
重新绘制与房价相关变量的散点图,这次的目的是观察离群值。
1 | # 地上居住面积/房价双变量分析 |
现在重新审视这张图可以发现:地上面积最大的两个房子,它们的价格却反常的低,我们可以推测比如这两个房子在乡下。我们要做的是把这两个样本定义为离群值并剔除,因为它们不能代表典型的情况。
上文说要留意两个偏离较大的值,也就是图中房价最高的两个点。但从这张散点图上看,这两个特殊案例符合主流趋势,因此对这两个点予以保留。
1 | # 删除离群值 |
同样,我们重新观察一下地下室面积与房价的散点图。
1 | # 地下室面积/房价双变量分析 |
可以观察到部分点(例如面积大于3000的3个)有离群的迹象,但可以接受,因此予以保留。
正态化数据
根据多重线性回归的假设检验,我们要确保数据具有以下特性:
- 正态性:残差e服从正态分布。
- 方差齐性:残差e的大小不随变量取值水平的改变而改变。
- 线性:自变量与因变量之间存在线性关系。
- 独立性:各个自变量之间不存在多重共线性问题。
现在要解决正态性问题。单变量的正态化并不能保证整个多元回归的正态性,但有一定效果。这同时可以解决异方差性的问题。
数据服从标准正态分布是我们的追求。对数据正态化的方法有很多,比如Box-Cox变换。我们已经知道这组数据中有些变量,例如因变量房价,服从偏态分布,可以用更简单的方法使之正态化。
首先我们绘制所要考察变量的柱状图和正态概率分布图。
1 | # 房价的柱状图和正太概率分布图 |
很明显这组房价满足偏态分布;用一种简单的转换方法可以使这组数据符合正态分布——取对数。
1 | # 对房价取对数 |
然后处理一个重要的自变量“地上居住面积”(GrLiveArea
):
1 | # 地上面积的柱状图和正太概率分布图 |
1 | # 对地上面积取对数 |
“地下室面积”(totalBesmtSF
):
1 | # 地下室面积的柱状图和正太概率分布图 |
处理这个变量相对比较棘手,因为有相当一部分的观测值为0。而0值是无法取对数的。除去这些0,总体上还是满足偏态分布的。因此,我们会新建一个二值变量来反映这个样本是否包含地下室,对于有地下室的样本进行对数转换,忽略无地下室的样本。(因为无法确定这种做法对不对,原作者称之为‘high risk engineering’。)
1 | # 建立一个新的列来存储新的变量 |
1 | # 对符合条件的地下室面积取对数 |
同方差性
以地上居住面积与房价关系的散点图为例,早先版本的散点图左下角密集而右上角稀疏,呈现圆锥状,这就是具有同方差性的问题。
绘制对数转换后的散点图:
1 | # 地上居住面积/房价散点图 |
可以看见我们已经解决了同方差性的问题,数据变得正态了。再来看看房价和地下室面积的关系:
1 | # 地下室面积/房价散点图 |
至此,我们可以认为这几个重要变量的正态化已经完成了。
虚拟变量
这一步将把标称型的数据one-hot化:
1 | # 把标称性变量虚拟化 |
这篇探索性数据分析的kernel就到此为止了。接下来要做的就是训练模型,将会参考另外一篇kernel。
总结
- 对于大多数Kaggle数据科学竞赛,处理数据是耗费的时间最多的、并且是对结果精度影响最大的环节。因此这篇kernel尽管没有到训练那一步,却获得了极高的点赞数。
- 探索性数据分析,包含数据可视化、处理缺失值、离群值以及数据标准化、正态化、虚拟化等等,对于数据挖掘和统计机器学习非常重要。作为初学者,要熟练运用numpy、matplotlib、pandas这三大利器。