波士顿房价问题
这个是Kaggle专栏的第二篇,赛题名是: House Prices - Advanced Regression Techniques。在本文中,你将会学习到:
- 单、多变量分析
- 相关性分析
- 缺失值和异常值处理
- 哑变量转换
原notebook地址:https://www.kaggle.com/pmarcelino/comprehensive-data-exploration-with-python
排名榜
让我们看下排名榜,第一名真的是碾压其他选手呀~所以,今天我们一起看看这个第一名的方案到底是多棒?
数据介绍
这份波士顿房价的数据集有4份数据,训练集train+测试集test+数据集的描述description+提交模板sample
其中训练集有81个特征,1460条数据;测试集81个特征,1459条数据。看下部分属性介绍:
数据EDA
导入模块和数据,并进行数据探索:
导入库
1 | import pandas as pd |
导入数据
数据信息
训练集整体是1460*81;而且很多的存在字段都存在缺失值
描述统计信息:
销售价格SalePrice分析
前原notebook文档中,作者分析了很多自己关于这个题目和字段的看法,具体不阐述。下面介绍的是重点部分:
统计信息
单单看这个字段的统计信息:
分布直方图如下,我们明显感受到:
- 价格的分布偏离了正态分布
- 有明显的正偏度现象
- 有明显的峰值出现
偏度和峰度(skewness and kurtosis)
知识加油站:偏度和峰度
详细的解释参见文章:https://zhuanlan.zhihu.com/p/53184516
- 偏度:衡量随机变脸概率分布的不对称性,是相对于平均值不对称程度的度量,通过对偏度系数的测量,我们能够判定数据分布的不对称程度以及方向。
- 峰度:是研究数据分布陡峭或者平滑的统计量,通过对峰度系数的测量,我们能够判定数据相对于正态分布而言是更陡峭还是更平缓。峰度接近0,数据呈现正态分布;峰度>0,高尖分布;峰度<0,矮胖分布
偏度的两种分布情况:
- 如果是左偏,则偏度小于0
- 如果是右偏,则偏度大于0
峰度的两种分布情况:
- 如果是高瘦型,则峰度大于0
- 如果是矮胖型,则峰度小于0
1 | # 打印销售价格的偏度和峰度 |
偏度和峰度值都是正的,明显说明数据是右偏且高尖分布
SalePrice和数值型字段的关系
首先我们考察和居住面积的关系:
1 | plt.figure(1,figsize=(12,6)) |
1 | # plotly版本 |
TotalBsmtSF VS SalePrice
1 | # 2、TotalBsmtSF |
小结:我们可以观察到这两个特征和销售价格之间是存在一定的线性关系。
价格和分类型字段的关系
1、OverallQual VS SalePrice
1 | # 1、OverallQual:整体房屋质量 |
1 | 5 397 |
1 | data = train[["SalePrice","OverallQual"]] |
2、YearBuilt VS SalePrice
住在建造年份和销售价格的关系
1 | data = train[["SalePrice","YearBuilt"]] |
小结:销售价格和住宅的整体质量有很强的关系;但是和建筑年份的关系不大。但是在实际的买房过程中,我们还是会很在意年份
小结
对上面分析的一点小结:
- 地面生活区(GrLivArea)、地下室面积(GrLivArea)和销售价格SalePrice都是呈现正向的线性相关
- 房屋的整体质量(OverallQual)和建造年份(YearBuilt)好像也和销售价格线性相关。常识来说,整体的质量越好,价格越贵
相关性分析
为了探索众多属性之间的关系,进行如下的分析:
- 两两属性间的相关性(热力图)
- 销售价格saleprice和其他属性的关系(热力图)
- 关联性最大的属性间的关系(散点图)
整体相关性
分析每两个属性的相关性,并绘制热力图
上图中有两个值得关注的点:
- TotalBsmtSF and 1stFlrSF
- GarageCar and GarageArea
这两组变量都是强相关的,我们后续的分析只取其中一个
缩放相关矩阵(销售价格saleprice)
从上面的热力图中选择和SalePrice相关性最强的前10个特征来绘制热力图
1 | sns.set(font_scale=1.25) |
小结1
通过上面的缩放热力图,我们可以得到下面的结论:
- ‘OverallQual’, ‘GrLivArea’ and 'TotalBsmtSF’是真的和’SalePrice’呈现强相关
- ‘GarageCars’ and ‘GarageArea’ 也是两个相关性比较强的特征;而且他们都是同时出现,后续选取GarageCars进行分析
- 建筑年限’YearBuilt’相对来说,相关性比较低
变量离散图
将销售价格SalePrice和几个相关性比较强的特征放在一起,绘制变量离散图
1 | sns.set() |
小结2
正对角线方向上是变量的直方图,解释变量和被解释变量SalePrice,其他的则是散点图。
如果图中呈现直线或者横线的散点,则说明该变量是离散的,比如第1行4列的变量,y轴是SalePrice,x轴是YearBuilt,直线说明YearBuilt是离散的
缺失值处理
针对缺失值的情况,主要是讨论两点:
- 缺失值分布情况怎么样?
- 缺失值是随机的?还有具有某种规律
缺失值占比
1、查看每个字段的缺失值情况
1 | # 每个字段的缺失值数量:降序 |
1 | PoolQC 1453 |
2、转成百分比
1 | # 每个字段的缺失值 / 总数 |
1 | PoolQC 0.995205 |
3、数据合并,整体的缺失值情况:
删除缺失值
原文中分析了很多,最后的结论:
In summary, to handle missing data,
1、we’ll delete all the variables with missing data, except the variable ‘Electrical’.
2、In ‘Electrical’ we’ll just delete the observation with missing data.
1 | # 步骤1:需要删除的字段 |
1 | Index(['PoolQC', 'MiscFeature', 'Alley', 'Fence', 'FireplaceQu', 'LotFrontage', |
1 | # 第一步 |
离群点out liars
查找离群点
1 | ## 数据标准化standardizing data |
1 | array([[ 0.34704187], |
1 | # 查看前10和最后10位的数据 |
小结3
- low_range接近,且离0比较近
- high_range离0很远;且7+的数据就应该是离群点了
单变量分析1
1 | data = train[["SalePrice","GrLivArea"]] |
很明显的,两个变量(属性)存在一种线性关系
删除离群点
指定删除某个字段为具体值的方法:
单变量分析2
1 | data = train[["SalePrice","TotalBsmtSF"]] # 待分析的两个变量 |
深入理解SalePrice
主要从以下几个方面来深入研究销售价格:
- Normality:归一化
- Homoscedasticity:同方差性
- Linearity:线性特质
- Absence of correlated errors:相关误差
Normality归一化(SalePrice)
1 | sns.distplot(train["SalePrice"],fit=norm) |
我们发现:销售价格不是正态分布的,出现了右偏度;同时也不遵循对数变化的规律。
为了解决这个问题:实施对数变换
1 | ## 对数变换 |
实施对数变换后效果好了很多的
Normality-归一化(GrLivArea)
1 | sns.distplot(train["GrLivArea"],fit=norm) |
对数变换前的效果:
执行对数变换及效果:
1 | # 执行相同的对数操作 |
Normality-归一化(TotalBsmtSF)
1 | sns.distplot(train["TotalBsmtSF"],fit=norm) |
处理之前的效果:
如何处理上面的特殊部分?
1 | # 增加一列数据 |
同方差性
检验两个变量之间的同方差性最好的方法就是作图。
The best approach to test homoscedasticity for two metric variables is graphically
1、讨论:‘SalePrice’ 和’GrLivArea’之间的关系
2、讨论SalePrice’ 和 ‘TotalBsmtSF’
We can say that, in general, ‘SalePrice’ exhibit equal levels of variance across the range of ‘TotalBsmtSF’. Cool!
从上面的两张图中,我们看到:销售价格和另外两个变量都是呈现一定的正向关系
生成哑变量
虚拟变量( Dummy Variables) 又称虚设变量、名义变量或哑变量,用以反映质的属性的一个人工变量,是量化了的自变量,通常取值为0或1。
Pandas中的get_dummies函数能够实现:
1 | train = pd.get_dummies(train) # 生成哑变量 |
总结
至此,我们完成了以下的内容:
- 整体变量间的相关性分析
- 重点分析了变量“SalePrice”
- 处理缺失值和异常值(离群点)
- 做了一些统计分析,将分类变量变成了哑变量
自己需要后续补充深入学习的点:
- 多元统计分析
- 偏度和峰度
- 哑变量的深入
- 标准化和归一化
看完整篇文章的分析过程,有什么感受呢?