kaggle实战之房价预测,了解一下?

在这里插入图片描述
在学习完各种高大上的机器学习理论知识(线性回归、逻辑回归、分类决策树、随机森林等等)之后,也许你会问这玩意儿到底有什么用?? 也许你已经按捺不住想自己好奇的心,想找到实际的数据练练手??

Talk is cheap, show me the code!

本篇文章就是用 kaggle 平台上实际的数据带你走进机器学习的世界,来看看,所谓的数据挖掘或者机器学习实际应用到底是怎么样一个过程。

1.数据集介绍

Kaggle 平台上包含9500多个数据集,简直就是我们学习机器学习的一座宝库,本篇文章使用的是爱荷华州艾姆斯的住宅房价数据。

  • 问题背景页
    在这里插入图片描述
  • 可下载 Data 的页面
    在这里插入图片描述
  • 内核 kernels ,你会看到各种大神级人物很棒的数据处理合建模idea
    在这里插入图片描述
  • 数据背景
    基于竞赛方所提供的爱荷华州埃姆斯的住宅数据信息,预测每间房屋的销售价格,很明显这是一个回归问题。
    常用算法: 线性回归、随机森林、GBDT、xgboost、lightGBM
2.如何开始?

当第一次真正对这么复杂的数据进行操作,也许你有点不知所措,别着急待我们一点点分析后,肯定会有大大的收获!!

用机器学习解决问题的一般步骤如下:
在这里插入图片描述

在训练模型之前,对数据进行分析探索,找出特征工程属性是非常重要的!!

数据探索

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

特征工程

  • 根据常识以及数据分析的结果构造特征工程;
  • 处理缺失值、数据类型转换等;

模型选择

  • 根据目标函数确定学习类型,是无监督学习还是监督学习,是分类问题还是回归问题等;
  • 选择多个模型进行训练,比较各个模型的分数,然后取效果较好的模型作为基础模型;

模型融合

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

修改特征和模型参数

  • 可以通过添加或者修改特征,提高模型的上限.
  • 通过修改模型的超参数,使模型逼近上限
3.数据探索 (Exploratory Data Analysis)

先看看数据包含哪些东西,在 Data 页签下载 train.csv 和 test.csv 两个文件,分别存着官方给的训练和测试数据,这其中既有离散型也有连续性特征,而且存在大量的缺失值,但是官方提供了 data_description.txt 这个文件,里面对各个特征的含义进行了描述,理解了其中内容后对于大部分缺失值就进行填充了。

pandas 是常用的 python 数据处理包,把 csv 文件读入成 dataframe 格式(可以想象成excel),具体数据展示在上图的 ipython notebook中。
在这里插入图片描述
我们看到,总共有81个属性,其中 " SalePrice " 字段表示的是该房子的售价,其余都是房子的相关信息,每一列的属性含义如下(参考data_description.txt):

我们让 dataframe 展示一些信息,如下所示:

数据有分布,有不同的业务意义,我们可以通过matplotlib 、seaborn 画图更加深入理解某些属性的意义,然后构造或是提取出有用的特征。

3.1 数据可视化分析

每条数据都这么多属性,那我们如何知道哪些属性更有用,而又应该怎么用它们?

仅仅最上面的对数据了解,依旧无法给我们提供想法和思路,我们再深入一点来看看我们的数据,看看每个/多个 属性和最后的 " SalePrice " 之间有着什么样的关系呢?

脑容量太有限了,看数据实在不很难分析出来,我们还是画些图来看看属性和房屋售价之间的关系:

  • 分析“SalePrice” :
通过上图可以看出 “SalePrice” 没有无效或者其他非数值的数据,下面通过图示化来进一步展示“SalePrice”:

使用seaborn 进行可视化展示,matplotlib作的直方图最大的区别在于有一条密度曲线,通过图形可以看出房价呈现正态分布。

  • 相关性分析

相关度特征排序,寻找10个最相关的特征信息。

相关性协方差表 corr()函数,返回结果接近 0 说明无相关性,大于 0 说明是正相关,小于 0是负相关,如果两个变量相互独立,他们的协方差(covariance)为 0 。

在这里插入图片描述
我们可以看出跟房产售价最相关的10个数值属性为:
‘OverallQual’ : 整体材料和装修评分
‘GrLivArea’ : 地上面积
‘GarageCars’ : 车库容量
‘GarageArea’ : 车库面积
‘TotalBsmtSF’ :地下室面积
‘1stFlrSF’ : 一楼的平方英尺
‘FullBath’ :完整浴室
‘TotRmsAbvGrd’:地上总房间数
‘YearBuilt’ : 建造年份

