Kaggle入门之预测房价

先给出本次参赛的地址House Prices: Advanced Regression Techniques

这是一个非常经典机器学习题目,给出众多与房价相关的特征,根据这些数据特征来预测房价。

理解问题与数据

首先当然是导入数据了,建议此类数据分析使用anaconda来完成,会非常方便高效。

 1import seaborn as sns
 2import matplotlib.pyplot as plt
 3import pandas as pd
 4import numpy as np
 5from sklearn.model_selection import cross_val_score
 6from sklearn import linear_model
 7from sklearn import metrics
 8
 9train = pd.read_csv('/Machine-Learning/all/train.csv')
10test = pd.read_csv('/Machine-Learning/all/test.csv')

先整体查看下数据

1sns.distplot(train['SalePrice'])
1train['SalePrice'].describe()
1count      1460.000000
2mean     180921.195890
3std       79442.502883
4min       34900.000000
525%      129975.000000
650%      163000.000000
775%      214000.000000
8max      755000.000000
9Name: SalePrice, dtype: float64
1#skewness and kurtosis
2print("偏度: %f" % train['SalePrice'].skew())
3print("峰度: %f" % train['SalePrice'].kurt())
1偏度: 1.882876
2峰度: 6.536282

偏度能够反应分布的对称情况,右偏(也叫正偏),在图像上表现为数据右边脱了一个长长的尾巴,这时大多数值分布在左侧,有一小部分值分布在右侧。

峰度反应的是图像的尖锐程度:峰度越大,表现在图像上面是中心点越尖锐。在相同方差的情况下,中间一大部分的值方差都很小,为了达到和正太分布方差相同的目的,必须有一些值离中心点越远,所以这就是所说的“厚尾”,反应的是异常点增多这一现象。

查看热图

1data = train.corr()
2sns.heatmap(data)

越是白色越是关联紧密。可以观察SalePrice跟哪些属性关联更紧密。

直接查看

热力图显示有很多时候显示不全,尤其属性特别多的时候。这个时候,可能直接查看更方便

1data['SalePrice'].sort_values()
 1KitchenAbvGr    -0.135907
 2EnclosedPorch   -0.128578
 3MSSubClass      -0.084284
 4OverallCond     -0.077856
 5YrSold          -0.028923
 6LowQualFinSF    -0.025606
 7Id              -0.021917
 8MiscVal         -0.021190
 9BsmtHalfBath    -0.016844
10BsmtFinSF2      -0.011378
113SsnPorch        0.044584
12MoSold           0.046432
13PoolArea         0.092404
14ScreenPorch      0.111447
15BedroomAbvGr     0.168213
16BsmtUnfSF        0.214479
17BsmtFullBath     0.227122
18LotArea          0.263843
19HalfBath         0.284108
20OpenPorchSF      0.315856
212ndFlrSF         0.319334
22WoodDeckSF       0.324413
23LotFrontage      0.351799
24BsmtFinSF1       0.386420
25Fireplaces       0.466929
26MasVnrArea       0.477493
27GarageYrBlt      0.486362
28YearRemodAdd     0.507101
29YearBuilt        0.522897
30TotRmsAbvGrd     0.533723
31FullBath         0.560664
321stFlrSF         0.605852
33TotalBsmtSF      0.613581
34GarageArea       0.623431
35GarageCars       0.640409
36GrLivArea        0.708624
37OverallQual      0.790982
38SalePrice        1.000000
39Name: SalePrice, dtype: float64

可以看到有不少值是负的,还有很多值低于0.2,我们可以直接把这些feature从我们的模型里面去掉。

数据处理

处理异常数据

1sns.lmplot(x='GrLivArea', y='SalePrice', data=train, fit_reg=False, scatter=True)

可以看到有两个面积特别大的房子,售价却很低。故我们在训练数据中删除这两个数据。

1train = train[-((train.SalePrice < 200000) &  (train.GrLivArea > 4000))]

缺失数据的处理

查看缺失数据

1for col in train.columns:
2    if train[col].isnull().sum() > 0:
3        print(col, train[col].isnull().sum())
 1LotFrontage 259
 2Alley 1367
 3MasVnrType 8
 4MasVnrArea 8
 5BsmtQual 37
 6BsmtCond 37
 7BsmtExposure 38
 8BsmtFinType1 37
 9BsmtFinType2 38
10Electrical 1
11FireplaceQu 690
12GarageType 81
13GarageYrBlt 81
14GarageFinish 81
15GarageQual 81
16GarageCond 81
17PoolQC 1452
18Fence 1177
19MiscFeature 1404

处理缺失数据

 1#一半是删除过多空值的属性,一半是删除无关联的属性 
 2train = train.drop(["MiscFeature", "Id", "PoolQC", "Alley", "Fence","GarageFinish", "KitchenAbvGr", "EnclosedPorch", "MSSubClass", "OverallCond", "YrSold", "LowQualFinSF", "MiscVal", "BsmtHalfBath", "BsmtFinSF2", "3SsnPorch", "MoSold", "PoolArea"], axis=1)
 3
 4test = test.drop(["MiscFeature", "PoolQC", "Alley", "Fence","GarageFinish", "KitchenAbvGr", "EnclosedPorch", "MSSubClass", "OverallCond", "YrSold", "LowQualFinSF", "MiscVal", "BsmtHalfBath", "BsmtFinSF2", "3SsnPorch", "MoSold", "PoolArea"], axis=1)
 5
 6#汇总train和test的数据
 7all_data = pd.concat((train, test))
 8#如果数字,填写均值。如果字符串,填写次数最多的
 9for col in train.columns:
10    if train[col].isnull().sum() > 0:
11        if train[col].dtypes == 'object':
12            val = all_data[col].dropna().value_counts().idxmax()
13            train[col] = train[col].fillna(val)
14        else:
15            val = all_data[col].dropna().mean()
16            train[col] = train[col].fillna(val)
17
18for col in test.columns:
19    if test[col].isnull().sum() > 0:
20        if test[col].dtypes == 'object':
21            val = all_data[col].dropna().value_counts().idxmax()
22            test[col] = test[col].fillna(val)
23        else:
24            val = all_data[col].dropna().mean()
25            test[col] = test[col].fillna(val)

转非数

对非数字的属性进行转换。这里我使用最简单粗暴的get_dummies()来对train数据和test数据进行转换。这里也有个地方要注意:test数据里面属性的取值范围可能跟train数据里面属性的取值范围部分不同。这样如果直接对test数据和train数据做get_dummies,很可能会导致test和train数据转化后出现了不同的列。所以需要综合处理。

 1#综合处理,转值类型
 2for col in all_data.select_dtypes(include = [object]).columns:
 3    train[col] = train[col].astype('category', categories = all_data[col].dropna().unique())
 4    test[col] = test[col].astype('category', categories = all_data[col].dropna().unique())
 5
 6for col in train.columns:
 7    if train[col].dtype.name == 'category':
 8        tmp = pd.get_dummies(train[col], prefix = col)
 9        train = train.join(tmp)
10        train = train.drop(col, axis=1)
11
12for col in test.columns:
13    if test[col].dtype.name == 'category':
14        tmp = pd.get_dummies(test[col], prefix = col)
15        test = test.join(tmp)
16        test = test.drop(col, axis=1)

建模&&预测

 1lr = linear_model.LinearRegression()
 2X = train.drop("SalePrice", axis=1)
 3y = np.log(train["SalePrice"])
 4
 5lr = lr.fit(X, y)
 6results = lr.predict(test.drop("Id", axis = 1))
 7final = np.exp(results)
 8
 9submission = pd.DataFrame()
10submission['Id'] = test.Id
11submission['SalePrice'] = final
12
13submission.head()
1Id    SalePrice
20    1461    121738.894467
31    1462    160600.237304
42    1463    186313.100909
53    1464    197581.617513
64    1465    198611.414415
1submission.to_csv("submission1.csv", index= False)

大功告成!

总结

重新回顾,用到了哪些知识?

首先当然是pandas和seaborn的使用,一个用来处理数据,这部分通常会花费很多时间,一个用来可视化,用图来代替数据,直观明了;处理完数据后直接使用sklearn.linear_model.LinearRegression进行线性回归,看看简单例子

1>>> from sklearn import linear_model
2>>> clf = linear_model.LinearRegression()
3>>> X = [[0,0],[1,1],[2,2]]
4>>> y = [0,1,2]
5>>> clf.fit(X,y)
6>>> clf.coef_
7[ 0.5 0.5]
8>>> clf.intercept_
91.11022302463e-16

第一次参加Kaggle,最终名次是 2316,提交过一次。还需要好好看看别人的办法,可以在Kernels下找到好多,基本上都是英文的,不过也有两个中文的,看着很亲切了。这里是我写的不走,有空来看看 Kaggle入门之预测房价。完整代码阅读原文。

原文发布于微信公众号 - Python爬虫与算法进阶(zhangslob)

原文发表时间:2018-10-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏极客猴

Python 绘图,我只用 Matplotlib(二)

上篇文章,我们了解到 Matplotlib 是一个风格类似 Matlab 的基于 Python 的绘图库。它提供了一整套和matlab相似的命令API,十分适合...

17110
来自专栏Flutter入门

偶遇FFmpeg(二)——常用命令

将输入的视频的帧,以左上角为坐标的原点,剪切成x,y坐标开始的指定大小。 语法:

40740
来自专栏章鱼的慢慢技术路

OpenGL透明与混色效果

22760
来自专栏前端那些事

过渡与动画 - 逐帧动画&steps调速函数

写在前面 上一篇中我们熟悉五种内置的缓动曲线和(三次)贝塞尔曲线,并且基于此完成了缓动效果. 但是如果我们想要实现逐帧动画,基于贝塞尔曲线的调速函数就显得有些无...

292100
来自专栏前端那些事

过渡与动画 - 逐帧动画&steps调速函数

写在前面 上一篇中我们熟悉五种内置的缓动曲线和(三次)贝塞尔曲线,并且基于此完成了缓动效果. 但是如果我们想要实现逐帧动画,基于贝塞尔曲线的调速函数就显得有些无...

26770
来自专栏wym

俄罗斯方块修复BUG版

//*********************************************// //**************  头文件  ***...

10120
来自专栏MixLab科技+设计实验室

人工智能设计师之智能排版的另一种实现方式

Flipboard的自动排版系统Duplo 最近在整理算法驱动设计的案例,翻到Flipboard的自动排版系统,再次研究了下,把相关的技术思路整理了下: Fli...

40370
来自专栏IMWeb前端团队

移动端重构实战系列7——环形UI

本文作者:IMWeb 结一 原文出处:IMWeb社区 未经同意,禁止转载 ”本系列教程为实战教程,是本人移动端重构经验及思想的一次总结,也是对sand...

24060
来自专栏wym

俄罗斯方块

//*********************************************// //**************  头文件  *****...

15410
来自专栏coding for love

CSS进阶12-网格布局 Grid Layout

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

10320

扫码关注云+社区

领取腾讯云代金券