機器學習kaggle比賽—泰坦尼克號獲救預測 二

機器學習kaggle比賽—泰坦尼克號獲救預測 二

介紹

上篇文章建立了Base model,準確率76.555%,今天要做的是提升預測準確率,主要是兩個方面:

1. 交叉驗證:在給定的訓練集中,拿出大部分樣本進行建模,留小部分樣本用剛建立的模型進行預測,並求這小部分樣本的預測誤差,記錄它們的平方加和。

2. 模型融合:通過對多個單模型融合以提升整體性能

交叉驗證

通常做交叉驗證,我們把訓練集的數據分成兩部分,一部分用於訓練我們需要的模型,另外一部分數據上看我們預測算法的效果。用scikit-learn的cross_validation來完成這個工作。

我們這次還要把驗證失敗的item都拿出來,分析一下為什麼預測錯了,然後再改進。代碼如下:

split_train, split_cv = cross_validation.train_test_split(df, test_size=0.3, random_state=0)

train_df = split_train.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')

clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)

clf.fit(train_df.as_matrix()[:,1:], train_df.as_matrix()[:,0])

cv_df = split_cv.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')

predictions = clf.predict(cv_df.as_matrix()[:,1:])

origin_data_train = pd.read_csv("Train.csv")

bad_cases = origin_data_train.loc[origin_data_train['PassengerId'].isin(split_cv[predictions != cv_df.as_matrix()[:,0]]['PassengerId'].values)]

bad_cases

機器學習kaggle比賽—泰坦尼克號獲救預測 二

得到這樣的錯誤數據,更深一些的分析特徵:

  1. 可以添加字段來表示是否是小孩,條件是age<10

  2. Parch表示父母和小孩個數,如果名字中有Mrs,並且Parch>1,可以判斷是一名母親

  3. Embarked登船口這個屬性好像作用不大,先去掉

  4. 對年齡按步長做離散化處理,形成單獨的特徵

過擬合 欠擬合

有一種情況是在做機器學習經常發生的,就是在用訓練集數據去做預測的時候,準確率很高,一切看起來都很美好,但是當用測試集數據去做預測的時候,發現效果不好,這種情況就是過擬合。

過擬合更通俗一點講就是,比如小智考駕照天天練倒車,練的非常好,教練的口訣記得很清楚“向左方向打一圈,走兩秒,打死,走3秒,回正,走到底,完成”,但是拿到駕照後在自己家的車庫裡倒車的時候,刮的,擦的掉漆。因為實際車庫沒有那麼標準,旁邊的車停的位置有時候也不正,靠牆的車位和中間的車位倒法都不一樣,最重要的是,缺少一位老司機在旁邊。

欠擬合就像是這樣,小智太懶考駕照的時候沒有怎麼練習,教練說“開車一定多練才能開好,開好了才能拿到駕照”,小智一聽急了,從包裡掏出了兩萬塊錢,說“這樣能拿到駕照嗎”,教練說“再加兩萬,就可以”,小智毫不猶豫從包裡再拿出兩萬甩在了副駕駛座上。等小智拿到駕照後,回到自己家車庫去倒車,結果更悲劇,因為根本就沒怎麼練。

而在機器學習的問題上,對於過擬合和欠擬合兩種情形。我們優化的方式是不同的:

對過擬合而言,通常以下策略對結果優化是有用的:

  • 做一下feature selection,挑出較好的feature的subset來做training

  • 提供更多的數據,從而彌補原始數據的bias問題,學習到的model也會更準確

而對於欠擬合而言,我們通常需要更多的feature,更復雜的模型來提高準確度。

模型融合

模型融合可以比較好地緩解,訓練過程中產生的過擬合問題,從而對於結果的準確度提升有一定的幫助。比如分類問題,當我們手頭上有一堆在同一份數據集上訓練得到的分類器(比如logistic regression,SVM,KNN,random forest,神經網絡),那我們讓他們都分別去做判定,然後對結果做投票統計,取票數最多的結果為最後結果。

我們來做一個bagging,就是說不要用全部的訓練集,每次取訓練集的一個子集,做訓練,這樣,我們雖然用的是同一個機器學習算法,但是得到的模型卻是不一樣的;同時,因為我們沒有任何一份子數據集是全的,因此即使出現過擬合,也是在子訓練集上出現過擬合,而不是全體數據上,這樣做一個融合。

使用sk-learn中的bagging方法,代碼如下:

train_df = df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass.*|Mother|Child|Family|Title')

train_np = train_df.as_matrix()

y = train_np[:, 0]

X = train_np[:, 1:]

clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)

bagging_clf = BaggingRegressor(clf, n_estimators=20, max_samples=0.8, max_features=1.0, bootstrap=True, bootstrap_features=False, n_jobs=-1)

bagging_clf.fit(X, y)

test = df_test.filter(regex='Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass.*|Mother|Child|Family|Title')

predictions = bagging_clf.predict(test)

result = pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(), 'Survived':predictions.astype(np.int32)})

result.to_csv("logistic_regression_bagging_predictions.csv", index=False)

上傳kaggle驗證後,得出結果是從7000多名上升到1206名,準確率80.382%

機器學習kaggle比賽—泰坦尼克號獲救預測 二

總結

介紹了交叉驗證,過擬合,欠擬合,模型融合的概念,優化了base model,提升了準確率。

同學們可以從sk-learn這個框架開始學習機器學習,很全面,使用起來方便,還有一個非常簡單易懂的使用指南,地址:http://scikit-learn.org/stable/user_guide.html

建議還是穩紮穩打,不建議剛開始就學深度學習,去用Tensorflow;在微積分線性代數,標量向量張量都弄不清楚的情況下,即使按照教程做出來一些小demo,作用也不大,而且還有可能會養成知其然,不知其所以然的壞習慣,會有種假象是我會用就行了,不需要知道原理;千萬不要有這種想法,非常坑人,尤其是程序員,如果只停留在會用的層面上,不去看源碼,不去探求底層原理的話,則水平會很有限。


分享到:


相關文章: