Kaggle之房价问题

阅读: 评论:0

Kaggle之房价问题

Kaggle之房价问题

Kaggle之房价问题

基于爱荷华州埃姆斯的住宅数据信息,预测每间房屋的销售价格。
这是一个回归问题,评估方式是均方根误差。

数据分析

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from scipy.special import boxcox1p
import missingno as msno
import warnings
warnings.filterwarnings("ignore")%matplotlib inline
# 导入数据
house_train = pd.read_csv('/home/aistudio/data/data32288/train.csv')
house_test  = pd.read_csv('/home/aistudio/data/data32288/test.csv')house_train.shape,house_test.shape
((1460, 81), (1459, 80))
house_train.info()
print('-'*40)
house_test.info()
<class &#frame.DataFrame'>
RangeIndex: 1460 entries, 0 to 1459
Data columns (total 81 columns):#   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  0   Id             1460 non-null   int64  1   MSSubClass     1460 non-null   int64  2   MSZoning       1460 non-null   object 3   LotFrontage    1201 non-null   float644   LotArea        1460 non-null   int64  5   Street         1460 non-null   object 6   Alley          91 non-null     object 7   LotShape       1460 non-null   object 8   LandContour    1460 non-null   object 9   Utilities      1460 non-null   object 10  LotConfig      1460 non-null   object 11  LandSlope      1460 non-null   object 12  Neighborhood   1460 non-null   object 13  Condition1     1460 non-null   object 14  Condition2     1460 non-null   object 15  BldgType       1460 non-null   object 16  HouseStyle     1460 non-null   object 17  OverallQual    1460 non-null   int64  18  OverallCond    1460 non-null   int64  19  YearBuilt      1460 non-null   int64  20  YearRemodAdd   1460 non-null   int64  21  RoofStyle      1460 non-null   object 22  RoofMatl       1460 non-null   object 23  Exterior1st    1460 non-null   object 24  Exterior2nd    1460 non-null   object 25  MasVnrType     1452 non-null   object 26  MasVnrArea     1452 non-null   float6427  ExterQual      1460 non-null   object 28  ExterCond      1460 non-null   object 29  Foundation     1460 non-null   object 30  BsmtQual       1423 non-null   object 31  BsmtCond       1423 non-null   object 32  BsmtExposure   1422 non-null   object 33  BsmtFinType1   1423 non-null   object 34  BsmtFinSF1     1460 non-null   int64  35  BsmtFinType2   1422 non-null   object 36  BsmtFinSF2     1460 non-null   int64  37  BsmtUnfSF      1460 non-null   int64  38  TotalBsmtSF    1460 non-null   int64  39  Heating        1460 non-null   object 40  HeatingQC      1460 non-null   object 41  CentralAir     1460 non-null   object 42  Electrical     1459 non-null   object 43  1stFlrSF       1460 non-null   int64  44  2ndFlrSF       1460 non-null   int64  45  LowQualFinSF   1460 non-null   int64  46  GrLivArea      1460 non-null   int64  47  BsmtFullBath   1460 non-null   int64  48  BsmtHalfBath   1460 non-null   int64  49  FullBath       1460 non-null   int64  50  HalfBath       1460 non-null   int64  51  BedroomAbvGr   1460 non-null   int64  52  KitchenAbvGr   1460 non-null   int64  53  KitchenQual    1460 non-null   object 54  TotRmsAbvGrd   1460 non-null   int64  55  Functional     1460 non-null   object 56  Fireplaces     1460 non-null   int64  57  FireplaceQu    770 non-null    object 58  GarageType     1379 non-null   object 59  GarageYrBlt    1379 non-null   float6460  GarageFinish   1379 non-null   object 61  GarageCars     1460 non-null   int64  62  GarageArea     1460 non-null   int64  63  GarageQual     1379 non-null   object 64  GarageCond     1379 non-null   object 65  PavedDrive     1460 non-null   object 66  WoodDeckSF     1460 non-null   int64  67  OpenPorchSF    1460 non-null   int64  68  EnclosedPorch  1460 non-null   int64  69  3SsnPorch      1460 non-null   int64  70  ScreenPorch    1460 non-null   int64  71  PoolArea       1460 non-null   int64  72  PoolQC         7 non-null      object 73  Fence          281 non-null    object 74  MiscFeature    54 non-null     object 75  MiscVal        1460 non-null   int64  76  MoSold         1460 non-null   int64  77  YrSold         1460 non-null   int64  78  SaleType       1460 non-null   object 79  SaleCondition  1460 non-null   object 80  SalePrice      1460 non-null   int64  
dtypes: float64(3), int64(35), object(43)
memory usage: 924.0+ KB
----------------------------------------
<class &#frame.DataFrame'>
RangeIndex: 1459 entries, 0 to 1458
Data columns (total 80 columns):#   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  0   Id             1459 non-null   int64  1   MSSubClass     1459 non-null   int64  2   MSZoning       1455 non-null   object 3   LotFrontage    1232 non-null   float644   LotArea        1459 non-null   int64  5   Street         1459 non-null   object 6   Alley          107 non-null    object 7   LotShape       1459 non-null   object 8   LandContour    1459 non-null   object 9   Utilities      1457 non-null   object 10  LotConfig      1459 non-null   object 11  LandSlope      1459 non-null   object 12  Neighborhood   1459 non-null   object 13  Condition1     1459 non-null   object 14  Condition2     1459 non-null   object 15  BldgType       1459 non-null   object 16  HouseStyle     1459 non-null   object 17  OverallQual    1459 non-null   int64  18  OverallCond    1459 non-null   int64  19  YearBuilt      1459 non-null   int64  20  YearRemodAdd   1459 non-null   int64  21  RoofStyle      1459 non-null   object 22  RoofMatl       1459 non-null   object 23  Exterior1st    1458 non-null   object 24  Exterior2nd    1458 non-null   object 25  MasVnrType     1443 non-null   object 26  MasVnrArea     1444 non-null   float6427  ExterQual      1459 non-null   object 28  ExterCond      1459 non-null   object 29  Foundation     1459 non-null   object 30  BsmtQual       1415 non-null   object 31  BsmtCond       1414 non-null   object 32  BsmtExposure   1415 non-null   object 33  BsmtFinType1   1417 non-null   object 34  BsmtFinSF1     1458 non-null   float6435  BsmtFinType2   1417 non-null   object 36  BsmtFinSF2     1458 non-null   float6437  BsmtUnfSF      1458 non-null   float6438  TotalBsmtSF    1458 non-null   float6439  Heating        1459 non-null   object 40  HeatingQC      1459 non-null   object 41  CentralAir     1459 non-null   object 42  Electrical     1459 non-null   object 43  1stFlrSF       1459 non-null   int64  44  2ndFlrSF       1459 non-null   int64  45  LowQualFinSF   1459 non-null   int64  46  GrLivArea      1459 non-null   int64  47  BsmtFullBath   1457 non-null   float6448  BsmtHalfBath   1457 non-null   float6449  FullBath       1459 non-null   int64  50  HalfBath       1459 non-null   int64  51  BedroomAbvGr   1459 non-null   int64  52  KitchenAbvGr   1459 non-null   int64  53  KitchenQual    1458 non-null   object 54  TotRmsAbvGrd   1459 non-null   int64  55  Functional     1457 non-null   object 56  Fireplaces     1459 non-null   int64  57  FireplaceQu    729 non-null    object 58  GarageType     1383 non-null   object 59  GarageYrBlt    1381 non-null   float6460  GarageFinish   1381 non-null   object 61  GarageCars     1458 non-null   float6462  GarageArea     1458 non-null   float6463  GarageQual     1381 non-null   object 64  GarageCond     1381 non-null   object 65  PavedDrive     1459 non-null   object 66  WoodDeckSF     1459 non-null   int64  67  OpenPorchSF    1459 non-null   int64  68  EnclosedPorch  1459 non-null   int64  69  3SsnPorch      1459 non-null   int64  70  ScreenPorch    1459 non-null   int64  71  PoolArea       1459 non-null   int64  72  PoolQC         3 non-null      object 73  Fence          290 non-null    object 74  MiscFeature    51 non-null     object 75  MiscVal        1459 non-null   int64  76  MoSold         1459 non-null   int64  77  YrSold         1459 non-null   int64  78  SaleType       1458 non-null   object 79  SaleCondition  1459 non-null   object 
dtypes: float64(11), int64(26), object(43)
memory usage: 912.0+ KB
# 统计性描述
house_train.describe().T
countmeanstdmin25%50%75%max
Id1460.0730.500000421.6100091.0365.75730.51095.251460.0
MSSubClass1460.056.89726042.30057120.020.0050.070.00190.0
LotFrontage1201.070.04995824.28475221.059.0069.080.00313.0
LotArea1460.010516.8280829981.2649321300.07553.509478.511601.50215245.0
OverallQual1460.06.0993151.3829971.05.006.07.0010.0
OverallCond1460.05.5753421.1127991.05.005.06.009.0
YearBuilt1460.01971.26780830.2029041872.01954.001973.02000.002010.0
YearRemodAdd1460.01984.86575320.6454071950.01967.001994.02004.002010.0
MasVnrArea1452.0103.685262181.0662070.00.000.0166.001600.0
BsmtFinSF11460.0443.639726456.0980910.00.00383.5712.255644.0
BsmtFinSF21460.046.549315161.3192730.00.000.00.001474.0
BsmtUnfSF1460.0567.240411441.8669550.0223.00477.5808.002336.0
TotalBsmtSF1460.01057.429452438.7053240.0795.75991.51298.256110.0
1stFlrSF1460.01162.626712386.587738334.0882.001087.01391.254692.0
2ndFlrSF1460.0346.992466436.5284360.00.000.0728.002065.0
LowQualFinSF1460.05.84452148.6230810.00.000.00.00572.0
GrLivArea1460.01515.463699525.480383334.01129.501464.01776.755642.0
BsmtFullBath1460.00.4253420.5189110.00.000.01.003.0
BsmtHalfBath1460.00.0575340.2387530.00.000.00.002.0
FullBath1460.01.5650680.5509160.01.002.02.003.0
HalfBath1460.00.3828770.5028850.00.000.01.002.0
BedroomAbvGr1460.02.8664380.8157780.02.003.03.008.0
KitchenAbvGr1460.01.0465750.2203380.01.001.01.003.0
TotRmsAbvGrd1460.06.5178081.6253932.05.006.07.0014.0
Fireplaces1460.00.6130140.6446660.00.001.01.003.0
GarageYrBlt1379.01978.50616424.6897251900.01961.001980.02002.002010.0
GarageCars1460.01.7671230.7473150.01.002.02.004.0
GarageArea1460.0472.980137213.8048410.0334.50480.0576.001418.0
WoodDeckSF1460.094.244521125.3387940.00.000.0168.00857.0
OpenPorchSF1460.046.66027466.2560280.00.0025.068.00547.0
EnclosedPorch1460.021.95411061.1191490.00.000.00.00552.0
3SsnPorch1460.03.40958929.3173310.00.000.00.00508.0
ScreenPorch1460.015.06095955.7574150.00.000.00.00480.0
PoolArea1460.02.75890440.1773070.00.000.00.00738.0
MiscVal1460.043.489041496.1230240.00.000.00.0015500.0
MoSold1460.06.3219182.7036261.05.006.08.0012.0
YrSold1460.02007.8157531.3280952006.02007.002008.02009.002010.0
SalePrice1460.0180921.19589079442.50288334900.0129975.00163000.0214000.00755000.0