此外,通过分析数据的特殊属性,还有以下非数值属性需要纳入考虑范围:
‘Neighborhood’ :表示房屋所处市区的位置
‘CentralAir’ :是否有中央空调

上图的关系矩阵只是数值型的,像Neighborhood这种离散型数据则没有参与计算,所以下面尝试着使用sklearn来对这些特征进行处理。

由上图可以看到’CentralAir’, 'Neighborhood’这两个特征对房价的影响并不大,所以后面将不予考虑。

  • GrLivArea 地上面积 和 SalePrice的关系:
    在这里插入图片描述
    一般认为房子面积越大,售价越高,从图上看大致也是这个趋势。

此外,从上图knack有两个离群的 GrLivArea 值很高的数据,我们可以猜测下其原因,或许他们代表了贫困地区,也就解释了低价。 这两个点很明显不能代表典型样例,所以我们将它们定义为异常值并删除。
在这里插入图片描述

  • 中央空调和 SalePrice 的关系(类别型特征)
    在这里插入图片描述
    可以很明显的看到有中央空调的房价明显比较高。

  • OverallQual 整体材料和装修评价
    在这里插入图片描述
    可以很明显的看到OverallQual 评价越好的房价明显比较高。

3.2 数据清洗

这里主要是处理缺失值,首先来看各特征的缺失值数量:
在这里插入图片描述
在这里插入图片描述

我们已经进行了数据清洗,并且发现了 SalePrice 的很多信息,现在我们要更进一步理解 SalePrice 。

接下来对 GrLivArea、OverallQual等进行画图分析,然后都进行数据装换。

4.模型选择
4.1 数据标准化在这里插入图片描述
4.2 开始建模

可选单个模型模型,比如线性回归(Ridge、Lasso)、树回归、GBDT、XGBoost、LightGBM 等。

import xgboost as xgb
import lightgbm as lgb
from sklearn.linear_model import ElasticNet, Lasso,  BayesianRidge, LassoLarsIC
from sklearn.ensemble import RandomForestRegressor,  GradientBoostingRegressor
from sklearn.kernel_ridge import KernelRidge
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import RobustScaler
from sklearn.base import BaseEstimator, TransformerMixin, RegressorMixin, clone
from sklearn.model_selection import KFold, cross_val_score, train_test_split
from sklearn.metrics import mean_squared_error

#定义交叉验证函数
n_folds = 5
def rmsle_cv(model):
    kf = KFold(n_folds, shuffle=True, random_state=42).get_n_splits(x_train)
# np.sqrt(x)返回x的平方根
# cross_val_score方法: 
# 这个方法是对数据进行多次分割,然后训练多个模型并评分,每次分割不一样。之后我们用评分的均值来代表这个模型的得分。
# 方法重要参数是:cv代表计算多少次,分割次数;scoring代表方法。
# 损失函数
    rmse= np.sqrt(-cross_val_score(model, x_train, y_train, scoring="neg_mean_squared_error", cv = kf))
    return(rmse)

# 模型选择
## LASSO Regression : # Linear least squares with L1 regularization.
lasso = make_pipeline(RobustScaler(), Lasso(alpha=0.0005, random_state=1))
# Elastic Net Regression
ENet = make_pipeline(RobustScaler(), ElasticNet(alpha=0.0005, l1_ratio=.9, random_state=3))
# Kernel Ridge Regression
KRR = KernelRidge(alpha=0.6, kernel='polynomial', degree=2, coef0=2.5)
## Gradient Boosting Regression
GBoost = GradientBoostingRegressor(
    n_estimators=3000,
    learning_rate=0.05,
    max_depth=4,
    max_features='sqrt',
    min_samples_leaf=15,
    min_samples_split=10,
    loss='huber',
    random_state=5)
## XGboost
model_xgb = xgb.XGBRegressor(
    colsample_bytree=0.4603,
    gamma=0.0468,
    learning_rate=0.05,
    max_depth=3,
    min_child_weight=1.7817,
    n_estimators=2200,
    reg_alpha=0.4640,
    reg_lambda=0.8571,
    subsample=0.5213,
    silent=1,
    random_state=7,
    nthread=-1)
