zoukankan      html  css  js  c++  java
  • kaggle比赛流程(转)

    一、比赛概述

    • 不同比赛有不同的任务,分类、回归、推荐、排序等。比赛开始后训练集和测试集就会开放下载。
    • 比赛通常持续 2 ~ 3 个月,每个队伍每天可以提交的次数有限,通常为 5 次。
    • 比赛结束前一周是一个 Deadline,在这之后不能再组队,也不能再新加入比赛。所以想要参加比赛请务必在这一 Deadline 之前有过至少一次有效的提交
    • 一般情况下在提交后会立刻得到得分的反馈。不同比赛会采取不同的评分基准,可以在分数栏最上方看到使用的评分方法。
    • 反馈的分数是基于测试集的一部分计算的,剩下的另一部分会被用于计算最终的结果。所以最后排名会变动。
    • LB 指的就是在 Leaderboard 得到的分数,由上,有 Public LB 和 Private LB 之分。
    • 自己做的 Cross Validation 得到的分数一般称为 CV 或是 Local CV。一般来说 CV 的结果比 LB 要可靠

    二、可视化

      通常来说 matplotlib 和 seaborn 提供的绘图功能就可以满足需求了。

    比较常用的图表有:

    • 查看目标变量的分布。当分布不平衡时,根据评分标准和具体模型的使用不同,可能会严重影响性能。
    • 对 Numerical Variable,可以用 Box Plot 来直观地查看它的分布。
    • 对于坐标类数据,可以用 Scatter Plot 来查看它们的分布趋势和是否有离群点的存在。
    • 对于分类问题,将数据根据 Label 的不同着不同的颜色绘制出来,这对 Feature 的构造很有帮助。
    • 绘制变量之间两两的分布和相关度图表。

    三、数据处理

    大部分情况下,在构造 Feature 之前,我们需要对比赛提供的数据集进行一些处理。通常的步骤有:

    • 有时数据会分散在几个不同的文件中,需要 Join 起来。
    • 处理 Missing Data
    • 处理 Outlier
    • 必要时转换某些 Categorical Variable 的表示方式。
    • 有些 Float 变量可能是从未知的 Int 变量转换得到的,这个过程中发生精度损失会在数据中产生不必要的 Noise,即两个数值原本是相同的却在小数点后某一位开始有不同。这对 Model 可能会产生很负面的影响,需要设法去除或者减弱 Noise。

    这一部分的处理策略多半依赖于在前一步中探索数据集所得到的结论以及创建的可视化图表。在实践中,我建议使用 iPython Notebook 进行对数据的操作,并熟练掌握常用的 pandas 函数。

    四、特征工程

    总的来说,我们应该生成尽量多的 Feature,相信 Model 能够挑出最有用的 Feature。但有时先做一遍 Feature Selection 也能带来一些好处:

    • Feature 越少,训练越快。
    • 有些 Feature 之间可能存在线性关系,影响 Model 的性能。
    • 通过挑选出最重要的 Feature,可以将它们之间进行各种运算和操作的结果作为新的 Feature,可能带来意外的提高。

    Feature Selection 最实用的方法也就是看 Random Forest 训练完以后得到的 Feature Importance 了。其他有一些更复杂的算法在理论上更加 Robust,但是缺乏实用高效的实现,比如这个。从原理上来讲,增加 Random Forest 中树的数量可以在一定程度上加强其对于 Noisy Data 的 Robustness。

    看 Feature Importance 对于某些数据经过脱敏处理的比赛尤其重要。这可以免得你浪费大把时间在琢磨一个不重要的变量的意义上。

    这里用一个例子来说明在一些情况下 Raw Feature 可能需要经过一些转换才能起到比较好的效果。

    假设有一个 Categorical Variable 一共有几万个取值可能,那么创建 Dummy Variables 的方法就不可行了。这时一个比较好的方法是根据 Feature Importance 或是这些取值本身在数据中的出现频率,为最重要(比如说前 95% 的 Importance)那些取值(有很大可能只有几个或是十几个)创建 Dummy Variables,而所有其他取值都归到一个“其他”类里面。

    五、模型选择

    准备好 Feature 以后,就可以开始选用一些常见的模型进行训练了。Kaggle 上最常用的模型基本都是基于树的模型:

    • Gradient Boosting
    • Random Forest
    • Extra Randomized Trees

    以下模型往往在性能上稍逊一筹,但是很适合作为 Ensemble 的 Base Model。这一点之后再详细解释。(当然,在跟图像有关的比赛中神经网络的重要性还是不能小觑的。)

    • SVM
    • Linear Regression
    • Logistic Regression
    • Neural Networks

    以上这些模型基本都可以通过 sklearn 来使用。

    当然,这里不能不提一下 XgboostGradient Boosting 本身优秀的性能加上 Xgboost 高效的实现,使得它在 Kaggle 上广为使用。几乎每场比赛的获奖者都会用 Xgboost 作为最终 Model 的重要组成部分。在实战中,我们往往会以 Xgboost 为主来建立我们的模型并且验证 Feature 的有效性。顺带一提,在 Windows 上安装 Xgboost 很容易遇到问题,目前已知最简单、成功率最高的方案可以参考我在这篇帖子中的描述

    六、模型训练

    在训练时,我们主要希望通过调整参数来得到一个性能不错的模型。一个模型往往有很多参数,但其中比较重要的一般不会太多。比如对 sklearn 的 RandomForestClassifier 来说,比较重要的就是随机森林中树的数量 n_estimators 以及在训练每棵树时最多选择的特征数量max_features。所以我们需要对自己使用的模型有足够的了解,知道每个参数对性能的影响是怎样的

    通常我们会通过一个叫做 Grid Search 的过程来确定一组最佳的参数。其实这个过程说白了就是根据给定的参数候选对所有的组合进行暴力搜索。

    1
    2
    3
    param_grid = {'n_estimators': [300, 500], 'max_features': [10, 12, 14]}
    model = grid_search.GridSearchCV(estimator=rfr, param_grid=param_grid, n_jobs=1, cv=10, verbose=20, scoring=RMSE)
    model.fit(X_train, y_train)

    顺带一提,Random Forest 一般在 max_features 设为 Feature 数量的平方根附近得到最佳结果。

    这里要重点讲一下 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。

    一般的调参步骤是:

    1. 将训练数据的一部分划出来作为验证集。
    2. 先将 eta 设得比较高(比如 0.1),num_round 设为 300 ~ 500。
    3. 用 Grid Search 对其他参数进行搜索
    4. 逐步将 eta 降低,找到最佳值。
    5. 以验证集为 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。

    七、交叉验证

    Cross Validation 是非常重要的一个环节。它让你知道你的 Model 有没有 Overfit,是不是真的能够 Generalize 到测试集上。在很多比赛中 Public LB 都会因为这样那样的原因而不可靠。当你改进了 Feature 或是 Model 得到了一个更高的 CV 结果,提交之后得到的 LB 结果却变差了,一般认为这时应该相信 CV 的结果。当然,最理想的情况是多种不同的 CV 方法得到的结果和 LB 同时提高,但这样的比赛并不是太多。

    在数据的分布比较随机均衡的情况下,5-Fold CV 一般就足够了。如果不放心,可以提到 10-Fold但是 Fold 越多训练也就会越慢,需要根据实际情况进行取舍。

    很多时候简单的 CV 得到的分数会不大靠谱,Kaggle 上也有很多关于如何做 CV 的讨论。比如这个。但总的来说,靠谱的 CV 方法是 Case By Case 的,需要在实际比赛中进行尝试和学习,这里就不再(也不能)叙述了。

    八、Ensemble Generation

    Ensemble Learning 是指将多个不同的 Base Model 组合成一个 Ensemble Model 的方法。它可以同时降低最终模型的 Bias 和 Variance(证明可以参考这篇论文,我最近在研究类似的理论,可能之后会写新文章详述),从而在提高分数的同时又降低 Overfitting 的风险。在现在的 Kaggle 比赛中要不用 Ensemble 就拿到奖金几乎是不可能的。

    常见的 Ensemble 方法有这么几种:

    • Bagging:使用训练数据的不同随机子集来训练每个 Base Model,最后进行每个 Base Model 权重相同的 Vote。也即 Random Forest 的原理。
    • Boosting:迭代地训练 Base Model,每次根据上一个迭代中预测错误的情况修改训练样本的权重。也即 Gradient Boosting 的原理。比 Bagging 效果好,但更容易 Overfit。
    • Blending:用不相交的数据训练不同的 Base Model,将它们的输出取(加权)平均。实现简单,但对训练数据利用少了。
    • Stacking:接下来会详细介绍。

    从理论上讲,Ensemble 要成功,有两个要素:

    • Base Model 之间的相关性要尽可能的小。这就是为什么非 Tree-based Model 往往表现不是最好但还是要将它们包括在 Ensemble 里面的原因。Ensemble 的 Diversity 越大,最终 Model 的 Bias 就越低。
    • Base Model 之间的性能表现不能差距太大。这其实是一个 Trade-off,在实际中很有可能表现相近的 Model 只有寥寥几个而且它们之间相关性还不低。但是实践告诉我们即使在这种情况下 Ensemble 还是能大幅提高成绩。

    九、Stacking

    相比 Blending,Stacking 能更好地利用训练数据。以 5-Fold Stacking 为例,它的基本原理如图所示:

    Stacking

    整个过程很像 Cross Validation。首先将训练数据分为 5 份,接下来一共 5 个迭代,每次迭代时,将 4 份数据作为 Training Set 对每个 Base Model 进行训练,然后在剩下一份 Hold-out Set 上进行预测。同时也要将其在测试数据上的预测保存下来。这样,每个 Base Model 在每次迭代时会对训练数据的其中 1 份做出预测,对测试数据的全部做出预测。5 个迭代都完成以后我们就获得了一个 #训练数据行数 x #Base Model 数量 的矩阵,这个矩阵接下来就作为第二层的 Model 的训练数据。当第二层的 Model 训练完以后,将之前保存的 Base Model 对测试数据的预测(因为每个 Base Model 被训练了 5 次,对测试数据的全体做了 5 次预测,所以对这 5 次求一个平均值,从而得到一个形状与第二层训练数据相同的矩阵)拿出来让它进行预测,就得到最后的输出。

    这里给出我的实现代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class Ensemble(object):
    def __init__(self, n_folds, stacker, base_models):
    self.n_folds = n_folds
    self.stacker = stacker
    self.base_models = base_models

    def fit_predict(self, X, y, T):
    X = np.array(X)
    y = np.array(y)
    T = np.array(T)

    folds = list(KFold(len(y), n_folds=self.n_folds, shuffle=True, random_state=2016))

    S_train = np.zeros((X.shape[0], len(self.base_models)))
    S_test = np.zeros((T.shape[0], len(self.base_models)))

    for i, clf in enumerate(self.base_models):
    S_test_i = np.zeros((T.shape[0], len(folds)))

    for j, (train_idx, test_idx) in enumerate(folds):
    X_train = X[train_idx]
    y_train = y[train_idx]
    X_holdout = X[test_idx]
    # y_holdout = y[test_idx]
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_holdout)[:]
    S_train[test_idx, i] = y_pred
    S_test_i[:, j] = clf.predict(T)[:]

    S_test[:, i] = S_test_i.mean(1)

    self.stacker.fit(S_train, y)
    y_pred = self.stacker.predict(S_test)[:]
    return y_pred

    获奖选手往往会使用比这复杂得多的 Ensemble,会出现三层、四层甚至五层,不同的层数之间有各种交互,还有将经过不同的 Preprocessing 和不同的 Feature Engineering 的数据用 Ensemble 组合起来的做法。但对于新手来说,稳稳当当地实现一个正确的 5-Fold Stacking 已经足够了。

    十、Pipeline

    可以看出 Kaggle 比赛的 Workflow 还是比较复杂的。尤其是 Model Selection 和 Ensemble。理想情况下,我们需要搭建一个高自动化的 Pipeline,它可以做到:

    • 模块化 Feature Transform,只需写很少的代码就能将新的 Feature 更新到训练集中。
    • 自动化 Grid Search,只要预先设定好使用的 Model 和参数的候选,就能自动搜索并记录最佳的 Model。
    • 自动化 Ensemble Generation,每个一段时间将现有最好的 K 个 Model 拿来做 Ensemble。

    对新手来说,第一点可能意义还不是太大,因为 Feature 的数量总是人脑管理的过来的;第三点问题也不大,因为往往就是在最后做几次 Ensemble。但是第二点还是很有意义的,手工记录每个 Model 的表现不仅浪费时间而且容易产生混乱。

    原文:http://www.cnblogs.com/zhizhan/p/5826089.html

  • 相关阅读:
    Java如何重置正则表达式的模式?
    Java如何创建用户自定义异常?
    Java如何使用线程异常?
    Java如何打印异常的堆栈?
    Java数组超出范围时如何处理多个异常?
    Java如何处理已检查异常?
    Java如何使用重载方法处理异常?
    Java如何使用catch来处理异常?
    Java如何处理空堆栈异常?
    Java如何处理运行时异常?
  • 原文地址:https://www.cnblogs.com/gczr/p/6943914.html
Copyright © 2011-2022 走看看