具有多个参数的分类器的最优参数估计

时间:2016-10-06 15:20:06

标签: machine-learning scikit-learn mathematical-optimization roc

Single Threshold Multiple Threshold

左边的图像显示了通过扫描单个阈值并记录相应的真阳性率(TPR)和假阳性率(FPR)形成的标准ROC曲线。

右边的图像显示我的问题设置,其中有3个参数,对于每个参数,我们只有2个选项。如图所示,它共同产生8个点。在实践中,我打算有数百种可能的100个参数组合,但这个概念在这个缩小的情况下保持不变。

我打算在这里找到两件事:

  • 确定给定数据的最佳参数
  • 为所有参数组合提供整体效果得分

如果是左边的ROC曲线,可以使用以下方法轻松完成:

  • 最佳参数:TPR和FPR与成本要素的最大差异(我相信它被称为J统计量?)
  • 整体表现:曲线下面积(图中的阴影部分)

但是,对于我右边图像中的情况,我不知道我选择的方法是否是通常使用的标准原则方法。

  • 最佳参数集:TPR和FPR的最大差异

      

    参数分数= TPR - FPR * cost_ratio

  • 整体表现:所有"参数得分的平均值"

我已经找到了很多具有单一阈值的ROC曲线的参考材料,虽然还有其他技术可用于确定性能,但本问题中提到的那些绝对被认为是标准方法。我没有找到右边所示情景的阅读材料。

Bottomline,这里的问题有两个:(1)提供方法来评估我的问题场景中的最佳参数集和整体性能,(2)提供声明建议的方法作为给定的标准方法的参考场景。

P.S。:我首先在" Cross Validated"上发布了这个问题。论坛,但没有得到任何回复,事实上,在15个小时内只获得了7次观看。

2 个答案:

答案 0 :(得分:3)

我将在aberger关于网格搜索的上一个答案中稍微扩展一下。与模型的任何调整一样,最好使用一部分数据优化超参数,并使用另一部分数据评估这些参数,因此GridSearchCV最适合此目的。

首先,我将创建一些数据并将其拆分为训练和测试

import numpy as np
from sklearn import model_selection, ensemble, metrics

np.random.seed(42)

X = np.random.random((5000, 10))
y = np.random.randint(0, 2, 5000)

X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.3)

这给了我们一个分类问题,这就是我认为你所描述的问题,尽管同样适用于回归问题。

现在考虑一下您可能想要优化的参数是有帮助的。交叉验证的网格搜索是一个计算成本高昂的过程,因此搜索空间越小,完成的越快。我将展示一个RandomForestClassifier的示例,因为这是我的模型。

clf = ensemble.RandomForestClassifier()    
parameters = {'n_estimators': [10, 20, 30],
              'max_features': [5, 8, 10],
              'max_depth': [None, 10, 20]}

所以现在我有了我的基本估算器和我想要优化的参数列表。现在我只需要考虑如何评估我要构建的每个模型。从您的问题看来,您对ROC AUC感兴趣,所以这就是我将用于此示例的内容。虽然您可以在scikit中选择许多默认指标,甚至可以定义自己的默认指标。

gs = model_selection.GridSearchCV(clf, param_grid=parameters,
                                  scoring='roc_auc', cv=5)
gs.fit(X_train, y_train)

这将适合我给出的所有可能参数组合的模型,使用5倍交叉验证评估使用ROC AUC执行这些参数的程度。一旦适合,我们就可以查看最佳参数并获得性能最佳的模型。

print gs.best_params_
clf = gs.best_estimator_

输出:

{'max_features': 5, 'n_estimators': 30, 'max_depth': 20}

现在,您可能希望在所有训练数据上重新训练分类器,因为目前已经使用交叉验证进行了训练。有些人不愿意,但我是一个退休人员!

clf.fit(X_train, y_train)

现在我们可以评估模型在训练和测试集上的表现。

print metrics.classification_report(y_train, clf.predict(X_train))
print metrics.classification_report(y_test, clf.predict(X_test))

输出:

             precision    recall  f1-score   support

          0       1.00      1.00      1.00      1707
          1       1.00      1.00      1.00      1793

avg / total       1.00      1.00      1.00      3500

             precision    recall  f1-score   support

          0       0.51      0.46      0.48       780
          1       0.47      0.52      0.50       720

avg / total       0.49      0.49      0.49      1500

我们可以看到这个模型已经因测试集上的不良分数而过度训练。但这并不奇怪,因为数据只是随机噪音!希望在使用信号对数据执行这些方法时,最终会得到一个调整良好的模型。

修改

这是“每个人都这样做”的情况之一,但没有真正明确的参考,说这是最好的方法。我建议寻找一个接近您正在处理的分类问题的示例。例如,使用Google Scholar搜索“网格搜索”“SVM”“基因表达”

答案 1 :(得分:0)

我喜欢我们在scikit-learn中谈论Grid Search。它(1)提供了评估最佳(超)参数的方法,(2),是在一个大众化和充分参考的统计软件包中实现的。