预测波士顿房价
第一步. 导入数据
在这个项目中,将使用波士顿房屋信息数据来训练和测试一个模型,并对模型的性能和预测能力进行评估。我们希望可以通过该模型实现对房屋的价值预估,提高房地产经纪人的工作效率。
此项目的数据集来自kaggle原始数据,未经过任何处理。该数据集统计了2006年至2010年波士顿个人住宅销售情况,包含2900多条观测数据(其中一半是训练数据,即我们的housedata.csv
文件)。更多文档信息可以参考作者的文档,以及项目附件data_description.txt
文件(特征描述文件)。
下面区域的代码用以载入一些此项目所需的Python库。
# 载入此项目需要的库
import numpy as np
import pandas as pd
import visuals as vs # Supplementary code 补充的可视化代码
import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use('seaborn') # use seaborn style 使用seaborn风格
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
print('你已经成功载入所有库!')
你已经成功载入所有库!
加载数据
# 载入波士顿房屋的数据集:使用pandas载入csv,并赋值到data_df
data_df = pd.read_csv('housedata.csv')
# 成功载入的话输出训练数据行列数目
print("Boston housing dataset has {} data points with {} variables each.".format(*data_df.shape))
Boston housing dataset has 1460 data points with 81 variables each.
第二步. 数据分析
这个部分,将对已有的波士顿房地产数据进行初步的观察与处理。
由于这个项目的最终目标是建立一个预测房屋价值的模型,需要将数据集分为特征(features)和目标变量(target variable)。
-
目标变量:
'SalePrice'
,是我们希望预测的变量。
-
特征:除
'SalePrice'
外的属性都是特征,它们反应了数据点在某些方面的表现或性质。
观察数据
对波士顿房价的数据进行观察,从而掌握更多数据本身的信息。
(1)使用 head方法 打印并观察前7条data_df
数据
# 打印出前7条data_df
print(data_df.head(7))
Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape \
0 1 60 RL 65.0 8450 Pave NaN Reg
1 2 20 RL 80.0 9600 Pave NaN Reg
2 3 60 RL 68.0 11250 Pave NaN IR1
3 4 70 RL 60.0 9550 Pave NaN IR1
4 5 60 RL 84.0 14260 Pave NaN IR1
5 6 50 RL 85.0 14115 Pave NaN IR1
6 7 20 RL 75.0 10084 Pave NaN Reg
LandContour Utilities ... PoolArea PoolQC Fence MiscFeature MiscVal \
0 Lvl AllPub ... 0 NaN NaN NaN 0
1 Lvl AllPub ... 0 NaN NaN NaN 0
2 Lvl AllPub ... 0 NaN NaN NaN 0
3 Lvl AllPub ... 0 NaN NaN NaN 0
4 Lvl AllPub ... 0 NaN NaN NaN 0
5 Lvl AllPub ... 0 NaN MnPrv Shed 700
6 Lvl AllPub ... 0 NaN NaN NaN 0
MoSold YrSold SaleType SaleCondition SalePrice
0 2 2008 WD Normal 208500
1 5 2007 WD Normal 181500
2 9 2008 WD Normal 223500
3 2 2006 WD Abnorml 140000
4 12 2008 WD Normal 250000
5 10 2009 WD Normal 143000
6 8 2007 WD Normal 307000
[7 rows x 81 columns]
(2)Id特征对我们训练数据没有任何用处,在data_df
中使用drop方法删除'Id'
列数据
# 删除data_df中的Id特征(保持数据仍在data_df中,不更改变量名)
data_df.drop('Id',axis=1,inplace=True)
(3)使用describe方法观察data_df
各个特征的统计信息:
data_df.describe()
|
MSSubClass |
LotFrontage |
LotArea |
OverallQual |
OverallCond |
YearBuilt |
YearRemodAdd |
MasVnrArea |
BsmtFinSF1 |
BsmtFinSF2 |
... |
WoodDeckSF |
OpenPorchSF |
EnclosedPorch |
3SsnPorch |
ScreenPorch |
PoolArea |
MiscVal |
MoSold |
YrSold |
SalePrice |
count |
1460.000000 |
1201.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1452.000000 |
1460.000000 |
1460.000000 |
... |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
1460.000000 |
mean |
56.897260 |
70.049958 |
10516.828082 |
6.099315 |
5.575342 |
1971.267808 |
1984.865753 |
103.685262 |
443.639726 |
46.549315 |
... |
94.244521 |
46.660274 |
21.954110 |
3.409589 |
15.060959 |
2.758904 |
43.489041 |
6.321918 |
2007.815753 |
180921.195890 |
std |
42.300571 |
24.284752 |
9981.264932 |
1.382997 |
1.112799 |
30.202904 |
20.645407 |
181.066207 |
456.098091 |
161.319273 |
... |
125.338794 |
66.256028 |
61.119149 |
29.317331 |
55.757415 |
40.177307 |
496.123024 |
2.703626 |
1.328095 |
79442.502883 |
min |
20.000000 |
21.000000 |
1300.000000 |
1.000000 |
1.000000 |
1872.000000 |
1950.000000 |
0.000000 |
0.000000 |
0.000000 |
... |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
1.000000 |
2006.000000 |
34900.000000 |
25% |
20.000000 |
59.000000 |
7553.500000 |
5.000000 |
5.000000 |
1954.000000 |
1967.000000 |
0.000000 |
0.000000 |
0.000000 |
... |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
5.000000 |
2007.000000 |
129975.000000 |
50% |
50.000000 |
69.000000 |
9478.500000 |
6.000000 |
5.000000 |
1973.000000 |
1994.000000 |
0.000000 |
383.500000 |
0.000000 |
... |
0.000000 |
25.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
6.000000 |
2008.000000 |
163000.000000 |
75% |
70.000000 |
80.000000 |
11601.500000 |
7.000000 |
6.000000 |
2000.000000 |
2004.000000 |
166.000000 |
712.250000 |
0.000000 |
... |
168.000000 |
68.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
8.000000 |
2009.000000 |
214000.000000 |
max |
190.000000 |
313.000000 |
215245.000000 |
10.000000 |
9.000000 |
2010.000000 |
2010.000000 |
1600.000000 |
5644.000000 |
1474.000000 |
... |
857.000000 |
547.000000 |
552.000000 |
508.000000 |
480.000000 |
738.000000 |
15500.000000 |
12.000000 |
2010.000000 |
755000.000000 |
8 rows × 37 columns
数据预处理
数据不可能是百分百的‘干净’数据(即有用数据),总会在采集整理时有些”失误“、“冗余”,造成“脏”数据,所以要从数据的正确性和完整性这两个方面来清理数据。
-
正确性:一般是指有没有异常值,比如我们这个数据集中作者的文档所说:
I would recommend removing any houses with more than 4000 square feet from the data set (which eliminates these five unusual observations) before assigning it to students.
建议我们去掉数据中'GrLivArea'
中超过4000平方英尺的房屋(具体原因可以参考文档),当然本数据集还有其他的异常点,这里不再处理。
-
完整性:采集或者整理数据时所产生的空数据造成了数据的完整性缺失,通常我们会使用一定的方法处理不完整的数据。在本例中,我们使用以下两种方法,一是丢弃数据,即选择丢弃过多空数据的特征(或者直接丢弃数据行,前提是NA数据占比不多),二是填补数据,填补的方法也很多,均值中位数众数填充等等都是好方法。
正确性方面
以下代码将使用matplotlib
库中的scatter方法 绘制'GrLivArea'
和'SalePrice'
的散点图,x轴为'GrLivArea'
,y轴为'SalePrice'
,观察数据**
# 绘制散点图
plt.scatter(data_df['GrLivArea'],data_df['SalePrice'])
plt.xlabel('GrLivArea')
plt.ylabel('SalePrice')
plt.show(