完整代碼: https://github.com/cindycindyhi/kaggle-Titanichtml
特徵工程系列:git
Titanic系列之原始數據分析和數據處理github
以前的三篇博文已經進行了一次還算完整的特徵工程,分析字符串類型的變量獲取新變量,對數值變量進行規範化,獲取派生屬性並進行維規約。如今咱們已經有了一個特徵集,能夠進行訓練模型了。機器學習
因爲這是一個分類問題,可使用L1 SVM 隨機森林等分類算法,隨機森林是一個很是簡單並且實用的分類模型,可調的變量不多。它的一個很是重要的變量是樹的個數,樹的個數增長到必定大小後會使耗時加大,可是精度不會增長不少。工具
通過以前的特徵工程,如今已經有237個特徵,數目過多的特徵會使模型過擬合,幸運的是,隨機森林在訓練以後能夠產生一個各個特徵重要性的數據集,咱們能夠利用這個數據集,肯定一個閾值,選出來對模型訓練幫助最大的一些屬性,這裏使用的隨機森林的參數都是默認值。學習
1 X = input_df.values[:, 1::] 2 y = input_df.values[:, 0] 3 survived_weight = .75 4 y_weights = np.array([survived_weight if s == 0 else 1 for s in y]) 5 6 print "Rough fitting a RandomForest to determine feature importance..." 7 forest = RandomForestClassifier(oob_score=True, n_estimators=10000) 8 forest.fit(X, y, sample_weight=y_weights) 9 feature_importance = forest.feature_importances_ 10 feature_importance = 100.0 * (feature_importance / feature_importance.max()) 11 12 fi_threshold = 18 13 important_idx = np.where(feature_importance > fi_threshold)[0] 14 important_features = features_list[important_idx] 15 print "\n", important_features.shape[0], "Important features(>", \ 16 fi_threshold, "% of max importance)...\n"#, \ 17 #important_features 18 sorted_idx = np.argsort(feature_importance[important_idx])[::-1] 19 #get the figure about important features 20 pos = np.arange(sorted_idx.shape[0]) + .5 21 plt.subplot(1, 2, 2) 22 plt.title('Feature Importance') 23 plt.barh(pos, feature_importance[important_idx][sorted_idx[::-1]], \ 24 color='r',align='center') 25 plt.yticks(pos, important_features[sorted_idx[::-1]]) 26 plt.xlabel('Relative Importance') 27 plt.draw() 28 plt.show()
代碼有點長,但主要分紅兩塊,一是模型訓練,二是根據訓練獲得的特徵重要性篩選重要特徵並畫圖。測試
獲得的特徵重要性大於18的屬性以下圖所示:優化
能夠看到Tiltle_Mr Title_id Gender這三個屬性至關重要。而與Title有關的屬性都是咱們對姓名進行分析獲得的,可見一些字符串屬性中可能會藏有很是重要的信息,在特種工程中要很是重視而不是將其拋棄。由於咱們的原始屬性很是少,因此產生的重要屬性大都是原始屬性的數學組合,派生變量可能並非必需的,這主要和模型有關,但大多數時候派生變量是沒有什麼壞處的。對於隨機森林這種訓練數據想對容易的模型來講,可能一些原始的屬性直接用來進行訓練也會產生很好的效果,可是做爲一道學習題,固然是什麼處理辦法都要嘗試一遍,積累經驗啦。
對於隨機森林如何獲得變臉重要性的,能夠看一下scikit learn 的官方文檔 scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html#example-ensemble-plot-forest-importances-py
固然在獲得重要的特徵後,咱們就要把不重要的特徵去掉了,以提升模型的訓練速度(閾值可調的小一點,以保留更多的特徵)
1 X = X[:, important_idx][:, sorted_idx] 2 submit_df = submit_df.iloc[:,important_idx].iloc[:,sorted_idx]
如今咱們就獲得了最終的數據集,終於能夠正式用來訓練模型了。
上面部分都是用的隨機森林的默認參數,可是模型的參數是可調的,咱們要調整參數以得到更好的訓練。scikit learn 提供了兩種參數優化的方法,也是其餘工具通用的方法,一是GridSearch,另外一個是RandomizedSearch。在這兩種狀況下,均可以指定每一個參數的取值範圍,建立一個字典。將參數字典提供給search方法,它就會執行模型所指定的值的組合。對於GridSearch,它測試參數每個可能的組合。 RandomizedSearch容許指定有多少不一樣的組合要測試,而後隨機選擇組合。若是正在使用模型關鍵參數不少,RandomizedSearch頗有用能夠幫助節省時間。
1 sqrtfeat = int(np.sqrt(X.shape[1])) 2 minsampsplit = int(X.shape[0]*0.015) 3 # (adapted from http://scikit-learn.org/stable/auto_examples/randomized_search.html) 4 def report(grid_scores, n_top=5): 5 params = None 6 top_scores = sorted(grid_scores, key=itemgetter(1), reverse=True)[:n_top] 7 for i, score in enumerate(top_scores): 8 print("Parameters with rank: {0}".format(i + 1)) 9 print("Mean validation score: {0:.4f} (std: {1:.4f})".format( 10 score.mean_validation_score, np.std(score.cv_validation_scores))) 11 print("Parameters: {0}".format(score.parameters)) 12 print("") 13 14 if params == None: 15 params = score.parameters 16 17 return params 18 # Simple grid test 19 grid_test1 = { "n_estimators" : [1000, 2500, 5000], 20 "criterion" : ["gini", "entropy"], 21 "max_features" : [sqrtfeat-1, sqrtfeat, sqrtfeat+1], 22 "max_depth" : [5, 10, 25], 23 "min_samples_split" : [2, 5, 10,minsampsplit ] } 24 25 forest = RandomForestClassifier(oob_score=True) 26 27 print "Hyperparameter optimization using GridSearchCV..." 28 grid_search = GridSearchCV(forest, grid_test1, n_jobs=-1, cv=10) 29 grid_search.fit(X, y) 30 best_params_from_grid_search = scorereport.report(grid_search.grid_scores_)
經訓練獲得的參數爲 params_score = { "n_estimators" : 10000, "max_features" : sqrtfeat, "min_samples_split" : minsampsplit },結果仍是很符合經驗結果預測的。
怎麼評價這個訓練後的模型呢? Learning Curves。《機器學習實戰》這本書裏有講,Andrew Ng的公開課裏也講過。主要是誤差方差折衷與測試偏差和訓練偏差的關係。咱們應該調整模型來達到測試偏差的最小值。sklearn.learning_curve模塊能夠完成這個功能。 Learning Curves曲線最後代表咱們的模型須要更多的數據訓練。
在訓練時要注意的是,由於倖存者相對未倖存的人數較少,因此數據是不均衡的,能夠經過上抽樣或下抽樣或者調整樣本的權重,來得到均衡的訓練樣本。
而後咱們就能夠用forest來預測測試集了,bingo!