Kaggle经典Data Science项目->房价预测案例

308 阅读10分钟

我使用的是爱荷华州艾姆斯的住宅房价数据。数据分为训练数据集和测试数据集。两个数据集都包括每栋房⼦的特征,如街道类型、建造年份、房顶类型、地下室状况等特征值。这些特征值有连续的数字、离散的标签甚⾄是缺失值“na”。只有训练数据集包括了每栋房⼦的价格,也就是标签。训练数据和测试数据分别各有1460条,数据的特征列有79个,其中35个是数值类型的,44个类别类型。要根据给出的79个特征,预测对应的房价。理解其中内容对于后续的数据预处理、数据清洗以及方差分析十分重要。所以我们的目标是:

  • 预测每一个房屋的销售价格。对于测试集中的每个ID,预测SalePrice变量的值。
  • 解决问题:观察每个变量特征的意义以及对于问题的重要程度
  • 研究主要特征:也就是最终的目的变量----》房价呗
  • 研究其他变量:研究其他多变量对“房价”的影响的他们之间的关系
  • 基础的数据清理:对一些缺失数据、异常点和分类数据进行处理
  • 测试假设

先来简单介绍一下项目(以下是我本人正儿八经的吧啦吧啦):

房价预测是kaggle的一个经典Data Science项目。就是要根据给出的79个特征,预测对应的房价,这些特征包括房子的类型、临街宽度、各层的面积等等。

Kaggle房价预测链接: House Prices - Advanced Regression Techniques | Kaggle

image.png

收集数据在这!

房价预测数据下载地址:House Prices - Advanced Regression Techniques | Kaggle

image.png

开始数据探索啦

  • 总体预览:了解每列数据的含义,数据的格式等;
  • 数据初步分析:使用绘图工具初步了解数据之间的相关性,为模型建立做准备。

模型融合

  • 通过对模型的对比打分方式选择合适的模型;
  • 在房价预测里我们使用模型融合的方法来输出结果,最终的效果很好

评价指标

根据预测值的对数与观察到的销售价格的对数之间的均方根误差(RMSE)评估提交的内容(采取对数意味着预测昂贵房屋和廉价房屋的错误将同等影响结果)

image.png

重难点有哪些捏?

1、seaborn库介绍:

seaborn是基于Matplotlib的Python数据可视化库。它提供了一个高级界面,用于绘制引人入胜且内容丰富的统计图形,只是在Matplotlib上进行了更高级的API封装,从而使作图更加容易;

seaborn是针对统计绘图的,能满足数据分析90%的绘图需求,需要复杂的自定义图形还需要使用到Matplotlib。

2、scipy

  • 基类
  • bool8类型 byte类型 intN
  • 运行时Warning
  • 计算平台限制
  • numpy相关数学函数
  • scipy.stats

  • 统计: 平均 中位数 归一化
  • 概率分布
  • 随机数

3、IPython介绍

ipython是一个python的交互式shell,比默认的python shell好用得多,支持变量自动补全,自动缩进,支持bash shell命令,内置了许多很有用的功能和函数。学习ipython将会让我们以一种更高的效率来使用python。同时它也是利用Python进行科学计算和交互可视化的一个最佳的平台。

IPython的主要功能如下:

  • 运行ipython控制台
  • 使用ipython作为系统shell
  • 使用历史输入(history)
  • Tab补全
  • 使用%run命令运行脚本
  • 使用%timeit命令快速测量时间
  • 使用%pdb命令快速debug
  • 使用pylab进行交互计算
  • 使用IPython Notebook

任务实施

1.	导入库
# 导入需要的模块
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib
# 正态分布
from scipy.stats import norm
# 离散统计分布以及连续统计分布
from scipy import stats
from scipy.stats import skew
from scipy.stats.stats import pearsonr

import matplotlib.pyplot as plt
%matplotlib inline

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
2.	读取数据
train=pd.read_csv(r"A:\dashujushuju\train.csv")
evaluate=pd.read_csv(r"A:\dashujushuju\test.csv")
# 读取csv数据
train.shape
evaluate.shape

image.png

结论:可以看到训练数据的大小是1460*81,也就是说训练数据总共有1460条,81列,其中最后一列是我们的预测目标:SalePrice。测试数据一共是1459条,80列。注意到Id这一列是直接从1顺次排到2919的,训练数据取的是1 ~ 1460,测试数据取的是1461 ~ 2919,说明Id和房价没有任何关系,所以直接去掉这一列:

#ID列没有用,直接删掉
train.drop('Id', axis=1, inplace=True)
test.drop('Id', axis=1, inplace=True)
print('The shape of training data:', train.shape)
print('The shape of testing data:', test.shape)

数据整体理解

train.info()

image.png

image.png

image.png

属性的意义:

SalePric:以美元出售的房产价格   MSSubClass:建筑类  Msszoning:城市总体规划区

LotFrontage:连接物业的街道线   LotArea:Lot size in square feet方块大小 

Street:道路入口类型  Alley:巷类型  LotShape:地产的外形 LandContour:地产的扁平化

Utilities:地产的公用事业类型  LotConfig:地产配置   LandSlope:地产的坡

Neighborhood:城市范围内的物理位置  Condition1:接近主干道或铁路 CentralAir:空调

Condition2:接近主路或铁路  BldgType:住宅类型   HouseStyle:居家风格

OverallQual:整体质量和表面质量  OverallCond:总体状态额定值 RoofMatl:屋顶材料

YearBuilt:原施工日期  YearRemodAdd:重塑日期  RoofStyle:屋顶类型

Exterior1st:房屋外墙  Exterior2nd:外部第二层:房屋外部覆盖物  Heating:暖气方式

MasVnrType:圬工单板型  MasVnrArea:砌体单板覆盖面积  ExterQual: 外观材质

ExterCond:外墙材料的现状  Foundation:地基类型  BsmtQual:地下室的高度

BsmtCond:地下室概况  BsmtExposure: 走道或花园式地下室墙 BsmtFinSF1:1型成品面积

BsmtFinType1:地下室竣工面积质量  BsmtFinType2:第二成品区域的质量(如果存在)

BsmtFinSF2:2型成品面积  BsmtUnfSF:地下室面积  TotalBsmtSF:地下室面积总计面积

HeatingQC:暖气质量与条件 Electrical:电气系统 1stFlrSF:一楼面积 2ndFlrSF:二楼面积

LowQualFinSF:低质量完工面积(所有楼层) GrLivArea:高档(地面)居住面积

BsmtFullBath:地下室全浴室 BsmtHalfBath:地下室半浴室  FullBath:高档浴室

HalfBath:半日以上洗澡浴室 Bedroom:地下室层以上的卧室数 Kitchen:厨房数量

KitchenQual 厨房品质 TotRmsAbvGrd 总房间(不包括浴室) Functional 家庭功能评级

Fireplaces:壁炉数 FireplaceQu:壁炉质量 GarageType:车库位置 GarageYrBlt车库建成年

GarageFinish:车库的内饰 GarageCars:车库容量大小 GarageArea:车库大小

GarageQual:车库质量 GarageCond:车库状况  PavedDrive:铺好的车道 Fence:围栏质量

WoodDeckSF:木制甲板面积 OpenPorchSF:外部走廊面积  EnclosedPorch:闭走廊面积

3SsnPorch: 三季走廊面积 ScreenPorch:屏风走廊面积  PoolArea:泳池面积

PoolQC:泳池的质量 MiscFeature:其他类别的杂项特征 MiscVal:杂项价值

MoSold:月售出  YrSold:年销售  SaleType:销售类型  SaleCondition:销售条件

属性分析

可以看出,标签为房价,而对于79个属性主要分为几分方面咯:

房子地理位置: 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、Bedroom、Kitchen、KitchenQual、TotRmsAbvGrd、Functional 车库: GarageType、GarageYrBlt、GarageFinish、GarageCars、GarageArea、GarageQual、GarageCond、PavedDrive 其他面积: WoodDeckSF、OpenPorchSF、EnclosedPorch、3SsnPorch:、ScreenPorch、PoolArea 销售: MoSold、YrSold、SaleType、SaleCondition 其他: Fireplaces、FireplaceQu、PoolQC、Fence、MiscFeature、MiscVal

结论:假如数据真实可靠,则从实际情况考虑,对于一个房子的价格,最重要的属性首先应该有:地理位置、面积、地下室、冷暖气、车库、房子质量,还有会影响到房价的有:销售条件如时间和方式。所以先可以着重讨论这些方面的属性。