缺失值

msno.matrix(house_train, labels=True)

msno.bar(house_train)

msno.heatmap(house_train)

data_null = house_train.isnull().sum()
data_null[data_null>0].sort_values(ascending=False)
PoolQC          1453
MiscFeature     1406
Alley           1369
Fence           1179
FireplaceQu      690
LotFrontage      259
GarageYrBlt       81
GarageType        81
GarageFinish      81
GarageQual        81
GarageCond        81
BsmtFinType2      38
BsmtExposure      38
BsmtFinType1      37
BsmtCond          37
BsmtQual          37
MasVnrArea         8
MasVnrType         8
Electrical         1
dtype: int64

可视化

# numeric features
numeric_dtypes = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
numeric = []
for col in lumns:if house_train[col].dtype in numeric_dtypes:if col in ['TotalSF', 'Total_Bathrooms','Total_porch_sf','haspool','hasgarage','hasbsmt','hasfireplace']:passelse:numeric.append(col)     fig, axs = plt.subplots(ncols=2, nrows=0, figsize=(12, 120))
# 调整子图布局
plt.subplots_adjust(right=2,top=2)
# 显示husl颜色空间平均分布的8个颜色
lor_palette("husl", 8)
# 从1开始
for i, feature in enumerate(list(house_train[numeric]),1):if(feature=='MiscVal'):breakplt.subplot(len(list(numeric)), 3, i)sns.scatterplot(x=feature,y='SalePrice',hue='SalePrice',palette='Blues',data=house_train)# labelpad:控制刻度标注的上下位置plt.xlabel('{}'.format(feature),size=15,labelpad=12.5)plt.ylabel('SalePrice', size=15, labelpad=12.5)for j in range(2):plt.tick_params(axis='x', labelsize=12)plt.tick_params(axis='y', labelsize=12)plt.legend(loc='best', prop={'size': 10})plt.show()

查看目标数据

  • SalePrice不是正太分布,高度偏斜
  • 平均售价为180921美元,拉向离群值的上端。
  • 中位数163000美元,低于平均值。
  • 上端有异常值
house_train['SalePrice'].describe()
count      1460.000000
mean     180921.195890
std       79442.502883
min       34900.000000
25%      129975.000000
50%      163000.000000
75%      214000.000000
max      755000.000000
Name: SalePrice, dtype: float64
f,ax = plt.subplots(1,2,figsize=(16,6))
sns.distplot(house_train['SalePrice'],fit&#,ax=ax[0])
sns.boxplot(house_train['SalePrice'])#skewness and kurtosis
print("Skewness: {}".format(house_train['SalePrice'].skew()))
print("Kurtosis: {}".format(house_train['SalePrice'].kurt()))
Skewness: 1.8828757597682129
Kurtosis: 6.536281860064529

fig = plt.figure()
stats.probplot(house_train['SalePrice'],plot=plt)
((array([-3.30513952, -3.04793228, -2.90489705, ...,  2.90489705,3.04793228,  3.30513952]),array([ 34900,  35311,  37900, ..., 625000, 745000, 755000])),(74160.16474519414, 180921.19589041095, 0.9319665641512983))

# 数据变换
house_train['SalePrice'] = np.log1p(house_train['SalePrice'])
fig = plt.figure()
stats.probplot(house_train['SalePrice'],plot=plt)
((array([-3.30513952, -3.04793228, -2.90489705, ...,  2.90489705,3.04793228,  3.30513952]),array([10.46027076, 10.47197813, 10.54273278, ..., 13.34550853,13.52114084, 13.53447435])),(0.398259646654151, 12.024057394918403, 0.9953761551826702))

特征相关性

def draw_corr(data):corr = ()plt.subplots(figsize=(12,12))sns.heatmap(corr,vmax=1,square=True,cmap='Blues')plt.show()draw_corr(house_train)

# 相关性最大的10个特征
corrmat = ()
plt.subplots(figsize=(10,8))
k = 10
cols = corrmat.nlargest(k, 'SalePrice')['SalePrice'].index
cm = np.corrcoef(house_train[cols].values.T)# annot_kws:当annot为True时,可设置各个参数,包括大小size,颜色color,加粗,斜体字等
# fmt:格式设置 这里保留2位小数
sns.heatmap(cm,cbar=True, annot=True, square=True,fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)

1.OverallQual
f,ax = plt.subplots(figsize=(8,6))
fig = sns.boxplot(x='OverallQual', y="SalePrice", data=house_train)

# 删除异常值
mask = (house_train['OverallQual']<5)&(house_train['SalePrice']>12)
house_train.drop(house_train[mask].index, inplace=True)
house_train.plot.scatter(x='OverallQual', y='SalePrice')

2.GrLivArea
house_train.plot.scatter(x='GrLivArea', y='SalePrice',alpha=0.3)

# 删除右下角两个异常值
mask = (house_train['GrLivArea']>4000)&(house_train['SalePrice']<12.5)
house_train= house_train.drop(house_train[mask].index)# 删除异常值后
fig,ax = plt.subplots()
ax.scatter(x=house_train['GrLivArea'],y=house_train['SalePrice'])
plt.xlabel('GrLivArea',fontsize=13)
plt.ylabel('SalePrice',fontsize=13)

3.GarageCars
house_train.plot.scatter(x='GarageCars', y='SalePrice', alpha=0.3)

4.GarageArea
house_train.plot.scatter(x='GarageArea', y='SalePrice')

# 删除异常值
mask = (house_train['GarageArea']>1100)&(house_train['SalePrice']<12.5)
house_train.drop(house_train[mask].index, inplace=True)house_train.plot.scatter(x='GarageArea', y='SalePrice')

5.TotalBsmtSF
house_train.plot.scatter(x='TotalBsmtSF', y='SalePrice')

6.1stFlrSF
house_train.plot.scatter(x='1stFlrSF', y='SalePrice')

7.FullBath
house_train.plot.scatter(x='FullBath', y='SalePrice')

8.YearBuilt
house_train.plot.scatter(x='YearBuilt', y='SalePrice')

# 删除异常值
mask = (house_train['YearBuilt']<1900)&(house_train['SalePrice']>12.3)
house_train= house_train.drop(house_train[mask].index)# 删除异常值后
house_train.plot.scatter(x='YearBuilt', y='SalePrice')

9.YearRemodAdd
house_train.plot.scatter(x='YearRemodAdd', y='SalePrice')

# 重置索引
set_index(drop=True,inplace=True)

特征工程

合并测试集和训练集,对整体数据做特征工程

train_num = house_train.shape[0]
test_num  = house_test.shape[0]train_y = house_train.SalePrice.valuesall_data = pd.concat((house_train,house_test)).reset_index(drop=True)
all_data.drop(['SalePrice','Id'],axis=1,inplace=True)
all_data.shape,train_num,test_num
((2908, 79), 1449, 1459)

缺失值处理

  • 将数值型特征的缺失值填充为他们对应的众数或0
  • 将类别型feautre里的缺失值全部填补为“None”
  • 删除无用特征
  • 对类别型特征编码,get_dummies
count = all_data.isnull().sum().sort_values(ascending=False)
ratio = count/len(all_data)*100
cols_type = all_data[count.index].dtypesmissing_data = pd.concat([count,ratio,cols_type],axis=1,keys=['count','ratio','cols_type'])
missing_data=missing_data[missing_data.ratio>0]
missing_data
countratiocols_type
PoolQC289999.690509object
MiscFeature280496.423659object
Alley271193.225585object
Fence233880.398900object
FireplaceQu141848.762036object
LotFrontage48416.643741float64
GarageCond1595.467675object
GarageQual1595.467675object
GarageYrBlt1595.467675float64
GarageFinish1595.467675object
GarageType1575.398900object
BsmtCond822.819807object
BsmtExposure822.819807object
BsmtQual812.785420object
BsmtFinType2802.751032object
BsmtFinType1792.716644object
MasVnrType240.825309object
MasVnrArea230.790922float64
MSZoning40.137552object
BsmtHalfBath20.068776float64
Utilities20.068776object
Functional20.068776object
BsmtFullBath20.068776float64
BsmtFinSF210.034388float64
BsmtFinSF110.034388float64
Exterior2nd10.034388object
BsmtUnfSF10.034388float64
TotalBsmtSF10.034388float64
Exterior1st10.034388object
SaleType10.034388object
Electrical10.034388object
KitchenQual10.034388object
GarageArea10.034388float64
GarageCars10.034388float64
# 可视化
f,axis = plt.subplots(figsize=(15,12))
icks(rotation='90')
sns.barplot(x=missing_data.index,y=missing_data.ratio)plt.xlabel('Features', fontsize=15)
plt.ylabel('Percent of missing values', fontsize=15)
plt.title('Percent missing data by feature', fontsize=15)

在赛事方提供的特征描述中说明了一部分特征值数据的缺失是由于房屋确实不存在此种类型的特征,因此对于这一部分特征的缺失值,根据特征的数据类型分别进行插补,类别特征的缺失值以一种新类别插补,数值特征以0值插补,剩余的那一部分缺失的特征值采用众数插补

None填充
str_cols = ["PoolQC" , "MiscFeature", "Alley", "Fence", "FireplaceQu", "GarageType", "GarageFinish", "GarageQual", "GarageCond",  "BsmtQual", "BsmtCond", "BsmtExposure", "BsmtFinType1", "BsmtFinType2", "MasVnrType", "MSSubClass"]
for col in str_cols:all_data[col].fillna("None",inplace=True)del str_cols, col
0填充
num_cols=["BsmtUnfSF","TotalBsmtSF","BsmtFinSF2","BsmtFinSF1","BsmtFullBath","BsmtHalfBath", "MasVnrArea","GarageCars","GarageArea","GarageYrBlt"]
for col in num_cols:all_data[col].fillna(0, inplace=True)
del num_cols, col
众数填充
other_cols = ["MSZoning", "Electrical", "KitchenQual", "Exterior1st", "Exterior2nd", "SaleType"]
for col in other_cols:all_data[col].fillna(all_data[col].mode()[0], inplace=True)del other_cols, col
lotfrontage

位于同一街道的相邻的房屋往往具有相同的街区面积属性

all_data["LotFrontage"] = upby("Neighborhood")["LotFrontage"].transform(lambda x: x.dian()))
Utilities

