2、房價預測實戰中學到的經驗

用Bagging優化模型的過程:
1、對于要使用的弱模型(比如線性分類器、嶺回歸),通過交叉驗證的方式找到弱模型本身的最好超參數;
2、然后用這個帶著最好超參數的弱模型去構建強模型;
3、對強模型也是通過交叉驗證的方式找到強模型的最好超參數(比如弱模型的數量)

對于Bagging、RandomForest、Boosting這些組合算法,默認是用的弱模型是決策樹,但是可以通過base_estimator參數調整。

1、查看數據,數據預處理

讀入數據

train_df = pd.read_csv(filename,index_col=0)

dataframe.head()

觀察數據分布

對于連續型數值變量,查看的是直方圖。
對于分類型變量,查看的是頻數圖。其實和直方圖差不多。

首先,查看因變量(y,房價)的分布,看原始分布的時候,還做了個轉換,對房價取了個對數。同時查看兩狀態下的數據分布。

之所以看分布和做轉換,是因為用線性回歸有個條件是因變量符合正態分布,如果不是的話,最好做個平滑處理,讓其盡可能符合高斯分布,否則效果不會好。

%matplotlib inline
pricesDf = pd.DataFrame( {"price":df['salePrice'] ,"log_price+1":np.log1p(df['salePrice']) })
這行代碼其實是用原始數據中的房價和取對數后的房價創建了個新的DataFrame

log1p就是 log(x+1),可以避免出現負數結果,逼格很高。
不過,如果用平滑后的價格做模型,那么做預測時,預測結果也不要忘記反向操作,反向函數就是expm1,log反向是exp
priceDf.hist()
然后用柱狀圖繪制分布

測試數據和訓練數據合并

合并的目的是后續的特征處理時,就一并把訓練集和測試集的一并轉換了。
當然,最后訓練的時候還是要用訓練數據集,驗證時還是要用測試數據集。我們就直接用train_df.index和test_df.index把它們再提取出來就好了。

all_df = pd.concat((train_df,test_df), axis=0)

2、特征工程

把分類型變量數字化

當用數值型變量表達分類變量時,由于數字本身有大小的含義,所以亂給數字會給后來的模型學習帶來麻煩,所以對于分類型變量,更好的方法是one-hot編碼。

pandas方法
all_df['columnname'].value_count()
pd.get_dummies(all_df ['columnname'] , prefix='SomePrefix' ).head()

得到的one-hot column的名字是'SomePrefix_value'的樣式

也可以一次性對所有分類變量one-hot

all_dummy_df = all_df.get_dummies(all_df)
all_dummy_df.head()

對數值變量的處理

首當其沖就是對缺失值的處理。

缺失值的處理

查看缺失值最多的列

all_dummy_df.isnull().sum().sort_values(ascending=False).head()

對于缺失值的處理,需要根據具體的情況作處理。

比如,用均值填充

mean_cols=all_dummy_df.mean()
mean_cols.head(10)
用均值填充
all_dummy_df.fillna(mean_cols,inplace=True) 就地填充

數據分布標準化處理

并不是所有的模型都需要做數據分布的標準化處理,但是像回歸模型比較嬌貴,最好把自變量放在一個標準正態分布里,不要讓數據的差距太大。
當然對于哪些one-hot的列,因為只有0,1兩個值,所以不需要標準化,我們的目標應該只是那些本來就是數值型變量。

先看哪些列是數值型的
numeric_cols = all_df.columns[add_df.dtypes != 'object']
這些列就是數值型列的索引
計算標準分布: (x-x`)/s
numeric_col_means = all_dummy_df.loc[:,numeric_cols].mean()
numeric_col_std = all_dummy_df.loc[:,numeric_cols].std()
all_dummy_df.loc[:,numeric_cols]=(all_dummy_df.loc[:,numeric_cols] - umeric_col_means) / numeric_col_std

3、建立模型

數據集分成訓練/測試集

train_df=all_dummy_df.loc[train_df.index]
test_df=all_dummy_df.loc[test_df.index]

把pandas的DataFrame轉換成numpy的Array,只是為了和sklearn更配

x_train = train_df.values
x_test=test_df.values

剩下就是用sklearn的嶺回歸Ridge訓練模型了,這個模型需要一個alpha超參,我們用交叉驗證得到最優的參數值。

交叉驗證的代碼套路是固定的:

alphas = np.logspace(-3,2,50)
test_scores=[]
for alpha in alphas:
clf = Ridge(alpha)
test_scores=np.sqrt(cross_val_score(clf,X_train,y_train,cv=10,scoring='neg_mean_squared_error'))
test_scores.append(np.mean(test_score))

這段代碼運行完畢后,我們有兩個列表,一個是alphas列表,一個是test_scores列表。用這兩個列表畫一個折線圖,我們就可以觀察到在alpha取什么值的時候,誤差最小。

同樣的數據集,也可以用RandomForestRegressor來做回歸。這個模型有兩個超參數,最大特征個數、最大采樣數量。

max_features=[.1 ,.3 ,.5 ,.7 ,.9 ,.99]
test_scores=[]
for max_feat in max_features:
clf = RandomForestRegressor(n_estimators=200,max_features=max_feat)
#n_estimators 代表要多少棵樹
test_scores=np.sqrt(-cross_val_score(clf,X_train,y_train,cv=5,scoring='neg_mean_squared_error')
test_scores.append(np.mean(test_scores))

通過交叉驗證,我們可以找到兩個模型的最佳超參數。

4、模型融合

簡單的我們可以用bagging的方法,把兩個模型最好測參數拿出來,組合成最終的model。每個模型都做個預測值,最終兩個模型的預測值取平均。

5、提交結果

走你~

6、進階優化 用高級的模型融合

一般來說,單個分類器的效果有效,我們會傾向于把N多的分類器合在一起,做一個綜合分類器達到最好的效果。

sklearn中已經有現成框架,在sklearn.ensemble中,有bagging有Boosting。Bagging和Bossting又都有回歸和分類之分。把bagging用在回歸上,也是同時得到多個回歸模型,比如這個案例中我們用Ridge做回歸器,最后就是得到多個Ridge。

Bagging缺省的用的是DecisionTree,通過改變base_estimator參數的值就可以修改弱模型的類型了。

from sklearn.ensemble import BaggingRegressor

之前,我們通過交叉驗證的方法,得到了Ridge嶺回歸alpha參數的最佳值。
我們就可以用這個最佳參數作為小分類器。

from sklearn.linear_model import Ridge
ridge = Ridge(alpha=15)

而我們在接下來是用Bagging時,同樣是要用交叉驗證,訓練出來的其實是小分類器的個數的最佳值。

我們先定義小分類器的個數

params = [1,10,15,20,25,30,40]
....
找到最佳的小回歸器的數量。

大殺器,xgboost

可以用xgboost,而且xgboost可以用一樣的模式嵌入到sklearn中,代碼套路完全一樣

from xgboost import XGBRegressor
params = [1,2,3,4,5]
for param in params :
clf = XGBRegressor(max_depth=param)
test_score = np.sqrt(-cross_val_score(clf,x_train,y_train,cv=10,scoring=‘neg_mean_squared_error') )
test_scores.append(test_score)

完全一樣的代碼套路。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容