kaggel入門比賽_HousePrices

@update 2016.11.28,自己嘗試了一些缺失值填補的方法,調sklearn寫了一些特徵變換和特徵選擇的算法

下一步:繼續特徵規約,開始模型調參

kaggle入門系列比賽HousePrices,該比賽是一個經典的迴歸問題,預測房價,這個比賽我用來熟悉kaggle,熟悉基本的數據挖掘流程,主要是特徵工程,包括常見的缺失值填補,categorial特徵的處理,其實主要就是熟悉用python的pandas包對數據進行預處理。

第一次嘗試的過程我主要是參考了Regularized Linear Models這篇kernel,它對數據的處理就是一些最基本的做法,作爲入門、熟悉基本流程是很好的一篇kernel。

一.處理數據,準備建模

1.數據變換

特徵中的屬性分爲兩種,定性的和定量的。對定量的屬性我們可以有很多種距離度量方式。而對定性的屬性我們一般用標籤來表示之,這對於常見的機器學習算法而言是不好處理的,常見的做法是轉化爲數值屬性,但是如何轉化?如何單純的轉化爲數字的話會影響一些以距離度量爲依據的算法的準確性。一般我們使用pandas的get_dummies()將其每個屬性值轉化爲一個二元屬性維度,值對應爲0/1,但這也存在一個問題,就是當原始定性屬性的屬性值過多時。
all_data = pd.get_dummies(all_data) #直接對整個DataFrame中所有類別屬性做dummies
對於定量屬性,一個可能需要的操作就是規範化。但規範化不是必須的,當所使用的算法不是依據距離屬性作爲度量時,不需要做歸一化。
在上述提到的Regularized Linear Models的做法中,值得一提的是通過對數據的繪圖(也可以通過scipy包的)發現預測屬性是偏態分佈的。這種偏態分佈(數據不均衡)會影響算法準確性,作者通過對偏態數據做log變換改善數據傾斜度。
skewed_feats = train[numeric_feats].apply(lambda x: skew(x.dropna())) #compute skewness<pre name="code" class="python">all_data[skewed_feats] = np.log1p(all_data[skewed_feats])

@2016.11.28:對categorical的處理也就是get_dummies了,目前沒有用到別的優化。

值得一提的是,雖然log變換使數據趨於正態分佈,這種優化是針對於線性迴歸的(因爲線性迴歸後續的一些檢驗是基於正態分佈假設的),但是我在實踐中發現對tree-based的模型,也是通過log變換會使得分提高,why?

2.缺失值填補

常見的缺失值填補方法,見這篇數據挖掘之缺失值填補常見手段

我們首先嚐試一個最基本的填補方法,即均值填補

all_data = all_data.fillna(all_data.mean())

@2016.11.28:缺失值處理的幾種常見方法:

1.刪除帶缺失值的數據:適用於數據量足夠大的時候;
2.均值/衆數填補:簡單常用;
3.建立模型,如線性迴歸,隨機森林:利用的是屬性之間的相關性,如果屬性之間相關性過高,則該屬性沒有意義,而若相關性過低,無法準確預測該缺失值。一般情況下介於兩者之間
4.當作特殊情況,取特殊值填入:適用於缺失值很多,或缺失值本身有一定意義的情況。
對HousePrices的處理,我使用了上述2、3、4三種,對如Alley這樣的用的是4,對一些與輸出相關性高的features使用3,剩下的使用2。在這樣的處理下最後得分有提升。雖然理論解釋有待考證。

3.維度規約

特徵維度過高可能會引起維數災難,原因在於:1,這些特徵之間可能存在多重共線性,從而導致空間的不穩定;2,高維空間本身具有稀疏性,一維正態分佈有68%的值落於正負標準差之間,而在十維空間上只有0.02%;三是由於過多的屬性 會使挖掘需要很長時間。當前這些現象對不同的算法而言也是不同的,比如對L1(Lasso)而言,大量屬性時效果很好,因爲它可以有效忽略掉噪聲變量,而對一些模型而言過多的屬性則容易過擬合。

@2016.11.28:做到這一步我就迷幻了,因爲我試了好幾種維度變換的方法,都是提交的得分效果變差... 一度導致我不想做下去,可能自己對這方面的理論缺失,經驗又太少,做起來有點迷茫吧,anyway,還是要繼續,於是今晚看了一些kernel,發現幾乎沒有對features做類似PCA這樣的維度變換的,不造爲什麼。

關於特徵選擇倒是有人做,我試了一下添加了兩個合成特徵,提交結果還是有提升噠,更神奇的是有一個合成的features[1stFlr_2ndFlr_Sf = ['1stFlrSF'] + ['2ndFlrSF']]。它居然在訓練好的lasso模型上係數是最高的,所以說領域知識,或者說特徵工程真的很重要的。

下一步可以試一下特徵選擇,比如說利用random forest的特徵重要度,kernel上大部分都是用lassocv自動完成特徵選擇,but anyway還是xgboost性能好些吧。


@update2016.11.29:試了一下模型選擇,sklearn.feature_selection中的RFECV和SelectFromModel,前者是利用模型的準確度(具體可以選擇sklearn提供的scoring標準)來遞歸的減少特徵直到選出最優特徵子集,後者則是根據模型中的estimator.feature_importances_屬性(所以輸入的模型必須有這個屬性)來選擇特徵子集。我大概試了下兩者的性能都不好,其中我又SelectFromModel結合RandomForest試了下,簡直可怕,看代碼和輸出:

from sklearn.model_selection import cross_val_score
import numpy as np
def rmse_cv(model,X_train,y):
    rmse= np.sqrt(-cross_val_score(model, X_train, y, scoring="neg_mean_squared_error", cv=3,n_jobs=-1))
    return(rmse)
from sklearn.feature_selection import SelectFromModel
# u can see from 'SelectFromModel' that this method use model result to select features, 'Wrapper'
# estimator: a supervised model with fit() method
def fea_sel_tree(train_x,train_y,estimator):
    estimator = estimator.fit(train_x,train_x)
    print 'feature importances in this model',
    print sorted(estimator.feature_importances_,reverse=True)
    model = SelectFromModel(estimator,prefit = True)
    after_sel = model.transform(train_x)
    return pd.DataFrame(after_sel)
import xgboost as xgb
from sklearn.ensemble import RandomForestRegressor
esti = RandomForestRegressor(n_estimators=360, max_depth=2,n_jobs=-1,random_state=0)
train_after = fea_sel_tree(alldata_newfea.iloc[:1460],y,esti)
model_xgb = xgb.XGBRegressor(n_estimators=360, max_depth=2, learning_rate=0.1)
print rmse_cv(model_xgb,train_after.iloc[:1460],y)
輸出:(可怕
feature importances in this model [0.98394303690584572, 0.0095377084732799645, 0.0065192546208747695, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
rmse: [ 0.28251422  0.300882    0.28558193]  #注:正常的rmse至少是0.13左右的吧

直接加了個特徵選擇降這麼多,可怕,但是其實從feature importance可以看出來,290多個features直接只剩3個了,各種不靠譜。

於是我在想,可能model的參數不太靠譜,於是我想先不加特徵規約了,先model調參吧。

# 上述完整代碼參見:點擊打開鏈接

二.Modeling

#具體的建模過程

@2016.11.28:model部分基本上一直堅信xgboost - -,但是沒有調參,下一步可以進行,不過感覺調參真是一條艱難的道路- -

然後下一步可能可以試一下集成模型,這也是個調參的坑啊。。。我還沒想好要不要從HousePrices的坑裏爬出來,找一個數據量稍微大點的坑撲進去- -

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章