缺失值为2,而几乎所有的值都是AllPub,考虑删除

all_data["Utilities"].isnull().sum()
2
all_data["Utilities"].value_counts()
AllPub    2905
NoSeWa       1
Name: Utilities, dtype: int64
# 删除特征
all_data.drop(['Utilities'],axis=1,inplace=True)
Functional
all_data["Functional"] = all_data["Functional"].fillna("Typ")
# 查看缺失值
mask =all_data.isnull().sum().sort_values(ascending=False)>0
lumns[mask]
Index([], dtype='object')

编码

  • 顺序变量编码
  • LabelEncoder编码
  • 独热编码(get_dummies)
# 对顺序变量进行编码
def custom_coding(x):if(x=='Ex'):r = 0elif(x=='Gd'):r = 1elif(x=='TA'):r = 2elif(x=='Fa'):r = 3elif(x=='None'):r = 4else:r = 5return r
## 顺序变量特征编码
cols = ['BsmtCond','BsmtQual','ExterCond','ExterQual','FireplaceQu','GarageCond','GarageQual','HeatingQC','KitchenQual','PoolQC']
for col in cols:all_data[col] = all_data[col].apply(custom_coding)del cols, col

一些特征其被表示成数值特征缺乏意义,例如年份还有类别,这里将其转换为字符串,即类别型变量

cols = ['MSSubClass', 'YrSold', 'MoSold', 'OverallCond', "MSZoning", "BsmtFullBath", "BsmtHalfBath", "HalfBath","Functional", "Electrical", "KitchenQual","KitchenAbvGr", "SaleType", "Exterior1st", "Exterior2nd", "YearBuilt", "YearRemodAdd", "GarageYrBlt","BedroomAbvGr","LowQualFinSF"]
for col in cols:all_data[col] = all_data[col].astype(str)    
del cols, col
# 对年份类的数据等进行LabelEncoder编码
from sklearn.preprocessing import LabelEncoder# 年份等特征的标签编码
str_cols = ["YearBuilt", "YearRemodAdd", 'GarageYrBlt', "YrSold", 'MoSold']
for col in str_cols:all_data[col] = LabelEncoder().fit_transform(all_data[col])
# 为了后续构建有意义的其他特征而进行标签编码
lab_cols = ['Heating','BsmtFinType1', 'BsmtFinType2', 'Functional', 'Fence', 'BsmtExposure', 'GarageFinish', 'LandSlope', 'LotShape', 'PavedDrive', 'Street', 'Alley', 'CentralAir', 'MSSubClass', 'OverallCond', 'YrSold', 'MoSold', 'MSZoning','Neighborhood','Condition1','Condition2','BldgType','HouseStyle','Exterior1st','MasVnrType','Foundation', 'GarageType','SaleType','SaleCondition']for col in lab_cols:new_col = "labfit_" + colall_data[new_col] = LabelEncoder().fit_transform(all_data[col]) del col,str_cols,lab_cols,new_col

构建新特征

# 区域相关特征对于确定房价非常重要,增加了一个总面积的特征
all_data['TotalHouseArea'] = all_data['TotalBsmtSF'] + all_data['1stFlrSF'] + all_data['2ndFlrSF']
# 房屋改造时间(YearsSinceRemodel)与房屋出售时间(YrSold)间隔时间的长短通常也会影响房价
all_data['YearsSinceRemodel'] = all_data['YrSold'].astype(int) - all_data['YearRemodAdd'].astype(int)
# 房屋的整体质量特征也是影响房价的重要要因素
all_data['Total_Home_Quality'] = all_data['OverallQual'].astype(int) + all_data['OverallCond'].astype(int)

房屋内某些区域空间的有无通常也是影响房屋价格的重要因素,例如有三季门廊区(3SsnPorch)、开放式门廊(OpenPorchSF)的房屋可能就比没有三级门廊区的房屋价格贵。因此这里我们再增添几个特征用于描述房屋内是否存在这些区域空间

