kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)

这是这个项目的各数据变量的详细解释:https://blog.csdn.net/Nyte2018/article/details/89977261。
只有对每个变量的意思和分类都了解,才能更好的进行数据分析和处理。
由于本人是这方面的小白,也是第一次参加这种比赛,于是决定选择这个比赛kernels中几篇许多人赞同的数据分析进行学习,这次的kernel是COMPREHENSIVE DATA EXPLORATION WITH PYTHON,在jupyter notebook中运行。

1、准备工作

首先进行各种库的导入:

#invite people for the Kaggle party
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy.stats import norm
from sklearn.preprocessing import StandardScaler
from scipy import stats
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline

读取数据集文件:

#bring in the six packs
df_train = pd.read_csv('data/train.csv')

获取数据集中的列名:

#check the decoration
df_train.columns
Index(['Id', 'MSSubClass', 'MSZoning', 'LotFrontage', 'LotArea', 'Street',
       'Alley', 'LotShape', 'LandContour', 'Utilities', 'LotConfig',
       'LandSlope', 'Neighborhood', 'Condition1', 'Condition2', 'BldgType',
       'HouseStyle', 'OverallQual', 'OverallCond', 'YearBuilt', 'YearRemodAdd',
       'RoofStyle', 'RoofMatl', 'Exterior1st', 'Exterior2nd', 'MasVnrType',
       'MasVnrArea', 'ExterQual', 'ExterCond', 'Foundation', 'BsmtQual',
       'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinSF1',
       'BsmtFinType2', 'BsmtFinSF2', 'BsmtUnfSF', 'TotalBsmtSF', 'Heating',
       'HeatingQC', 'CentralAir', 'Electrical', '1stFlrSF', '2ndFlrSF',
       'LowQualFinSF', 'GrLivArea', 'BsmtFullBath', 'BsmtHalfBath', 'FullBath',
       'HalfBath', 'BedroomAbvGr', 'KitchenAbvGr', 'KitchenQual',
       'TotRmsAbvGrd', 'Functional', 'Fireplaces', 'FireplaceQu', 'GarageType',
       'GarageYrBlt', 'GarageFinish', 'GarageCars', 'GarageArea', 'GarageQual',
       'GarageCond', 'PavedDrive', 'WoodDeckSF', 'OpenPorchSF',
       'EnclosedPorch', '3SsnPorch', 'ScreenPorch', 'PoolArea', 'PoolQC',
       'Fence', 'MiscFeature', 'MiscVal', 'MoSold', 'YrSold', 'SaleType',
       'SaleCondition', 'SalePrice'],
      dtype='object')

2、SalePrice分析

获取saleprice列的详细数据情况:

#descriptive statistics summary
df_train['SalePrice'].describe()
count      1460.000000
mean     180921.195890
std       79442.502883
min       34900.000000
25%      129975.000000
50%      163000.000000
75%      214000.000000
max      755000.000000
Name: SalePrice, dtype: float64

可以看出训练集中一共有1460行数据,平均值为180921.195890等信息。
获取saleprice列的直方图:

#histogram
sns.distplot(df_train['SalePrice']);

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第1张图片
可以看出数据偏离了正态分布,是明显的正偏斜,即偏度大于0。具体的偏度和峰度(反映了峰部的尖度,如果峰度大于三,峰的形状比较尖,比正态分布峰要陡峭):

#skewness and kurtosis
print("Skewness: %f" % df_train['SalePrice'].skew())
print("Kurtosis: %f" % df_train['SalePrice'].kurt())
Skewness: 1.882876
Kurtosis: 6.536282

3、SalePrice与其它变量的关系

先来看看与数字变量的关系,SalePrice与GrLivArea(地面上居住面积(平方英尺))的关系用散点图表示:

#scatter plot grlivarea/saleprice
var = 'GrLivArea'
data = pd.concat([df_train['SalePrice'], df_train[var]], axis=1)
data.plot.scatter(x=var, y='SalePrice', ylim=(0,800000));