#对train销售价格的描述

train['SalePrice'].describe()

image.png

#绘制目标值分布

sns.distplot(train['SalePrice'])

image.png 结论:明显的右偏分布,这就意味着我们之后要对目标值做一些处理,因为回归模型在正态分布的数据集上表现更好。*

# 再看看目标值的统计值:

train['SalePrice'].describe()

image.png

结论:最大值和均值之间差距比较大,可能会存在异常值。这里有一个小trick:把类别特征和数字特征分离开来,在处理的时候会比较方便。

#分离数字特征和类别特征

num_features = []

cate_features = []

for col in test.columns:

    if test[col].dtype == 'object':

        cate_features.append(col)

    else:

        num_features.append(col)

print('number of numeric features:', len(num_features))

print('number of categorical features:', len(cate_features))

结论:总共有36个数字特征,43个类别特征。

# 查看目标值和数字特征之间的关系(查看数字特征通常采用散点图):

#查看数字特征与目标值的关系

plt.figure(figsize=(16, 20))

plt.subplots_adjust(hspace=0.3, wspace=0.3)

for i, feature in enumerate(num_features):

    plt.subplot(9, 4, i+1)

    sns.scatterplot(x=feature, y='SalePrice', data=train, alpha=0.5)

    plt.xlabel(feature)

    plt.ylabel('SalePrice')

plt.show()

image.png

image.png

image.png

结论:可以看到,‘TotalBsmtSF’、'GrLiveArea’与目标值之间有明显的线性关系,那么这两个值对目标值的预测应该会有很大的帮助,这就是我们要重点关注的特征。*

在类别特征中,凭直觉来看,'Neighborhood’这个特征应该是很重要的,房子的房价往往和周围的房价是差不多的,为了验证这个想法,我们来看看不同类型的’Neighborhood’房价的分布情况。*、

#查看‘Neighborhood’与目标值的关系

plt.figure(figsize=(9, 8))

sns.boxplot(x='Neighborhood', y='SalePrice', data=train)

plt.xlabel('Neighborhood', fontsize=14)

plt.ylabel('SalePrice', fontsize=14)

plt.xticks(rotation=90, fontsize=12)

image.png 结论:不同的’Neighborhood’类型房价的分布区间是明显不同的,这验证了我们的猜想。

# 出售年份’YrSold’和房价的关系

plt.figure(figsize=(8, 6))

sns.boxplot(x='YrSold', y='SalePrice', data=train)

plt.xlabel('YrSold', fontsize=14)

plt.ylabel('SalePrice', fontsize=14)

plt.xticks(rotation=90, fontsize=12)

image.png

数值型自变量探索

3.1相关系数矩阵

DataFrame.corr()方法可以给出两个列之间的相关性,我们利用该方法用于检测特征和目标变量之间的相关性。

corr = train.select_dtypes(include = [np.number]).iloc[:, 1:].corr()

Corr

image.png

image.png

plt.figure(figsize=(12,12))

sns.heatmap(corr, vmax=1, square=True)

image.png 结论:热力图的方式能够非常直观的看到所有变量之间的相关性分布:*

首先两个白色的方块,第一个是 TotalBsmtSF 和 1stFlrSF 变量的相关系数,第二个是 GarageX 变量群。 这两个示例都显示了这些变量之间很强的相关性。实际上,相关性的程度达到了一种多重共线性的情况。 我们可以总结出这些变量几乎包含相同的信息,所以确实出现了多重共线性。*

另一个引起注意的地方是 SalePrice 的相关性。我们可以看到GrLivArea,TotalBsmtSF和 OverallQual 的相关性很强, 除此之外也有很多其他的变量应该进行考虑,这也是我们下一步的内容。

#分析与目标值相关度最高的十个变量

cols_10 = corrs.nlargest(10, 'SalePrice')['SalePrice'].index

corrs_10 = train[cols_10].corr()

plt.figure(figsize=(8, 6))

sns.heatmap(corrs_10, annot=True)

image.png

# 并绘制这十个特征两两之间的散点图

g = sns.PairGrid(train[cols_10])

g.map_diag(plt.hist)

g.map_offdiag(plt.scatter)

image.png

image.png

结论:目前可以看出,‘TotalBsmtSF’、‘GrLiveArea’、'Neighborhood’这几个是我们要重点关注的特征。