all_data['HasWoodDeck'] = (all_data['WoodDeckSF'] == 0) * 1
all_data['HasOpenPorch'] = (all_data['OpenPorchSF'] == 0) * 1
all_data['HasEnclosedPorch'] = (all_data['EnclosedPorch'] == 0) * 1
all_data['Has3SsnPorch'] = (all_data['3SsnPorch'] == 0) * 1
all_data['HasScreenPorch'] = (all_data['ScreenPorch'] == 0) * 1
# 房屋总面积加车库面积
all_data["TotalAllArea"] = all_data["TotalHouseArea"] + all_data["GarageArea"]
# 房屋总面积和房屋材质指标乘积
all_data["TotalHouse_and_OverallQual"] = all_data["TotalHouseArea"] * all_data["OverallQual"]# 地面上居住总面积和房屋材质指标乘积
all_data["GrLivArea_and_OverallQual"] = all_data["GrLivArea"] * all_data["OverallQual"]# 地段总面积和房屋材质指标乘积
all_data["LotArea_and_OverallQual"] = all_data["LotArea"] * all_data["OverallQual"]# 一般区域分类与房屋总面积的乘积
all_data["MSZoning_and_TotalHouse"] = all_data["labfit_MSZoning"] * all_data["TotalHouseArea"]
# 一般区域分类指标与房屋材质指标之和
all_data["MSZoning_and_OverallQual"] = all_data["labfit_MSZoning"] + all_data["OverallQual"]
# 一般区域分类指标与初始建设年份之和
all_data["MSZoning_and_YearBuilt"] = all_data["labfit_MSZoning"] + all_data["YearBuilt"]      
# 地理邻近环境位置指标与总房屋面积之积
all_data["Neighborhood_and_TotalHouse"] = all_data["labfit_Neighborhood"] * all_data["TotalHouseArea"]
all_data["Neighborhood_and_OverallQual"] = all_data["labfit_Neighborhood"] + all_data["OverallQual"]  
all_data["Neighborhood_and_YearBuilt"] = all_data["labfit_Neighborhood"] + all_data["YearBuilt"]# 1型成品的面积和房屋材质指标乘积
all_data["BsmtFinSF1_and_OverallQual"] = all_data["BsmtFinSF1"] * all_data["OverallQual"]
## 家庭功能评级指标与房屋总面积的乘积
all_data["Functional_and_TotalHouse"] = all_data["labfit_Functional"] * all_data["TotalHouseArea"]
all_data["Functional_and_OverallQual"] = all_data["labfit_Functional"] + all_data["OverallQual"]
all_data["TotalHouse_and_LotArea"] = all_data["TotalHouseArea"] + all_data["LotArea"]
# 房屋与靠近公路或铁路指标乘积系数
all_data["Condition1_and_TotalHouse"] = all_data["labfit_Condition1"] * all_data["TotalHouseArea"]
all_data["Condition1_and_OverallQual"] = all_data["labfit_Condition1"] + all_data["OverallQual"]
# 地下室相关面积总和指标
all_data["Bsmt"] = all_data["BsmtFinSF1"] + all_data["BsmtFinSF2"] + all_data["BsmtUnfSF"]
# 地面上全浴室和地面上房间总数量之和
all_data["Rooms"] = all_data["FullBath"]+all_data["TotRmsAbvGrd"]
# 开放式门廊、围廊、三季门廊、屏风玄关总面积
all_data["PorchArea"] = all_data["OpenPorchSF"]+all_data["EnclosedPorch"]+all_data["3SsnPorch"]+all_data["ScreenPorch"]    
## 全部功能区总面积(房屋、地下室、车库、门廊等)
all_data["TotalPlace"] = all_data["TotalAllArea"] + all_data["PorchArea"]   

Log变换

将数值型feature里skew(偏度)绝对值大于0.75的特征进行一个log变换,将非正态的数据修正为接近正态分布的数据,以便满足线性模型的需要。

为什么要通过函数变换来改变原始数值型特征的分布呢?

  1. 变换后可以更加便捷的发现数据之间的关系:从没有关系变成有关系,使得模型更好利用数据;
  2. 很多特征的数据呈现严重的偏态分布(例如:很多偏小的值聚在一起),变换后可以拉开差异;
  3. 让数据符合模型理论所需要的假设,然后对其进行分析,例如变换后的数据呈现正态分布;

常用数据转换方法的有:对数转换,box-cox转换等变换方式,其中对数转换的方式是最为常用的,取对数之后数据的性质和相关关系不会发生改变,但压缩了变量的尺度,大大方便了计算。

from scipy.stats import norm, skew# 计算各数值型特征变量的偏度
num_features = all_data.select_dtypes(include=['int64','float64','int32']).copy()
num_feature_names = list(lumns)skewed_feats = all_data[num_feature_names].apply(lambda x: skew(x.dropna())).sort_values(ascending=False)
skewness = pd.DataFrame({'Skew' :skewed_feats})
skewness[skewness["Skew"].abs()>0.75]
Skew
MiscVal21.915535
PoolArea17.661095
LotArea13.334935
labfit_Condition212.437736
TotalHouse_and_LotArea12.380094
labfit_Heating12.136394
LotArea_and_OverallQual11.799484
3SsnPorch11.354131
labfit_LandSlope5.009358
BsmtFinSF24.137116
EnclosedPorch4.005089
ScreenPorch3.926054
GarageCond3.153395
labfit_Condition13.005668
GarageQual2.863557
MasVnrArea2.619878
Condition1_and_TotalHouse2.544979
BsmtCond2.542349
OpenPorchSF2.493685
PorchArea2.232411
labfit_BldgType2.186631
BsmtFinSF1_and_OverallQual2.017572
WoodDeckSF1.852261
TotalHouse_and_OverallQual1.615116
GrLivArea_and_OverallQual1.485190
1stFlrSF1.264660
LotFrontage1.106714
GrLivArea1.048644
TotalHouseArea1.012116
BsmtFinSF10.982488
BsmtUnfSF0.919524
TotalAllArea0.891388
TotalPlace0.887892
2ndFlrSF0.853227
Neighborhood_and_TotalHouse0.852391
ExterQual-0.784824
ExterCond-0.838720
Functional_and_OverallQual-0.920453
labfit_BsmtExposure-1.116930
labfit_MSZoning-1.745237
HasEnclosedPorch-1.880501
labfit_Fence-1.990335
labfit_SaleCondition-2.785113
HasScreenPorch-2.915483
labfit_PavedDrive-2.979584
labfit_BsmtFinType2-3.036904
labfit_CentralAir-3.461892
labfit_SaleType-3.737598
labfit_Functional-4.062504
Has3SsnPorch-8.695256
labfit_Street-16.166862
PoolQC-20.309793

设置阈值为1,对偏度大于阈值的特征进行log函数变换操作以提升质量

skew_cols = list(skewness[skewness["Skew"].abs()>1].index)
for col in skew_cols:# 偏度超过阈值的特征做box-cox变换# all_data[col] = boxcox1p(all_data[col], 0.15)# 偏度超过阈值的特征对数变换all_data[col] = np.log1p(all_data[col])
# 查看字符特征变量
all_data.info()
<class &#frame.DataFrame'>
RangeIndex: 2908 entries, 0 to 2907
Columns: 135 entries, MSSubClass to TotalPlace
dtypes: float64(54), int64(40), object(41)
memory usage: 3.0+ MB
# 对于这些剩下的字符型特征,采用独热编码的方式,将其转化为数值型的特征
all_data = pd.get_dummies(all_data)
all_data.head()
LotFrontageLotAreaOverallQualYearBuiltYearRemodAddMasVnrAreaExterQualExterCondBsmtQualBsmtCond...SaleType_ConLwSaleType_NewSaleType_OthSaleType_WDSaleCondition_AbnormlSaleCondition_AdjLandSaleCondition_AllocaSaleCondition_FamilySaleCondition_NormalSaleCondition_Partial
04.1896559.0420407109535.2832041211.098612...0001000010
14.3944499.169623682260.0000002211.098612...0001000010
24.2341079.3282127107525.0937501211.098612...0001000010
34.1108749.164401724200.0000002220.693147...0001100000
44.4426519.5652848106505.8607861211.098612...0001000010

5 rows × 393 columns

all_data.info()
all_data.shape
<class &#frame.DataFrame'>
RangeIndex: 2908 entries, 0 to 2907
Columns: 393 entries, LotFrontage to SaleCondition_Partial
dtypes: float64(54), int64(40), uint8(299)
memory usage: 2.9 MB(2908, 393)

特征降维

可以看到总共才2908行数据,就有390维特征,特征比较多,我们在这里使用Lasso进行降维

# 划分数据集
def split_data(all_data,train_index):cols = list(lumns)# 用众数填充特征工程中产生的异常值(正负无穷大)for col in cols:all_data[col].values[np.isinf(all_data[col].values)]=all_data[col].median()del cols,coltrain_data = all_data[:train_index]test_data  = all_data[train_index:]return train_data,test_data
train_X,test_X = split_data(all_data,train_num)
train_X.shape,test_X.shape,train_y.shape
((1449, 393), (1459, 393), (1449,))

1.针对离群点做标准化处理

from sklearn.preprocessing import RobustScalerscaler = RobustScaler()
# 训练集特征归一化
train_X = scaler.fit_transform(train_X)
# 测试集特征归一化
test_X = ansform(test_X)

2.建模

from sklearn.linear_model import Lassolasso_model = Lasso(alpha=0.001)
lasso_model.fit(train_X,train_y)
Lasso(alpha=0.001, copy_X=True, fit_intercept=True, max_iter=1000,normalize=False, positive=False, precompute=False, random_state=None,selection='cyclic', tol=0.0001, warm_start=False)
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)# 索引和特征重要性
FI_lasso = pd.DataFrame({"Feature Importance":f_},index=lumns)
# 由高到低进行排序
FI_lasso.sort_values("Feature Importance",ascending=False).round(5).head(10)
Feature Importance
Neighborhood_Crawfor0.09052
Total_Home_Quality0.08677
TotalPlace0.07877
GrLivArea0.06999
KitchenQual_00.05483
Functional_and_TotalHouse0.04605
labfit_SaleCondition0.04488
Exterior1st_BrkFace0.04458
YearBuilt0.03844
MSZoning_and_YearBuilt0.03626

3.可视化