## lightGBM
model_lgb = lgb.LGBMRegressor(
    objective='regression',
    num_leaves=5,
    learning_rate=0.05,
    n_estimators=720,
    max_bin=55,
    bagging_fraction=0.8,
    bagging_freq=5,
    feature_fraction=0.2319,
    feature_fraction_seed=9,
    bagging_seed=9,
    min_data_in_leaf=6,
    min_sum_hessian_in_leaf=11)
## 对这些基本模型进行打分
score = rmsle_cv(lasso)
print("\nLasso score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))
score = rmsle_cv(ENet)
print("ElasticNet score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))
score = rmsle_cv(KRR)
print(
    "Kernel Ridge score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))
score = rmsle_cv(GBoost)
print("Gradient Boosting score: {:.4f} ({:.4f})\n".format(score.mean(),
                                                          score.std()))
score = rmsle_cv(model_xgb)
print("Xgboost score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))
score = rmsle_cv(model_lgb)
print("LGBM score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))

也可以将多个模型组合起来,进行模型融合。比如Averaging、stacking等方法,好的特征决定模型上限,好的模型和参数可以无线逼近上限。

在机器学习中,集成方法(ensemble learning)把许多个体预测器(base estimator)组合起来,从而提高整体模型的鲁棒性和泛化能力。

集成方法有两大类:
Averaging:独立建造多个个体模型,再取它们各自预测值的平均,作为集成模型的最终预测;能够降低variance。例子:随机森林、bagging。

Boosting:顺序建立一系列弱模型,每一个弱模型都努力降低bias,从而得到一个强模型,最终的预测结果,是所有预测器的加权平均(或投票结果)。例子:AdaBoost、Gradient Boosting、XGBoost、LightGBM。

# 这里使用Boosting模型融合:
class AveragingModels(BaseEstimator, RegressorMixin, TransformerMixin):
    def __init__(self, models):
        self.models = models

    # we define clones of the original models to fit the data in
    def fit(self, X, y):
        self.models_ = [clone(x) for x in self.models]

        # Train cloned base models
        for model in self.models_:
            model.fit(X, y)

        return self

    # Now we do the predictions for cloned models and average them
    def predict(self, X):
        predictions = np.column_stack(
            [model.predict(X) for model in self.models_])
        return np.mean(predictions, axis=1)


# 评价这四个模型的好坏
stacked_averaged_models = AveragingModels(models=(ENet, GBoost, KRR, lasso))
score = rmsle_cv(stacked_averaged_models)
print(" Averaged base models score: {:.4f} ({:.4f})\n".format(score.mean(),
                                                              score.std()))
5.预测结果
from sklearn.metrics import mean_squared_log_error
# 最终对模型的训练和预测

def rmsle(y_train,y_pre):
    return np.sqrt(mean_squared_error(y_train, y_pre))
    
# StackedRegressor
stacked_averaged_models.fit(x_train, y_train)
stacked_train_pred = stacked_averaged_models.predict(x_train)
stacked_pred = np.expm1(stacked_averaged_models.predict(x_test))
# Root Mean Squared Logarithmic Error
print(np.sqrt(mean_squared_error(y_train, stacked_train_pred)))

# XGBoost
model_xgb.fit(x_train, y_train)
xgb_train_pred = model_xgb.predict(x_train)
xgb_pred = np.expm1(model_xgb.predict(x_test))
print(rmsle(y_train, xgb_train_pred))
# lightGBM
model_lgb.fit(x_train, y_train)
lgb_train_pred = model_lgb.predict(x_train)
lgb_pred = np.expm1(model_lgb.predict(x_test))
print(rmsle(y_train, lgb_train_pred))
'''RMSE on the entire Train data when averaging'''

print('RMSLE score on train data:')
#结果是所有预测器的加权平均
print(rmsle(y_train, stacked_train_pred * 0.70 + xgb_train_pred * 0.15 +lgb_train_pred * 0.15))

把结果提交到kaggle上,得分0.15755:
在这里插入图片描述
初步的排名不是很好(但是相差不大),看来还得继续优化!!

6.总结

对于任何的机器学习问题,不要一上来就追求尽善尽美,先用自己会的基本算法撸一个 baseline 的 model 出来,再进行后续的分析步骤,一步步提高。

本文 kernel 地址:
https://www.kaggle.com/lomodays/kernela25bad0b84/notebook?scriptVersionId=9988077

几点 Tricks 跟大家共勉:

特征工程(feature engineering) 为王!
很有必要搭建一个 Pipeline,至少要能够自动训练并记录最佳参数!
要做模型融合(model ensemble)!

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值