赛题原址:House Prices: Advanced Regression Techniques
赛题描述:
Ask a home buyer to describe their dream house, and they probably won’t begin with the height of the basement ceiling or the proximity to an east-west railroad. But this playground competition’s dataset proves that much more influences price negotiations than the number of bedrooms or a white-picket fence.
With 79 explanatory variables describing (almost) every aspect of residential homes in Ames, Iowa, this competition challenges you to predict the final price of each home.
数据概况——对数据有一个初步的认识
先导入文件,做出各变量间混淆矩阵查看变量间相关程度:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df_train = pd.read_csv('C:\\Users\\rinnko\\Desktop\\learning\\MLlearning\\caseH\\train.csv')
print(df_train.columns)
#查看特征之间关联程度:相关系数矩阵可视化
corrmat = df_train.corr()
f, ax = plt.subplots(figsize=(12, 9))
sns.heatmap(corrmat, vmax=.8, square=True,cmap='magma');
观察特征的重要程度
(数值形式变量)相关系数矩阵如下:
初步观察,可以发现在对角线上有两个醒目的大方块。由此发现特征“TotalBsmtSF“与”1stFlrSF”,特征“GarageCars”与“GarageArea”之间相关系数接近于1,即变量间有十分强的关联性,这便意味着这两组相量均会引起多重共线性(Multicollinearity)。
多重共线性是指线性回归模型中的解释变量之间由于存在精确相关关系或高度相关关系而使模型估计失真或难以估计准确。观察变量名可初步推测变量间关系十分紧密基本可以确信其存在引起多重共线性的能力。继续寻找颜色浅甚至接近白色的方块,可以发现变量“YearBuilt”与“GarageYrBuilt”,“TotRmsAbvGrd”与“GrLivArea”相关系数很大,疑似存在引起多重共线性的可能性。
依题可知,此时预测的结果,即因变量为“SalePrice”变量。观察相关系数矩阵可发现,其中“SalePrice”与“OverallQual”、“GrLivArea”以及其他诸多变量相关系数都偏大,根据颜色可认为大多corr大于0.5,接下来用“SalePrice”变量中相关系数较大的变量做出一个相关系数矩阵,观察这些变量之间的相关程度。
#查看Saleprice相关程度较强的几个变量的混淆矩阵
#取10个corr最大的变量
cols = corrmat.nlargest(10,'SalePrice')['SalePrice'].index
corrSP = np.corrcoef(df_train[cols].values.T) #np.xorrcoef计算相关系数的方法,默认以行计算
hm = sns.heatmap(corrSP,cmap='magma',annot=True,square=True,fmt='.2f',annot_kws={
'size':10},yticklabels=cols.values,xticklabels=cols.values)
plt.show()
观察最左列以查看与因变量关系最紧密的变量排名,变量“OverallQual”,“GrLivArea”的关系自然不用说。“TotalBsmtSF“与”1stFlrSF”,特征“GarageCars”与“GarageArea”之间可以2选1,这里取与因变量关系紧密的变量,即“TotalBsmtSF“、“GarageCars”。相关系数在0.5左右的这几个变量是否重要仍待后续考证。“重要”的变量在处理时要多加留意。
观察变量之间关系的形式和特点
接下来可以以散点图的形式观察部分重要自变量(数值形式)与因变量“SalePrice”之间的关系形式,顺便获取更多有用的信息!
sns.set()
cols = ['SalePrice', 'OverallQual', 'GrLivArea', 'GarageCars', 'TotalBsmtSF', 'FullBath', 'YearBuilt']
sns.pairplot(df_train[cols], size = 2.5)#sns多变量图
plt.show();
从多变量图中可以看出以下几点:
-
观察(3,5)或者(5,3)可知:变量“TotRmsAbvGrd”与“GrLivArea”的点只占据了半个平面,部分散点构成了一条直线作为分界线,其余散点则聚集在直线的单侧。查看官方给的data_description可知:
TotalBsmtSF: Total square feet of basement area
GrLivArea: Above grade (ground) living area square feet
该数据集内房屋的地上居住面积通常是大于地下居住面积的,这也符合生活常识,House的地下面积可以等于地上面积,但不会超过地上面积,毕竟没有人愿意住地堡。 -
观察(1,7)或者(7,1)可以察觉到,变量“YearBuilt”与因变量“SalePrice”之间的关系近似于指数型,散点图显示出类似于售价随年份变化“上界”的存在。
-
“SalePrice”和“GrLivArea”变量之间疑似线性关系。
进一步观察SalePrice——探索数据分布转变的可能性
from scipy.stats import norm
from scipy import stats
sns.distplot(df_train['SalePrice'] , fit=norm);
#查看正弦分布拟合的参数
(mu, sigma) = norm.fit(df_train['SalePrice'])
print( '\n mu = {:.2f} and sigma = {:.2f}\n'.format(mu, sigma))
#绘制分布图:displot()集合了matplotlib的hist()与核函数估计kdeplot的功能
plt.legend(['Normal dist. ($\mu=$ {:.2f} and $\sigma=$ {:.2f} )'.format(mu, sigma)],loc='best')
plt.ylabel('Frequency')
plt.title('SalePrice distribution')
#也可以用QQ-plot来表示
fig = plt.figure()
res = stats.probplot(df_train['SalePrice'], plot=plt)
plt.show()
输出:
mu = 180932.92 and sigma = 79467.79
由此可见SalePrice稍稍偏离正态分布,是正偏态分布的,而线性模型适用于正太分布的数据集,我们可以想办法对该变量所有数据进行一个统一的处理,令因变量SalePrice在处理后近似服从正态分布。
数据预处理时首先可以对偏度比较大的数据用log1p函数进行转化,使其更加服从高斯分布,此步处理可能会使我们后续的分类结果得到一个好的结果。log1p = log(x+1)。这里我们采用np.log1p()方法对SalePrice进行转化。
SalePriceA = df_train["SalePrice"]#备份用
df_train["SalePrice"] = np.log1p(df_train["SalePrice"])
输出:
mu = 12.02 and sigma = 0.40
平滑处理可以达到预期效果。
特征工程
在对数据集有了一定的了解后,现在开始准备训练和测试用的dataframe,为此要进行缺失值处理、离群值处理、新特征的生产(如果可以提取出来的话)、偏态数据的处理、dummies和categori