注:pd.concat函数将两列值连接在一起,axis=1表示列合并。
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第2张图片
可以看出SalePrice 和 GrLivArea具有线性关系,再看一下和TotalBsmtSF(地下室总面积)的关系:

#scatter plot totalbsmtsf/saleprice
var = 'TotalBsmtSF'
data = pd.concat([df_train['SalePrice'], df_train[var]], axis=1)
data.plot.scatter(x=var, y='SalePrice', ylim=(0,800000));

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第3张图片
可以看出,SalePrice 和TotalBsmtSF也有线性关系,但是在最左侧,SalePrice的增加和TotalBsmtSF没有关系。
接下来看看与分类特征的关系,此时一般用箱型图。如OverallQual( 对房子的整体材料和装修进行评级):

#box plot overallqual/saleprice
var = 'OverallQual'
data = pd.concat([df_train['SalePrice'], df_train[var]], axis=1)
f, ax = plt.subplots(figsize=(8, 6))
fig = sns.boxplot(x=var, y="SalePrice", data=data)
fig.axis(ymin=0, ymax=800000);

注:plt.subplots返回的对象是figure和axes(轴)。
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第4张图片
从上图可看出SalePrice 与 OverallQual 分布趋势相同。再来看与YearBuilt(建造年份)的关系:

var = 'YearBuilt'
data = pd.concat([df_train['SalePrice'], df_train[var]], axis=1)
f, ax = plt.subplots(figsize=(16, 8))
fig = sns.boxplot(x=var, y="SalePrice", data=data)
fig.axis(ymin=0, ymax=800000);
plt.xticks(rotation=90);

注:plt.xticks函数获取或设置X轴的当前刻度位置和标签,rotation=90表示旋转90度,这样是为了标签能更好地显示。
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第5张图片
虽然趋势不是很明显,但是还是能看出建造时间越早的房屋所需要的钱更少。
总结:‘GrLivArea’ 和 ‘TotalBsmtSF’ 有正线性关系,而且TotalBsmtSF的斜率更高;箱型图显示了随着整体质量的增长,房价的增长趋势,能看出OverallQual 的相关性更强。

4、相关分析

为了能清楚地发现这些特征值和房价,特征值与特征值之间地关系,可以用相关矩阵(热图)来表示:

#correlation matrix
corrmat = df_train.corr()
f, ax = plt.subplots(figsize=(12, 9))
sns.heatmap(corrmat, vmax=.8, square=True);

注:.corr()函数求的是相关系数矩阵,sns.heatmap函数中,vmax,vmin分别是热力图的颜色取值最大和最小范围,即最右边的颜色图例,square设置热力图矩阵小块形状,默认值是False。
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第6张图片
在这个热图中,颜色越淡,说明两者的相关性越强。我们可以看出,TotalBsmtSF(地下室总面积) 和 1stFlrSF (1楼面积)变量之间有很强的相关性,GarageX 变量群也是如此。这说明这些变量间有多重共线性(注:一般来说,回归模型的解释变量之间不存在线性关系,但如果解释变量之间存在精确相关关系或高度相关关系会使模型估计失真或难以估计准确)。在与SalePrice相关性分析中,也可以发现GrLivArea(地面上居住面积),TotalBsmtSF, OverallQual(总体质量)与房价之间有很强的相关性。其它变量也有可能,需要进行下一步探索。下面直接来看和房价相关性很高的前十个变量的相关矩阵:

#saleprice correlation matrix
k = 10 #number of variables for heatmap
cols = corrmat.nlargest(k, 'SalePrice')['SalePrice'].index
cm = np.corrcoef(df_train[cols].values.T)
sns.set(font_scale=1.25)
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)
plt.show()

