经验
作者:Alex Hsu
链接:https://www.zhihu.com/question/24533374/answer/34649594
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
kaggle winner = feature engineering + ensemble + good machine + domain knowledge。
同意@Naiyan Wang的观点,大部分kaggle比赛和machine learning关系不大。大部分比赛还是很brute force的方法,个人看法能拿到10%并不是很困难,都是一些常见的featuer处理方法(Hash, BOW, TFIDF, Categorization, Normalization),加几个常见模型(RF, GBDT, LR),cross-validation调参数,最后ensemble一下。最好有很好的机器(主要是ram,以及tree-based model并行),这样就不用太担心online training的问题,大部分的lib也能用了。
不过如果想拿top10还是有一定难度,大部分冠军得主其实都有相关领域从业经验,有一些domain knowledge,对问题的思考也会更本质一点。
总体而言,我觉得参加kaggle还是很不错的体验,有一些帮助,特别是比赛结束后大家解法的分享和探讨可以学到一些东西(贴一个地址Kaggle Competition Past Solutions。)但honestly,我觉得kaggle更适合机器学习入门者,对这个领域有兴趣的同学们来产生兴趣,锻炼实际能力,感受一下实际的数据集(虽然仍然有些不一样),对从业者或者researcher们而言帮助不是很大。
天池历届答辩PPT和视频
特征工程视频详解
kaggle比赛各种源码
http://suanfazu.com/t/kaggle/230
http://blog.csdn.net/han_xiaoyang/article/details/52665396
进入5%
https://dnc1994.com/2016/04/rank-10-percent-in-first-kaggle-competition/
有人总结 Kaggle 比赛是 “Feature 为主,调参和 Ensemble 为辅”,
Feature Selection 最实用的方法也就是看 Random Forest 训练完以后得到的 Feature Importance 了。
看 Feature Importance 对于某些数据经过脱敏处理的比赛尤其重要。这可以免得你浪费大把时间在琢磨一个不重要的变量的意义上。
这里要重点讲一下 Xgboost 的调参。通常认为对它性能影响较大的参数有:
eta:每次迭代完成后更新权重时的步长。越小训练越慢。
num_round:总共迭代的次数。
subsample:训练每棵树时用来训练的数据占全部的比例。用于防止 Overfitting。
colsample_bytree:训练每棵树时用来训练的特征的比例,类似 RandomForestClassifier 的 max_features。
max_depth:每棵树的最大深度限制。与 Random Forest 不同,Gradient Boosting 如果不对深度加以限制,最终是会 Overfit 的。
early_stopping_rounds:用于控制在 Out Of Sample 的验证集上连续多少个迭代的分数都没有提高后就提前终止训练。用于防止 Overfitting。
一般的调参步骤是:
将训练数据的一部分划出来作为验证集。
先将 eta 设得比较高(比如 0.1),num_round 设为 300 ~ 500。
用 Grid Search 对其他参数进行搜索
逐步将 eta 降低,找到最佳值。
以验证集为 watchlist,用找到的最佳参数组合重新在训练集上训练。注意观察算法的输出,看每次迭代后在验证集上分数的变化情况,从而得到最佳的 early_stopping_rounds。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
X_dtrain, X_deval, y_dtrain, y_deval = cross_validation.train_test_split(X_train, y_train, random_state=1026, test_size=0.3)
dtrain = xgb.DMatrix(X_dtrain, y_dtrain)
deval = xgb.DMatrix(X_deval, y_deval)
watchlist = [(deval, 'eval')]
params = {
'booster': 'gbtree',
'objective': 'reg:linear',
'subsample': 0.8,
'colsample_bytree': 0.85,
'eta': 0.05,
'max_depth': 7,
'seed': 2016,
'silent': 0,
'eval_metric': 'rmse'
}
clf = xgb.train(params, dtrain, 500, watchlist, early_stopping_rounds=50)
pred = clf.predict(xgb.DMatrix(df_test))
最后要提一点,所有具有随机性的 Model 一般都会有一个 seed 或是 random_state 参数用于控制随机种子。得到一个好的 Model 后,在记录参数时务必也记录下这个值,从而能够在之后重现 Model。
在数据的分布比较随机均衡的情况下,5-Fold CV 一般就足够了。
由于被很多前辈教导过要相信自己的 CV,我的决定是将 5-Fold 提到 10-Fold,然后以 CV 为标准继续前进。
Kaggle 首战拿银总结 | 指导 (长文、干货)(分享自知乎网)https://zhuanlan.zhihu.com/p/26645088?iam=cb63279559dabb602297bfcbd1f38a50&utm_source=com.miui.notes&utm_medium=social
机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾 - 寒小阳 - CSDN博客 -
http://blog.csdn.net/han_xiaoyang/article/details/49797143?utm_source=com.jianshu.haruki&utm_medium=social
印象中Andrew Ng老师似乎在coursera上说过,应用机器学习,千万不要一上来就试图做到完美,先撸一个baseline的model出来,再进行后续的分析步骤,一步步提高,所谓后续步骤可能包括『分析model现在的状态(欠/过拟合),分析我们使用的feature的作用大小,进行feature selection,以及我们模型下的bad case和产生的原因』等等。
Kaggle上的大神们,也分享过一些experience,说几条我记得的哈:
『对数据的认识太重要了!』
『数据中的特殊点/离群点的分析和处理太重要了!』
『特征工程(feature engineering)太重要了!在很多Kaggle的场景下,甚至比model本身还要重要』
『要做模型融合(model ensemble)啊啊啊!
获得基本信息
data_train.info()
.describe()
泰坦尼克号的也有缺失值
如果缺值的样本占总数比例极高,我们可能就直接舍弃了,作为特征加入的话,可能反倒带入noise,影响最后的结果了
如果缺值的样本适中,而该属性非连续值特征属性(比如说类目属性),那就把NaN作为一个新类别,加到类别特征中
如果缺值的样本适中,而该属性为连续值特征属性,有时候我们会考虑给定一个step(比如这里的age,我们可以考虑每隔2/3岁为一个步长),然后把它离散化,之后把NaN作为一个type加到属性类目中。
有些情况下,缺失的值个数并不是特别多,那我们也可以试着根据已有的值,拟合一下数据,补充上。
我们通常会先对类目型的特征因子化,我们使用pandas的”get_dummies”来完成这个工作,并拼接在原来的”data_train”之上,
将对收敛速度造成几万点伤害值!甚至不收敛! (╬▔皿▔)…所以我们先用scikit-learn里面的preprocessing模块对这俩货做一个scaling,所谓scaling,其实就是将一些变化幅度较大的特征化到[-1,1]之内。
看过Andrew Ng老师的machine Learning课程的同学们,知道,我们应该分析分析模型现在的状态了,是过/欠拟合?,以确定我们需要更多的特征还是更多数据,或者其他操作。我们有一条很著名的learning curves对吧。
不过在现在的场景下,先不着急做这个事情,我们这个baseline系统还有些粗糙,先再挖掘挖掘。
重点又来了:
『要做交叉验证(cross validation)!』
『要做交叉验证(cross validation)!』
『要做交叉验证(cross validation)!』
强迫症患者』打算继续喊喊口号…
『模型融合(model ensemble)很重要!』
『模型融合(model ensemble)很重要!』
『模型融合(model ensemble)很重要!』
在这里我介绍一下plot方法的函数的使用。
Series.plot方法的函数:
参数说明
label用于图例的标签
ax要在其上进行绘制的matplotlib subplot对象。如果没有设置,则使用当前matplotlib subplot
style将要传给matplotlib的风格字符串(for example: ‘ko–’)
alpha图表的填充不透明(0-1)
kind可以是’line’, ‘bar’, ‘barh’, ‘kde’
logy在Y轴上使用对数标尺
use_index将对象的索引用作刻度标签
rot旋转刻度标签(0-360)
xticks用作X轴刻度的值
yticks用作Y轴刻度的值
xlimX轴的界限
ylimY轴的界限
grid显示轴网格线
在这里强调一下 kind参数——'line', 'bar', 'barh', 'kde':
直方图:是一种可以对值频率离散化显示的柱状图。通过调用Series.hist()方法即可创建。
密度图:与直方图相关的一种类型图,是通过计算“可能会产生观测数据的连续概率分布的估计”而产生的,通过给plot传入参数kind = 'kde' 即可。
散布图:是观测两个一维数据序列之间关系的有效手段,使用pd.scatter_matrix()即可建立。
部分代码:
[python] view plain copy
import matplotlib.pyplot as plt
fig = plt.figure()
fig.set(alpha=0.2) # 设定图表颜色alpha参数
plt.subplot2grid((2,3),(0,0)) # 在一张大图里分列几个小图,位置是(0,0)
data_train.Survived.value_counts().plot(kind='bar')# plots a bar graph of those who surived vs those who did not.
plt.title(u"获救情况 (1为获救)") # puts a title on our graph
plt.ylabel(u"人数")
plt.subplot2grid((2,3),(0,1)) # 在一张大图(2 * 3)中的位置是(0,1)
data_train.Pclass.value_counts().plot(kind="bar")
plt.ylabel(u"人数")
plt.title(u"乘客等级分布")
plt.subplot2grid((2,3),(0,2)) # 在一张大图(2 * 3)中的位置是(0, 2)
plt.scatter(data_train.Survived, data_train.Age)# 找出存活人数和年龄的散点图
plt.ylabel(u"年龄") # sets the y axis lable
plt.grid(b=True, which='major', axis='y') # formats the grid line style of our graphs
plt.title(u"按年龄看获救分布 (1为获救)")
plt.subplot2grid((2,3),(1,0), colspan=2) # colspan = 2 表示横向跨度是 2
# plots a kernel desity estimate(核密度估计) of the subset of the 1st class passanges's age
data_train.Age[data_train.Pclass ==1].plot(kind='kde')
data_train.Age[data_train.Pclass ==2].plot(kind='kde')
data_train.Age[data_train.Pclass ==3].plot(kind='kde')
plt.xlabel(u"年龄")# plots an axis lable
plt.ylabel(u"密度")
plt.title(u"各等级的乘客年龄分布")
plt.legend((u'头等舱', u'2等舱',u'3等舱'),loc='best') # sets our legend for our graph. 显示图示
plt.subplot2grid((2,3),(1,2))
data_train.Embarked.value_counts().plot(kind='bar')
plt.title(u"各登船口岸上船人数")
plt.ylabel(u"人数")
plt.show()
https://www.kaggle.com/sudalairajkumar/simple-exploration-notebook-zillow-prize/notebook