kaggle数据挖掘竞赛初步--Titanic<随机森林&特征重要性>

完整代码: https://github.com/cindycindyhi/kaggle-Titanichtml

特征工程系列:git

Titanic系列之原始数据分析和数据处理github

Titanic系列之数据变换算法

Titanic系列之派生属性&维归约dom

以前的三篇博文已经进行了一次还算完整的特征工程,分析字符串类型的变量获取新变量,对数值变量进行规范化,获取派生属性并进行维规约。如今咱们已经有了一个特征集,能够进行训练模型了。机器学习

因为这是一个分类问题,可使用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!

相关文章
相关标签/搜索