注:DataFrame.nlargest(n, columns, keep=‘first’)函数表示从columns中取出n个最大的值,其中keep默认为first,即如果有几个值是一样的,则选取在columns中最先出现的值,反之为last,如果为all,则这些一样的值都会被选取。因此,col为与SalePrice相关系数最大的前十个数的变量名。cm为这十个变量列表的相关系数矩阵。sns.heatmap中,cbar表示是否在热力图侧边绘制颜色刻度条,默认值是True ;annot默认取值False,如果是True,在热力图每个方格写入数据,如果是矩阵,在热力图每个方格写入该矩阵对应位置数据 ;fmt字符串格式代码,矩阵上标识数字的数据格式,比如保留小数点后几位数字 ;annot_kws默认取值False,如果是True,设置热力图矩阵上数字的大小颜色字体。
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第7张图片
最后得到的热力图如上,我们可以看出:
(1)OverallQual, GrLivArea,TotalBsmtSF与SalePrice有很强的关系。
(2)GarageCars(车位数量)和 GarageArea(车库面积)也有强相关性,但是车位的数量由车库面积决定,因此我们只要选择其中一个就行。最后我们选择相关性更高的GarageCars。
(3)TotalBsmtSF 和 1stFloor 的相关系数相同,因此我们也只要选择一个就行,就选择了TotalBsmtSF。
(4)TotRmsAbvGrd(地面上所有房间数量)和GrLivArea也像(3)中两个变量一样,双胞胎变量。
(5)YearBuilt(建造年份) 和 SalePrice 相关性似乎不强。
经过上述分析后,再将这些需要考虑的变量和SalePrice绘制散点图:
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第8张图片
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第9张图片
可以看出,TotalBsmtSF 和 GrLiveArea之间的散点图,有线性关系,但又像边界,因为大多数点都在线的下方。毕竟地下室面积可以和地面上的居住面积相等,但一般不希望地下室面积比地面上还要大。
SalePrice 和 YearBuilt 之间的散点图里,在点云的底部,几乎呈指数函数的分布;而在上端,也有这个趋势,且近几年的点有超过这个限制。

5、缺失值

缺失值是指粗糙数据中由于缺少信息而造成的数据的聚类、分组、删失或截断。它指的是现有数据集中某个或某些属性的值是不完全的。对于我们的这个问题来说,缺失值能使样本大小减少,阻止我们的分析进程。因此我们要保证对缺失值的处理不会出现偏离或隐藏会造成困难的真相。
分析有缺少值的变量的情况:

#missing data
total = df_train.isnull().sum().sort_values(ascending=False)
percent = (df_train.isnull().sum()/df_train.isnull().count()).sort_values(ascending=False)
missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
missing_data.head(20)

注:.isnull() 把对应的所有元素的位置都列出来,元素为空或者NA就显示True,否则就是False。isnull().sum()函数是将列中为空或者NA的个数统计出来。sort_values默认为True,升序排列。
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第10张图片
从上面这个表中可以看出,缺失值超过15%,我们应该删除相应的变量并假装它们从未存在过。
(1)例如PoolQC(游泳池质量), MiscFeature(其他类别未涵盖的其他功能), Alley(连接房屋的胡同道路类型)等这些都应该删掉。如果删掉了,我们会丢失数据吗?我并不这么认为。这些变量看起来都不重要。而且,像PoolQC,MiscFeature 和FireplaceQu(壁炉质量)这些变量有可能是离群值。
(2)GarageX系列变量的缺失值数目都一样。因为车库最重要的信息都能用GarageCars表达,且缺失值比例为5%,因此可以将这些变量删除。BsmtX系列变量也是同样的道理。
(3)对于MasVnrArea(砖石饰面面积) and MasVnrType(砖石饰面类型)这两个变量,看名字就觉得不重要。而且,它们和早已考虑过的YearBuilt, OverallQual有很强的相关行性。
(4)由于 Electrical (电力系统)中只有一个损失的观察值,所以我们删除这个观察值,但是保留这一变量。
所以,除了Electrical ,其它变量我们都删除,而Electrical 只删除那个缺失值:

#dealing with missing data
df_train = df_train.drop((missing_data[missing_data['Total'] > 1]).index,1)
df_train = df_train.drop(df_train.loc[df_train['Electrical'].isnull()].index)
df_train.isnull().sum().max() #just checking that there's no missing data missing...
0

6、离群值

离群值是指在数据中有一个或几个数值与其他数值相比差异较大。当出现离群值的时候,要慎重处理。

单变量分析 定义阈值来确定某个观察值是否为异常值,需要先标准化数据。标准化意味着将数值转为平均值0,标准差1。

#standardizing data
saleprice_scaled = StandardScaler().fit_transform(df_train['SalePrice'][:,np.newaxis]);
low_range = saleprice_scaled[saleprice_scaled[:,0].argsort()][:10]
high_range= saleprice_scaled[saleprice_scaled[:,0].argsort()][-10:]
print('outer range (low) of the distribution:')
print(low_range)
print('\nouter range (high) of the distribution:')
print(high_range)

注:fit_transform()的作用是先拟合数据,然后将其转化为标准形式。np.newaxis可以给原数组增加一个维度,但放的位置不同,产生的新数组也不同。X[:,0]是numpy中数组的一种写法,表示对一个二维数组,取该二维数组第一维中的所有数据,第二维中取第0个数据,直观来说,X[:,0]就是取所有行的第0个数据, X[:,1] 就是取所有行的第1个数据。argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引),然后输出到y。

outer range (low) of the distribution:
[[-1.83820775]
 [-1.83303414]
 [-1.80044422]
 [-1.78282123]
 [-1.77400974]
 [-1.62295562]
 [-1.6166617 ]
 [-1.58519209]
 [-1.58519209]
 [-1.57269236]]

outer range (high) of the distribution:
[[3.82758058]
 [4.0395221 ]
 [4.49473628]
 [4.70872962]
 [4.728631  ]
 [5.06034585]
 [5.42191907]
 [5.58987866]
 [7.10041987]
 [7.22629831]]

上面输出的是SalePrice标准化后,按从小到大的顺序排序,前10个和后10个的值。可以看出,低范围的值都比较相近,且离0很近;而高范围的值离0很远且7点几的值远离其它范围之外。

双变量分析
先来看GrLivArea与SalePrice的散点图:

#bivariate analysis saleprice/grlivarea
var = 'GrLivArea'
data = pd.concat([df_train['SalePrice'], df_train[var]], axis=1)
data.plot.scatter(x=var, y='SalePrice', ylim=(0,800000));

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第11张图片
可以看出,有两个离群的 GrLivArea 值很高,但SalePrice却很低的数据,可能它们代表了农业地区。 这两个点很明显不能代表典型样例,所以我们将它们定义为异常值并删除。而我们之前说的有两个7点多的数据在散点图中看起来遵循了总体趋势,所以我们保留它们:

#deleting points
df_train.sort_values(by = 'GrLivArea', ascending = False)[:2]
df_train = df_train.drop(df_train[df_train['Id'] == 1299].index)
df_train = df_train.drop(df_train[df_train['Id'] == 524].index)

然后来分析TotalBsmtSF(地下室总面积)和SalePrice:

#bivariate analysis saleprice/grlivarea
var = 'TotalBsmtSF'
data = pd.concat([df_train['SalePrice'], df_train[var]], axis=1)
data.plot.scatter(x=var, y='SalePrice', ylim=(0,800000));

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第12张图片
虽然TotalBsmtSF > 3000时,数据有点问题,但是其实问题不大,所以不动。

7、核心部分

正态性:
需要关注两点:直方图(峰度和偏度);正态概率图(数据分布应紧密跟随代表正态分布的对角线)。
SalePrice的直方图和正态概率图:

#histogram and normal probability plot
sns.distplot(df_train['SalePrice'], fit=norm);
fig = plt.figure()
res = stats.probplot(df_train['SalePrice'], plot=plt)