# 不为0的特征
FI_lasso=FI_lasso[FI_lasso["Feature Importance"] !=0 ].sort_values("Feature Importance")
FI_lasso.plot(kind="barh",figsize=(12,40), color='g')
icks(rotation=90)display(FI_lasso.shape)

4.特征选择

# 挑选特征
choose_cols = FI_list()
choose_data = all_data[choose_cols].copy()choose_data.shape
(2908, 86)

数据建模

# 划分数据集
train_X, test_X = choose_data[:train_num], choose_data[train_num:]
# 标准化处理
scaler = RobustScaler()
train_X = scaler.fit_transform(train_X)
test_X = ansform(test_X)train_X.shape,test_X.shape,train_y.shape
((1449, 86), (1459, 86), (1449,))
# Models
semble import RandomForestRegressor,GradientBoostingRegressor,ExtraTreesRegressor
from sklearn.kernel_ridge import KernelRidge
from sklearn.linear_model import Ridge,RidgeCV,Lasso,LinearRegression
from sklearn.linear_model import ElasticNet,ElasticNetCV,SGDRegressor,BayesianRidge
from sklearn.svm import SVR,LinearSVR
ssor import StackingCVRegressor
from sklearn.kernel_ridge import KernelRidge
import lightgbm as lgb
from lightgbm import LGBMRegressor
from xgboost import XGBRegressor# Misc
del_selection import GridSearchCV,KFold, cross_val_score
ics import mean_squared_error
from sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCA
from sklearn.base import BaseEstimator, TransformerMixin, RegressorMixin, clone# 12折交叉验证
kf = KFold(n_splits=12,random_state=42,shuffle=True)

评分函数

# 均方根误差
def rmse(y,y_pred):return np.sqrt(mean_squared_error(y,y_pred))def cv_rmse(model,X,y):# neg_mean_squared_error 负均方根误差rmse = np.sqrt(-cross_val_score(model,X,y,scoring="neg_mean_squared_error",cv=kf))return rmse

主成分分析

前面新建的特征和原始特征存在相关性,这可能导致较强的多重共线性 (Multicollinearity)

pca_model = PCA(n_components=60)
train_X = pca_model.fit_transform(train_X)
test_X  = ansform(test_X)

集成学习

通常对于一个问题,我们可以依据数据构建不同的模型去求解,这些模型站在不同的角度去解释数据的内部结构。我们可以融合不同的求解方法,得到更优的求解结果。在集成学习中,我们要做的事情就是构建不同的个体学习器,并将它们很好的进行集成。关键在于同一个训练集上训练出来的模型相关性很高,而我们希望它们“不同”,这样才能查漏补缺,取得更好的结果。

  • Bagging 基于数据去做,采用从训练集中有放回的采样方式,得到一个新的训练集,去训练个体学习器
  • Boosting 串行的去训练个体学习器,使用个体学习器对数据进行学习,将数据中做错的样本权值增大,做对的样本权值减小,然后继续训练处下一个个体学习,以此类推,直到我们的错误率低于我们的阈值。

Stacking和Blending属于Bagging方法,两者的不同之处在于采用不同的方式融合个体学习器,前者非线性,后者线性。

