kaggle经典比赛优秀社区总结:Stacked Regressions to predict House Prices
本文主要讲述特征工程和Stacking回归模型,可以说本文是新手入kaggle必经历的过程。本篇文章主要讲述上如何在数据集上进行特征工程,然后使用sklearn的基础模型加上xgboost和lightGBM进行集成,目的是能够使得线性模型有很好鲁棒性,最终达到一个很好的预测效果。
Stacked Regressions to predict House Prices
kaggle地址:https://www.kaggle.com/serigne/stacked-regressions-top-4-on-leaderboard/comments
这里面首先给几个链接,全都是kaggle社区里面比较好的笔记:
(1)Comprehensive data exploration with Python by Pedro MKarcelino:有关数据分析
(2)A Study on Regression applied to the Ames dataset by Julien Cohen-Solal:在线性回归模型使用特征工程和深度挖掘
(3)Regularized Linear Models by Alexandru Papiu:使用了模型选择和交叉验证
特征工程一般要做的事情:
(1)处理缺失值
(2)转换数据
(3)标签编码
(4)Box Cox 变换
(5)类别特征one-hot编码
一、数据概览
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from scipy.stats import norm, skew
# set float format limiting floats output to 3 points
pd.set_option('display.float_format', lambda x: '{:.3f}'.format(x))
train = pd.read_csv('/Users/xudong/kaggleData/houseprice/train.csv')
test = pd.read_csv('/Users/xudong/kaggleData/houseprice/test.csv')
# display the first rows of the data
print(train.head(5))
print('------------')
print(test.head(5))
# check the numbers of samples and features
print("The train data size before dropping Id feature is : {} ".format(train.shape))
print("The test data size before dropping Id feature is : {} ".format(test.shape))
# save the 'Id' column
train_ID = train['Id']
test_ID = test['Id']
# Now drop the 'Id' column since it's unnecessary for the prediction process.
train.drop("Id", axis=1, inplace=True)
test.drop("Id", axis=1, inplace=True)
# check again the data size after dropping the 'Id' variable
print("\nThe train data size after dropping Id feature is : {} ".format(train.shape))
print("The test data size after dropping Id feature is : {} ".format(test.shape))
二、数据处理
1.离群点
数据集文档表明了数据中有离群点(原文地址已经失效,这里就不复制地址立刻),并且建议移除。下面使用plot画出数据特征GrLivArea和SalePrice的数据分布图
# Data Processing 数据处理过程
# outliers 离群点
fig, ax = plt.subplots()
ax.scatter(x=train['GrLivArea'], y=train['SalePrice'])
plt.ylabel('SalePrice', fontsize=13)
plt.xlabel('GrLivArea', fontsize=13)
plt.show()
从图上看,右下角有两个离群点,它们GrLiveArea很大但是SalePrice很小,极度偏离数据,需要删除
# delete outliers
train = train.drop(train[(train['GrLivArea'] > 4000) & (train['SalePrice'] < 300000)].index)
Note:
移除离群点,一般都是选择明显的(比如本文中的超大的面积和很低的价格)
虽然数据中还可能有其他的离群点,但是,把他们都移除了可能会影响到我们的模型的训练如果测试数据中会有离群点的话。所以,一般不会把所有的离群点都移除掉,我们只是增加模型的鲁棒性。
2.目标变量(Target Variable)
SalePrice是我们需要预测的,因此对这个变量做一些分析。我们一般都期望数据的分布符合正态,但是有时候实际得到的数据不是这样的。
color = sns.color_palette()
sns.set_style('darkgrid')
sns.distplot(train['SalePrice'], fit=norm)
# get the fitted parameters used by the function
(mu, sigma) = norm.fit(train['SalePrice'])
print('\n mu = {:.2f} and sigma = {:.2f}\n'.format(mu, sigma))
# now plot the distribution
plt.legend(['Normal dist. ($\mu=$ {:.2f} and $\sigma=$ {:.2f})'.format(mu, sigma)], loc='best')
plt.ylabel('Frequency')
plt.title('SalePrice distribution')
# get also the QQ-plot
fig = plt.figure()
res = stats.probplot(train['SalePrice'], plot=plt)
plt.show()
SalePrice的分布图:
SalePrice的QQ图:
可以看出的是,目标变量(SalePrice)偏度很大(一般线性模型要求变量的分布符合正态分布)。因此,我们对目标变量进行log变换,变换后重新进行画图(这个地方不贴图了),可以明显看出目标变量的分布比较正常。
# we use the numpy function log1p which applies log(1+x) to all el