将sklearn GridSearchCV与CalibratedClassifierCV一起使用是否有意义?

时间:2020-02-17 14:18:11

标签: python scikit-learn

我要做的是派生一个分类器,该分类器的参数相对于给定指标(例如,召回得分)是最佳的,但也可以进行校准(在某种意义上,predict_proba方法的输出可以直接解释)作为置信度,请参见https://scikit-learn.org/stable/modules/calibration.html)。将sklearn GridSearchCV与CalibratedClassifierCV一起使用是否有意义,即通过GridSearchCV拟合分类器,然后将GridSearchCV输出传递给CalibratedClassifierCV对象?如果我是正确的,那么CalibratedClassifierCV对象将适合给定的估算器cv时间,然后将每个折痕的概率取平均值进行预测。但是,对于每个折叠,GridSearchCV的结果可能会有所不同。

3 个答案:

答案 0 :(得分:2)

是的,您可以执行此操作,并且可以正常工作。我不知道这样做是否有意义,但是我至少能做的就是解释我相信会发生什么。

我们可以将这样做与其他方法进行比较,后者是从网格搜索中获得最佳估计量并将其提供给校准的方法。

  1. 简单地获得最佳估算器并将其输入到Calibrationcv
from sklearn.model_selection import GridSearchCV
from sklearn import svm, datasets
from sklearn.calibration import CalibratedClassifierCV

iris = datasets.load_iris()
parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
svc = svm.SVC()
clf = GridSearchCV(svc, parameters)
clf.fit(iris.data, iris.target)
calibration_clf = CalibratedClassifierCV(clf.best_estimator_)
calibration_clf.fit(iris.data, iris.target)
calibration_clf.predict_proba(iris.data[0:10])

array([[0.91887427, 0.07441489, 0.00671085],
       [0.91907451, 0.07417992, 0.00674558],
       [0.91914982, 0.07412815, 0.00672202],
       [0.91939591, 0.0738401 , 0.00676399],
       [0.91894279, 0.07434967, 0.00670754],
       [0.91910347, 0.07414268, 0.00675385],
       [0.91944594, 0.07381277, 0.0067413 ],
       [0.91903299, 0.0742324 , 0.00673461],
       [0.91951618, 0.07371877, 0.00676505],
       [0.91899007, 0.07426733, 0.00674259]])

  1. 在标定简历中的进给网格搜索

from sklearn.model_selection import GridSearchCV
from sklearn import svm, datasets
from sklearn.calibration import CalibratedClassifierCV

iris = datasets.load_iris()
parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
svc = svm.SVC()
clf = GridSearchCV(svc, parameters)
cal_clf = CalibratedClassifierCV(clf)
cal_clf.fit(iris.data, iris.target)
cal_clf.predict_proba(iris.data[0:10])

array([[0.900434  , 0.0906832 , 0.0088828 ],
       [0.90021418, 0.09086583, 0.00891999],
       [0.90206035, 0.08900572, 0.00893393],
       [0.9009212 , 0.09012478, 0.00895402],
       [0.90101953, 0.0900889 , 0.00889158],
       [0.89868497, 0.09242412, 0.00889091],
       [0.90214948, 0.08889812, 0.0089524 ],
       [0.8999936 , 0.09110965, 0.00889675],
       [0.90204193, 0.08896843, 0.00898964],
       [0.89985101, 0.09124147, 0.00890752]])

请注意,两者的概率输出略有不同。

每种方法之间的区别是:

  1. 使用最佳估算器仅跨5个分割(默认cv)进行校准。在所有5个分割中都使用相同的估算器。

  2. 使用网格搜索,正在对来自校准5次的5个CV分割中的每一个进行网格搜索。基本上,每次选择4/5数据的最佳估计量,然后在最后5日使用最佳估计量进行校准时,实际上就是对4/5的数据进行交叉验证。根据网格搜索的选择,在每组测试数据上运行的模型可能会略有不同。

我认为网格搜索和校准是不同的目标,所以我认为我可能会分别进行研究,并按照上面指定的第一种方式获得效果最佳的模型,然后将其输入校准曲线。

但是,我不知道您的具体目标,所以我不能说这里描述的第二种方法是错误的方法。您总是可以尝试两种方式,看看有什么能给您带来更好的性能,然后选择效果最好的一种。

答案 1 :(得分:2)

我认为您的方法与您的目标略有不同。您的目标是“找到一个具有最佳召回率的模型,哪个置信度应该是无偏的”,但您要做的是“找到一个具有最佳召回率的模型,然后使置信度无偏”。所以一个更好(但更慢)的方法是:

  1. CalibratedClassifierCV 包裹您的模型,将此模型视为您应该优化的最终模型;
  2. 修改您的参数网格,确保您在 CalibratedClassifierCV 内调整模型(将 param 更改为类似 base_estimator__param 的内容,这是属性 CalibratedClassifierCV 来保存基估计量)
  3. CalibratedClassifierCV 模型输入到最终的 GridSearchCV 中,然后拟合
  4. 获得 best_estimator_,这是您的无偏模型,具有最佳召回率。

答案 2 :(得分:0)

我建议您在单独的一组上进行校准,以免造成估计偏差。 我看到两个选项。如上所述,您可以在为校准而生成的一小部分折叠内进行交叉验证,或者在对训练集执行交叉验证后,将仅用于校准的临时评估集分开。 无论如何,我建议您最终在测试集上进行评估。