# 网格搜索
def get_best_model_and_accuracy(model, params, X, y):# 如果报错,结果是0grid = GridSearchCV(model,params,scoring='neg_mean_squared_error',cv=5,n_jobs=-1,error_score=0.)grid.fit(X, y) # 拟合模型和参数# 经典的性能指标print("Best Score: {}".format(np.sqrt(-grid.best_score_)))# 得到最佳准确率的最佳参数print("Best Parameters: {}".format(grid.best_params_))# 拟合的平均时间(秒)print("Average Time to Fit (s): {}".format(round(grid.cv_results_['mean_fit_time'].mean(), 3)))# 预测的平均时间(秒)# 从该指标可以看出模型在真实世界的性能print("Average Time to Score (s): {}".format(round(grid.cv_results_['mean_score_time'].mean(), 3)))grid.cv_results_['mean_test_score'] = np.sqrt(-grid.cv_results_['mean_test_score'])# 打印单独的各参数组合参数及对应的评估指标print(pd.DataFrame(grid.cv_results_)[['params','mean_test_score','std_test_score']])return grid
Lasso
param_Lasso = {'alpha': [0.0004,0.0005,0.0006],'max_iter':[10000],'random_state':[1]}
Lasso_grid =get_best_model_and_accuracy(Lasso(),param_Lasso,train_X,train_y)
Best Score: 0.11233809637926326
Best Parameters: {'alpha': 0.0004, 'max_iter': 10000, 'random_state': 1}
Average Time to Fit (s): 0.002
Average Time to Score (s): 0.0params  mean_test_score  
0  {'alpha': 0.0004, 'max_iter': 10000, 'random_state': 1}         0.112338   
1  {'alpha': 0.0005, 'max_iter': 10000, 'random_state': 1}         0.112341   
2  {'alpha': 0.0006, 'max_iter': 10000, 'random_state': 1}         0.112416   std_test_score  
0        0.000861  
1        0.000884  
2        0.000907  
Ridge
param_Ridge = {'alpha':[35,40,45,50,55]}
Ridge_grid =get_best_model_and_accuracy(Ridge(),param_Ridge,train_X,train_y)
Best Score: 0.11201108834987004
Best Parameters: {'alpha': 35}
Average Time to Fit (s): 0.001
Average Time to Score (s): 0.0params  mean_test_score  std_test_score
0  {'alpha': 35}         0.112011        0.000953
1  {'alpha': 40}         0.112035        0.000967
2  {'alpha': 45}         0.112073        0.000980
3  {'alpha': 50}         0.112122        0.000991
4  {'alpha': 55}         0.112180        0.001001
SVR
param_SVR = {'C':[11,12,13,14,15],'kernel':["rbf"],"gamma":[0.0003,0.0004],"epsilon":[0.008,0.009]}
SVR_grid =get_best_model_and_accuracy(SVR(),param_SVR,train_X,train_y)
Best Score: 0.11185206657627142
Best Parameters: {'C': 15, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}
Average Time to Fit (s): 0.317
Average Time to Score (s): 0.044params  
0   {'C': 11, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
1   {'C': 11, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
2   {'C': 11, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
3   {'C': 11, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   
4   {'C': 12, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
5   {'C': 12, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
6   {'C': 12, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
7   {'C': 12, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   
8   {'C': 13, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
9   {'C': 13, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
10  {'C': 13, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
11  {'C': 13, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   
12  {'C': 14, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
13  {'C': 14, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
14  {'C': 14, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
15  {'C': 14, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   
16  {'C': 15, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
17  {'C': 15, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
18  {'C': 15, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
19  {'C': 15, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   mean_test_score  std_test_score  
0          0.112221        0.001143  
1          0.111954        0.001126  
2          0.112240        0.001131  
3          0.112010        0.001115  
4          0.112148        0.001147  
5          0.111916        0.001105  
6          0.112193        0.001135  
7          0.111954        0.001103  
8          0.112077        0.001141  
9          0.111902        0.001092  
10         0.112097        0.001137  
11         0.111994        0.001098  
12         0.112045        0.001135  
13         0.111888        0.001081  
14         0.112054        0.001127  
15         0.111958        0.001082  
16         0.112021        0.001123  
17         0.111852        0.001068  
18         0.112056        0.001113  
19         0.111902        0.001071  
KernelRidge
param_KernelRidge = {'alpha':[0.3,0.4,0.5], 'kernel':["polynomial"],'degree':[3],'coef0':[0.8,1,1.2]}KernelRidge_grid =get_best_model_and_accuracy(KernelRidge(),param_KernelRidge,train_X,train_y)
Best Score: 0.12053877269961878
Best Parameters: {'alpha': 0.5, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}
Average Time to Fit (s): 0.207
Average Time to Score (s): 0.037params  
0  {'alpha': 0.3, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
1    {'alpha': 0.3, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
2  {'alpha': 0.3, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   
3  {'alpha': 0.4, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
4    {'alpha': 0.4, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
5  {'alpha': 0.4, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   
6  {'alpha': 0.5, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
7    {'alpha': 0.5, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
8  {'alpha': 0.5, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   mean_test_score  std_test_score  
0         0.131492        0.001534  
1         0.124723        0.001179  
2         0.123360        0.001052  
3         0.132097        0.001687  
4         0.123652        0.001257  
5         0.121633        0.001096  
6         0.133186        0.001837  
7         0.123168        0.001331  
8         0.120539        0.001138  
ElasticNet

ElasticNet可以看做Lasso和Ridge的中庸化的产物。它也是对普通的线性回归做了正则化,但是它的损失函数既不全是L1的正则化,也不全是L2的正则化,而是用一个权重参数ρ来平衡L1和L2正则化的比重

机器学习算法之岭回归、Lasso回归和ElasticNet回归

param_ElasticNet = {'alpha':[0.0008,0.004,0.005],'l1_ratio':[0.08,0.1,0.3,0.5],'max_iter':[10000],'random_state':[3]}
ElasticNet_grid =get_best_model_and_accuracy(ElasticNet(),param_ElasticNet,train_X,train_y)
Best Score: 0.11223819703859092
Best Parameters: {'alpha': 0.005, 'l1_ratio': 0.08, 'max_iter': 10000, 'random_state': 3}
Average Time to Fit (s): 0.001
Average Time to Score (s): 0.0params  
0   {'alpha': 0.0008, 'l1_ratio': 0.08, 'max_iter': 10000, 'random_state': 3}   
1    {'alpha': 0.0008, 'l1_ratio': 0.1, 'max_iter': 10000, 'random_state': 3}   
2    {'alpha': 0.0008, 'l1_ratio': 0.3, 'max_iter': 10000, 'random_state': 3}   
3    {'alpha': 0.0008, 'l1_ratio': 0.5, 'max_iter': 10000, 'random_state': 3}   
4    {'alpha': 0.004, 'l1_ratio': 0.08, 'max_iter': 10000, 'random_state': 3}   
5     {'alpha': 0.004, 'l1_ratio': 0.1, 'max_iter': 10000, 'random_state': 3}   
6     {'alpha': 0.004, 'l1_ratio': 0.3, 'max_iter': 10000, 'random_state': 3}   
7     {'alpha': 0.004, 'l1_ratio': 0.5, 'max_iter': 10000, 'random_state': 3}   
8    {'alpha': 0.005, 'l1_ratio': 0.08, 'max_iter': 10000, 'random_state': 3}   
9     {'alpha': 0.005, 'l1_ratio': 0.1, 'max_iter': 10000, 'random_state': 3}   
10    {'alpha': 0.005, 'l1_ratio': 0.3, 'max_iter': 10000, 'random_state': 3}   
11    {'alpha': 0.005, 'l1_ratio': 0.5, 'max_iter': 10000, 'random_state': 3}   mean_test_score  std_test_score  
0          0.112599        0.000791  
1          0.112573        0.000795  
2          0.112379        0.000828  
3          0.112327        0.000865  
4          0.112244        0.000872  
5          0.112254        0.000888  
6          0.113251        0.001022  
7          0.114522        0.001099  
8          0.112238        0.000895  
9          0.112282        0.000914  
10         0.113737        0.001056  
11         0.115224        0.001138  
bay = BayesianRidge()
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)lgbm = LGBMRegressor(objective='regression',num_leaves=5,learning_rate=0.05, n_estimators=700,max_bin = 55,bagging_fraction = 0.8,bagging_freq = 5, feature_fraction = 0.25,feature_fraction_seed=9, bagging_seed=9,min_data_in_leaf = 6, min_sum_hessian_in_leaf = 11)GBR = 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)
Stacking

Stacking的学习器分两层,第一层是若干个弱学习器,它们分别进行预测,然后把预测结果传递给第二层;第二层学习器基于第一层的预测结果预测。

Stacking容易过拟合,采用K-Fold方法进行训练:

  1. 将训练集分成5份,迭代5次,每次迭代都将4份数据作为Train Set对每个Base Model进行训练,然后剩下的一份作为Hold-out Set进行预测。同时,每个Base Model在Test Set的预测值也要保存下来。经过5-Flod迭代后,我们获得了一个:训练样本行数 * 模型数量 的矩阵(每个Base Model在进行cv 的过程,分别会对每一份Hold-out-set进行预测,汇总产生一个对所有训练集的预测),这个矩阵作为第二层的训练数据进行训练,得到model B。

  2. 将之前保存的每个Base Model对测试集进行的预测的平均值拼成一个:测试样本行数 * 模型数量 的矩阵(每个Base Model会对测试集进行5-fold次预测,所以在拼测试数据的预测结果之前,需要对每个Base Model预测5-Fold次的预测结果求均值)。

  3. model B对测试集的预测进行预测。

class stacking(BaseEstimator, RegressorMixin, TransformerMixin):def __init__(self,mod,meta_model):d = mod  # 首层学习器模型a_model = meta_model  # 次学习器模型# 堆叠的最大特征划分折数self.k=5self.kf = KFold(n_splits=self.k, random_state=42, shuffle=True)# 训练数据def fit(self,X,y):# self.saved_model包含所有第一层学习器self.saved_model = [list() for i d]# 维度:训练样本行数*模型数量oof_train = np.zeros((X.shape[0], d)))for i,model in d): # 返回索引和模型本身#返回数据分割成分(训练集和验证集对应元素)的索引for train_index, val_index in self.kf.split(X,y):  renew_model = clone(model) # 模型的复制# 对分割出来的训练集数据进行训练renew_model.fit(X[train_index], y[train_index])# 添加模型 self.saved_model[i].append(renew_model)# 保存对应模型的验证集预测值oof_train[val_index,i] = renew_model.predict(X[val_index])# 次学习器模型训练,这里只是用到了首层预测值作为特征a_model.fit(oof_train,y)return self# 测试数据def predict(self,X):# 得到的是整个测试集的首层预测值,np.column_stack:左右根据列拼接 mean(axis=1):跨列求和whole_test = np.column_stack([np.column_stack(model.predict(X) for model in single_model).mean(axis=1) for single_model in self.saved_model])# 返回次学习器模型对整个测试集的首层预测值的最终预测a_model.predict(whole_test)            ## 获取首层学习结果的堆叠特征def get_oof(self,X,y,test_X):                 oof = np.zeros((X.shape[0],d)))test_single = np.zeros((test_X.shape[0],self.k))test_mean = np.zeros((test_X.shape[0],d)))for i,model in d):for j, (train_index,val_index) in enumerate(self.kf.split(X,y)):clone_model = clone(model)clone_model.fit(X[train_index],y[train_index])# 预测结果保存oof[val_index,i] = clone_model.predict(X[val_index])test_single[:,j] = clone_model.predict(test_X)# 对每个模型的测试集预测K-Fold结果取均值test_mean[:,i] = an(axis=1)return oof, test_mean
lasso = Lasso_grid.best_estimator_
ridge = Ridge_grid.best_estimator_
svr = SVR_grid.best_estimator_
ker = KernelRidge_grid.best_estimator_
ela= ElasticNet_grid.best_estimator_stack_model = stacking(mod=[bay,lasso,ridge,svr,ker,ela], meta_model=ker)# 查看训练集精度
score = cv_rmse(stack_model,train_X,train_y)
an())
0.10746634249868159
# 第二层学习器特征获取
x_train_stack, x_test_stack = _oof(train_X,train_y,test_X)
train_X.shape,train_y.shape,test_X.shape
((1449, 60), (1449,), (1459, 60))
# 第一层总共6个模型
x_train_stack.shape, x_test_stack.shape
((1449, 6), (1459, 6))

stacking的一般来说得到初级模型的预测值后,用次级模型训练预测就可以了。不过在本案例中,我们尝试将第一层得到的堆叠特征与初始特征进行合并,最后利用这些合并后的特征再次投入stacking里面进行训练。

# 将stacking特征和数据原始的特征拼接,水平方向上
x_train_add = np.hstack((train_X,x_train_stack))
x_test_add = np.hstack((test_X,x_test_stack))x_train_add.shape,x_test_add.shape
((1449, 66), (1459, 66))
# 查看拼接特征后的精度,发现效果有所提升
score =  cv_rmse(stack_model,x_train_add,train_y)
an())
0.10195220877304757

将x_train_add,train_y和x_test_add通过stacking重新进行训练

param_Lasso = {'alpha': [0.0004,0.0005,0.0006],'max_iter':[10000],'random_state':[1]}
Lasso_2 =get_best_model_and_accuracy(Lasso(),param_Lasso,x_train_add,train_y)
Best Score: 0.11162310214215297
Best Parameters: {'alpha': 0.0005, 'max_iter': 10000, 'random_state': 1}
Average Time to Fit (s): 0.009
Average Time to Score (s): 0.0params  mean_test_score  
0  {'alpha': 0.0004, 'max_iter': 10000, 'random_state': 1}         0.111637   
1  {'alpha': 0.0005, 'max_iter': 10000, 'random_state': 1}         0.111623   
2  {'alpha': 0.0006, 'max_iter': 10000, 'random_state': 1}         0.111662   std_test_score  
0        0.000880  
1        0.000896  
2        0.000909  
param_Ridge = {'alpha':[35,40,45,50,55]}
Ridge_2 =get_best_model_and_accuracy(Ridge(),param_Ridge,x_train_add,train_y)
Best Score: 0.1118608032209135
Best Parameters: {'alpha': 35}
Average Time to Fit (s): 0.002
Average Time to Score (s): 0.0params  mean_test_score  std_test_score
0  {'alpha': 35}         0.111861        0.000949
1  {'alpha': 40}         0.111892        0.000962
2  {'alpha': 45}         0.111924        0.000973
3  {'alpha': 50}         0.111960        0.000983
4  {'alpha': 55}         0.111999        0.000992
param_SVR = {'C':[11,12,13,14,15],'kernel':["rbf"],"gamma":[0.0003,0.0004],"epsilon":[0.008,0.009]}
SVR_2 =get_best_model_and_accuracy(SVR(),param_SVR,x_train_add,train_y)
Best Score: 0.11187202151025108
Best Parameters: {'C': 15, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}
Average Time to Fit (s): 0.316
Average Time to Score (s): 0.044params  
0   {'C': 11, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
1   {'C': 11, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
2   {'C': 11, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
3   {'C': 11, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   
4   {'C': 12, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
5   {'C': 12, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
6   {'C': 12, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
7   {'C': 12, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   
8   {'C': 13, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
9   {'C': 13, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
10  {'C': 13, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
11  {'C': 13, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   
12  {'C': 14, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
13  {'C': 14, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
14  {'C': 14, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
15  {'C': 14, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   
16  {'C': 15, 'epsilon': 0.008, 'gamma': 0.0003, 'kernel': 'rbf'}   
17  {'C': 15, 'epsilon': 0.008, 'gamma': 0.0004, 'kernel': 'rbf'}   
18  {'C': 15, 'epsilon': 0.009, 'gamma': 0.0003, 'kernel': 'rbf'}   
19  {'C': 15, 'epsilon': 0.009, 'gamma': 0.0004, 'kernel': 'rbf'}   mean_test_score  std_test_score  
0          0.112114        0.001168  
1          0.111980        0.001131  
2          0.112167        0.001164  
3          0.112013        0.001132  
4          0.112075        0.001161  
5          0.111909        0.001112  
6          0.112136        0.001158  
7          0.111960        0.001113  
8          0.112050        0.001159  
9          0.111898        0.001082  
10         0.112133        0.001152  
11         0.111930        0.001096  
12         0.112024        0.001159  
13         0.111873        0.001057  
14         0.112087        0.001149  
15         0.111928        0.001074  
16         0.111989        0.001150  
17         0.111872        0.001046  
18         0.112041        0.001143  
19         0.111910        0.001060  
param_KernelRidge = {'alpha':[0.3,0.4,0.5], 'kernel':["polynomial"],'degree':[3],'coef0':[0.8,1,1.2]}KernelRidge_2 =get_best_model_and_accuracy(KernelRidge(),param_KernelRidge,x_train_add,train_y)
Best Score: 0.11754411372302964
Best Parameters: {'alpha': 0.5, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}
Average Time to Fit (s): 0.184
Average Time to Score (s): 0.032params  
0  {'alpha': 0.3, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
1    {'alpha': 0.3, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
2  {'alpha': 0.3, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   
3  {'alpha': 0.4, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
4    {'alpha': 0.4, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
5  {'alpha': 0.4, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   
6  {'alpha': 0.5, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
7    {'alpha': 0.5, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
8  {'alpha': 0.5, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   mean_test_score  std_test_score  
0         0.121835        0.002417  
1         0.119743        0.002347  
2         0.118019        0.002291  
3         0.121416        0.002253  
4         0.119359        0.002201  
5         0.117628        0.002159  
6         0.121293        0.002123  
7         0.119272        0.002083  
8         0.117544        0.002051  
param_ElasticNet = {'alpha':[0.0008,0.004,0.005],'l1_ratio':[0.08,0.1,0.3,0.5],'max_iter':[10000],'random_state':[3]}
ElasticNet_2 =get_best_model_and_accuracy(ElasticNet(),param_ElasticNet,x_train_add,train_y)
Best Score: 0.10667612140906058
Best Parameters: {'alpha': 0.0008, 'l1_ratio': 0.08, 'max_iter': 10000, 'random_state': 3}
Average Time to Fit (s): 0.025
Average Time to Score (s): 0.0params  
0   {'alpha': 0.0008, 'l1_ratio': 0.08, 'max_iter': 10000, 'random_state': 3}   
1    {'alpha': 0.0008, 'l1_ratio': 0.1, 'max_iter': 10000, 'random_state': 3}   
2    {'alpha': 0.0008, 'l1_ratio': 0.3, 'max_iter': 10000, 'random_state': 3}   
3    {'alpha': 0.0008, 'l1_ratio': 0.5, 'max_iter': 10000, 'random_state': 3}   
4    {'alpha': 0.004, 'l1_ratio': 0.08, 'max_iter': 10000, 'random_state': 3}   
5     {'alpha': 0.004, 'l1_ratio': 0.1, 'max_iter': 10000, 'random_state': 3}   
6     {'alpha': 0.004, 'l1_ratio': 0.3, 'max_iter': 10000, 'random_state': 3}   
7     {'alpha': 0.004, 'l1_ratio': 0.5, 'max_iter': 10000, 'random_state': 3}   
8    {'alpha': 0.005, 'l1_ratio': 0.08, 'max_iter': 10000, 'random_state': 3}   
9     {'alpha': 0.005, 'l1_ratio': 0.1, 'max_iter': 10000, 'random_state': 3}   
10    {'alpha': 0.005, 'l1_ratio': 0.3, 'max_iter': 10000, 'random_state': 3}   
11    {'alpha': 0.005, 'l1_ratio': 0.5, 'max_iter': 10000, 'random_state': 3}   mean_test_score  std_test_score  
0          0.106676        0.000741  
1          0.107021        0.000758  
2          0.111335        0.000889  
3          0.111619        0.000880  
4          0.111584        0.000877  
5          0.111586        0.000891  
6          0.112205        0.001007  
7          0.113027        0.001072  
8          0.111594        0.000896  
9          0.111623        0.000914  
10         0.112603        0.001041  
11         0.113622        0.001111  
bay_2 = BayesianRidge()
xgb_2 = 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)lgbm_2 = LGBMRegressor(objective='regression',num_leaves=5,learning_rate=0.05,n_estimators=700,max_bin = 55,bagging_fraction = 0.8,bagging_freq = 5,feature_fraction = 0.25,feature_fraction_seed=9, bagging_seed=9,min_data_in_leaf = 6, min_sum_hessian_in_leaf = 11)GBR_2 = 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)lasso_2 = Lasso_2.best_estimator_
ridge_2 = Ridge_2.best_estimator_
svr_2 = SVR_2.best_estimator_
ker_2 = KernelRidge_2.best_estimator_
ela_2 = ElasticNet_2.best_estimator_stack_model_2 = stacking(mod=[bay_2,lasso_2,ridge_2,svr_2,ker_2,ela_2], meta_model=ker_2)
last_x_train_stack, last_x_test_stack = stack__oof(x_train_add,train_y,x_test_add)last_x_train_stack.shape, last_x_test_stack.shape
((1449, 6), (1459, 6))

第二层模型KernelRidge的参数搜索

param_ker = {'alpha':[0.2,0.3,0.4,0.5], 'kernel':["polynomial"],'degree':[3,4],'coef0':[0.8,1,1.2]}
Ker_stack_model=get_best_model_and_accuracy(KernelRidge(),param_ker,last_x_train_stack,train_y).best_estimator_
Best Score: 0.08808555947636867
Best Parameters: {'alpha': 0.2, 'coef0': 0.8, 'degree': 4, 'kernel': 'polynomial'}
Average Time to Fit (s): 0.186
Average Time to Score (s): 0.03params  
0   {'alpha': 0.2, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
1   {'alpha': 0.2, 'coef0': 0.8, 'degree': 4, 'kernel': 'polynomial'}   
2     {'alpha': 0.2, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
3     {'alpha': 0.2, 'coef0': 1, 'degree': 4, 'kernel': 'polynomial'}   
4   {'alpha': 0.2, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   
5   {'alpha': 0.2, 'coef0': 1.2, 'degree': 4, 'kernel': 'polynomial'}   
6   {'alpha': 0.3, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
7   {'alpha': 0.3, 'coef0': 0.8, 'degree': 4, 'kernel': 'polynomial'}   
8     {'alpha': 0.3, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
9     {'alpha': 0.3, 'coef0': 1, 'degree': 4, 'kernel': 'polynomial'}   
10  {'alpha': 0.3, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   
11  {'alpha': 0.3, 'coef0': 1.2, 'degree': 4, 'kernel': 'polynomial'}   
12  {'alpha': 0.4, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
13  {'alpha': 0.4, 'coef0': 0.8, 'degree': 4, 'kernel': 'polynomial'}   
14    {'alpha': 0.4, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
15    {'alpha': 0.4, 'coef0': 1, 'degree': 4, 'kernel': 'polynomial'}   
16  {'alpha': 0.4, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   
17  {'alpha': 0.4, 'coef0': 1.2, 'degree': 4, 'kernel': 'polynomial'}   
18  {'alpha': 0.5, 'coef0': 0.8, 'degree': 3, 'kernel': 'polynomial'}   
19  {'alpha': 0.5, 'coef0': 0.8, 'degree': 4, 'kernel': 'polynomial'}   
20    {'alpha': 0.5, 'coef0': 1, 'degree': 3, 'kernel': 'polynomial'}   
21    {'alpha': 0.5, 'coef0': 1, 'degree': 4, 'kernel': 'polynomial'}   
22  {'alpha': 0.5, 'coef0': 1.2, 'degree': 3, 'kernel': 'polynomial'}   
23  {'alpha': 0.5, 'coef0': 1.2, 'degree': 4, 'kernel': 'polynomial'}   mean_test_score  std_test_score  
0          0.089836        0.000473  
1          0.088086        0.000600  
2          0.089773        0.000480  
3          0.088102        0.000599  
4          0.089749        0.000485  
5          0.088118        0.000599  
6          0.090043        0.000456  
7          0.088470        0.000586  
8          0.089935        0.000462  
9          0.088486        0.000586  
10         0.089885        0.000468  
11         0.088501        0.000586  
12         0.090214        0.000443  
13         0.088732        0.000579  
14         0.090070        0.000449  
15         0.088748        0.000580  
16         0.089994        0.000455  
17         0.088762        0.000581  
18         0.090358        0.000434  
19         0.088920        0.000576  
20         0.090184        0.000439  
21         0.088936        0.000577  
22         0.090086        0.000445  
23         0.088949        0.000578  
cv_rmse(Ker_stack_model,last_x_train_stack,train_y).mean()
0.08791312508608311
# 注意之前对目标数据做过log变换
y_pred_stack = np.expm1(Ker_stack_model.predict(last_x_test_stack))

可以直接用stack_model类的函数拟合并预测数据

stack_model = stacking(mod=[lgbm,ela,svr,ridge,lasso,bay,xgb,GBR,ker],meta_model=KernelRidge(alpha=0.2 ,kernel='polynomial',degree=4, coef0=0.8))stack_model.fit(x_train_add,train_y)
y_pred_stack_2 = np.exp(stack_model.predict(x_test_add))
XGBoost建模预测
xgb.fit(last_x_train_stack,train_y)
y_pred_xgb = np.expm1(xgb.predict(last_x_test_stack))
# 交叉验证
cv_rmse(xgb,x_train_stack,train_y).mean()
0.1139198877562616
# 训练集误差
y_train_xgb = xgb.predict(last_x_train_stack)
rmse(y_train_xgb,train_y)
0.08778404527191365
LightGBM建模预测
lgbm.fit(last_x_train_stack,train_y)
y_pred_lgbm = np.expm1(lgbm.predict(last_x_test_stack))cv_rmse(lgbm,x_train_stack,train_y).mean()
0.1161628433489873
y_train_lgbm = xgb.predict(x_train_stack)
rmse(y_train_lgbm,train_y)
0.10937253913955777
# 模型融合
y_pred = (0.7*y_pred_stack)+(0.15*y_pred_xgb)+(0.15*y_pred_lgbm)
submission = pd.read_csv("/home/aistudio/data/data32288/submission.csv")submission.shape,y_pred.shape
((1459, 2), (1459,))
submission.iloc[:,1] = y_pred
_csv(r'./house_submission.csv',index=False)submission.head()
IdSalePrice
01461119962.721230
11462161987.446003
21463188901.912081
31464194701.643631
41465194480.370160
Blending

Blending与Stacking主要区别在于训练集不是通过K-Fold来获得预测值从而生成第二阶段模型的特征,而是建立一个Holdout集,第二阶段的stacker模型就基于第一阶段模型对验证集的预测值进行拟合。也就是就是把Stacking流程中的K-Fold CV 改成 HoldOut CV。

步骤:

  1. 把原始的训练集先分成两部分,比如70%的数据作为训练集,剩下30%的数据作为验证集。第一轮训练: 我们在这70%的数据上训练多个模型,然后去预测那30%验证数据的label,得到pre_val_set;同时也用这些模型去预测测试集得到pre_test_set。
  2. 第二轮训练,我们用pre_val_set做为新特征继续训练第二层的模型Model B
  3. 用Model B对pre_test_set进行预测,得到最终结果

Blending的优点:

  1. 比stacking简单(因为不用进行k次的交叉验证来获得stacker feature)
  2. 避开了一个信息泄露问题:generlizers和stacker使用了不一样的数据集
  3. 在团队建模过程中,不需要给队友分享自己的随机种子

Blending的缺点:

  1. 使用了很少的数据
  2. blender可能会过拟合(其实大概率是第一点导致的)
  3. stacking使用多次的CV会比较稳健
del_selection import StratifiedKFold,train_test_split# 模型融合中使用到的各个单模型
clfs = [BayesianRidge(),Lasso(),Ridge(),SVR(),KernelRidge(),ElasticNet()]# 切分训练数据集为train,val两部分
X_train, X_val, y_train, y_val = train_test_split(train_X,train_y,test_size=0.33, random_state=1855)
dataset_val = np.zeros((X_val.shape[0], len(clfs))) # 对验证集的预测
dataset_test = np.zeros((test_X.shape[0], len(clfs))) #对测试集的预测 # 依次训练各个单模型
for j, clf in enumerate(clfs):# 使用train_X训练模型,获得其预测的输出作为第2部分的新特征clf.fit(X_train, y_train)dataset_val[:, j] = clf.predict(X_val)# 对于测试集,直接用这k个模型的预测值作为新的特征dataset_test[:, j] = clf.predict(test_X)# 融合使用的模型
clf =  XGBRegressor()
clf.fit(dataset_val, y_val)# 注意前面对目标数据做过log变换
y_submission = np.expm1(clf.predict(dataset_test))
cv_rmse(clf,train_X,train_y).mean()
0.14310972129182878
y_submission
array([122274.41, 142203.67, 176042.67, ..., 164987.31, 107128.92,250321.12], dtype=float32)
y_pred_stack
array([118603.60717676, 162614.48976635, 190387.78002988, ...,179561.60366542, 117042.61233382, 223750.10906997])

可视化模型预测精度

# 使用mlxtend包
stack_gen = StackingCVRegressor(regressors=(lgbm,ela,svr,ridge,lasso,bay,xgb,GBR,ker),meta_regressor=ker,use_features_in_secondary=True)# 元分类器将根据原始回归器和原始数据集的预测进行训练

获取每个模型的交叉验证分数

scores = {}score = cv_rmse(lgbm,train_X,train_y)
print("lightgbm: {:.4f} ({:.4f})".an(), score.std()))
scores['lgbm'] = (an(), score.std())
lightgbm: 0.1280 (0.0148)
score = cv_rmse(ela,train_X,train_y)
print("ElasticNet: {:.4f} ({:.4f})".an(), score.std()))
scores['ela'] = (an(), score.std())
ElasticNet: 0.1108 (0.0151)
score = cv_rmse(svr,train_X,train_y)
print("SVR: {:.4f} ({:.4f})".an(), score.std()))
scores['svr'] = (an(), score.std())
SVR: 0.1096 (0.0172)
score = cv_rmse(ridge,train_X,train_y)
print("ridge: {:.4f} ({:.4f})".an(), score.std()))
scores['ridge'] = (an(), score.std())
ridge: 0.1106 (0.0154)
score = cv_rmse(lasso,train_X,train_y)
print("Lasso: {:.4f} ({:.4f})".an(), score.std()))
scores['Lasso'] = (an(), score.std())
Lasso: 0.1108 (0.0150)
score = cv_rmse(bay,train_X,train_y)
print("bay: {:.4f} ({:.4f})".an(), score.std()))
scores['bay'] = (an(), score.std())
bay: 0.1106 (0.0152)
score = cv_rmse(xgb,train_X,train_y)
print("xgb: {:.4f} ({:.4f})".an(), score.std()))
scores['xgb'] = (an(), score.std())
xgb: 0.1259 (0.0156)
score = cv_rmse(GBR,train_X,train_y)
print("GBR: {:.4f} ({:.4f})".an(), score.std()))
scores['GBR'] = (an(), score.std())
GBR: 0.1326 (0.0189)
score = cv_rmse(ker,train_X,train_y)
print("ker: {:.4f} ({:.4f})".an(), score.std()))
scores['ker'] = (an(), score.std())
ker: 0.1178 (0.0167)
score = cv_rmse(stack_gen,train_X,train_y)
print("stack_gen: {:.4f} ({:.4f})".an(), score.std()))
scores['stack_gen'] = (an(), score.std())
stack_gen: 0.1338 (0.0191)

确定性能最佳的模型

sns.set_style("white")
fig = plt.figure(figsize=(24, 12))ax = sns.pointplot(x=list(scores.keys()), y=[score for score, _ in scores.values()],markers=['o'], linestyles=['-'])
for i, score in enumerate(scores.values()):ax.text(i, score[0] + 0.002, '{:.6f}'.format(score[0]),horizontalalignment='left', size='large', color='black', weight='semibold')plt.ylabel('Score (RMSE)', size=20, labelpad=12.5)
plt.xlabel('Model', size=20, labelpad=12.5)
plt.tick_params(axis='x', labelsize=13.5)
plt.tick_params(axis='y', labelsize=12.5)plt.title('Scores of Models', size=20)
plt.show()

参考资料

  • kaggle竞赛项目:房价预测
  • Comprehensive data exploration with Python
  • Stacked Regressions : Top 4% on LeaderBoard
  • 模型融合之stacking&blending原理及代码

本文发布于:2024-02-02 03:47:29,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170681743741163.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:房价   Kaggle
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23