注:displot()集合了matplotlib的hist()与核函数估计kdeplot的功能,增加了rugplot分布观测条显示与利用scipy库fit拟合参数分布的新颖用途。QQ图主要是直观的表示观测与预测值之间的差异。一般我们所取得数量性状数据都为正态分布数据。预测的线是一条从原点出发的45度角的虚线,事假观测值是实心点。
kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第13张图片
可以看出,房价分布不是正态的,也显示了峰值,正偏度,但是并不跟随对角线。可以用数字转换解决,特别是正偏度,可以用log函数转换:

#applying log transformation
df_train['SalePrice'] = np.log(df_train['SalePrice'])
#transformed histogram and normal probability plot
sns.distplot(df_train['SalePrice'], fit=norm);
fig = plt.figure()
res = stats.probplot(df_train['SalePrice'], plot=plt)

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第14张图片
可以看出,log转换后的SalePrice已成正态分布,且观测与预测值差不多拟合。
同理来看GrLivArea:

#histogram and normal probability plot
sns.distplot(df_train['GrLivArea'], fit=norm);
fig = plt.figure()
res = stats.probplot(df_train['GrLivArea'], plot=plt)

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第15张图片

#data transformation
df_train['GrLivArea'] = np.log(df_train['GrLivArea'])
#transformed histogram and normal probability plot
sns.distplot(df_train['GrLivArea'], fit=norm);
fig = plt.figure()
res = stats.probplot(df_train['GrLivArea'], plot=plt)

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第16张图片
下一个:TotalBsmtSF

#histogram and normal probability plot
sns.distplot(df_train['TotalBsmtSF'], fit=norm);
fig = plt.figure()
res = stats.probplot(df_train['TotalBsmtSF'], plot=plt)

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第17张图片
这里,我们能发现,有许多值为0,即没有浴室的房屋。但值为0不能用log转换。因此,我们建立了一个二值变量,有或没有浴室。我们对所有非0观测值进行log转换,而忽略了0值。

#create column for new variable (one is enough because it's a binary categorical feature)
#if area>0 it gets 1, for area==0 it gets 0
df_train['HasBsmt'] = pd.Series(len(df_train['TotalBsmtSF']), index=df_train.index)
df_train['HasBsmt'] = 0 
df_train.loc[df_train['TotalBsmtSF']>0,'HasBsmt'] = 1
#transform data
df_train.loc[df_train['HasBsmt']==1,'TotalBsmtSF'] = np.log(df_train['TotalBsmtSF'])
#histogram and normal probability plot
sns.distplot(df_train[df_train['TotalBsmtSF']>0]['TotalBsmtSF'], fit=norm);
fig = plt.figure()
res = stats.probplot(df_train[df_train['TotalBsmtSF']>0]['TotalBsmtSF'], plot=plt)

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第18张图片
同方差性:最好的测量两个变量的同方差性的方法就是图像,偏离等离散度的形状如锥体(图的一侧的分散度较小,另一侧的分散度较大)或菱形(分布中心的大量点)。
先来看SalePrice和GrLivArea:

#scatter plot
plt.scatter(df_train['GrLivArea'], df_train['SalePrice']);

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第19张图片
现在的散点图不再是圆锥的,这就是因为标准化了。
再来看有地下室时,SalePrice和TotalBsmtSF 同方差性:

#scatter plot
plt.scatter(df_train[df_train['TotalBsmtSF']>0]['TotalBsmtSF'], df_train[df_train['TotalBsmtSF']>0]['SalePrice']);

kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一)_第20张图片
可以看出 SalePrice 在整个 TotalBsmtSF 变量范围内显示出了同等级别的变化。

虚拟变量
将类别变量转换为虚拟变量:

#convert categorical variable into dummy
df_train = pd.get_dummies(df_train)

你可能感兴趣的:(kaggle房价预测(House Prices: Advanced Regression Techniques)数据分析(一))