【问题标题】:Does it make sense to use sklearn GridSearchCV together with CalibratedClassifierCV?将 sklearn GridSearchCV 与 CalibratedClassifierCV 一起使用是否有意义?
【发布时间】:2020-06-01 12:02:25
【问题描述】:

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

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    是的,你可以做到这一点,它会工作。我不知道这样做是否有意义,但我至少可以解释一下我认为会发生什么。

    我们可以将这样做与从网格搜索中获取最佳估计器并将其提供给校准的替代方案进行比较。

    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. Calibration cv 中的馈电网格搜索
    
    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 个 CV 拆分中的每一个上进行 5 次网格搜索。每次为 4/5 的数据选择最佳估计器时,您实际上是在对 4/5 的数据进行交叉验证,然后在最后 5 日使用该最佳估计器进行校准。根据网格搜索选择的内容,您可以在每组测试数据上运行略有不同的模型。

    我认为网格搜索和校准是不同的目标,所以在我看来,我可能会分别对每一个进行工作,并采用上面指定的第一种方法,得到一个效果最好的模型,然后将其输入校准曲线。

    但是,我不知道您的具体目标,所以我不能说这里描述的第二种方式是错误的方式。您可以随时尝试两种方法,看看哪种方法可以提供更好的性能,然后选择效果最好的方法。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-22
          • 2012-09-13
          • 2017-09-17
          • 1970-01-01
          • 2018-10-24
          • 2018-09-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多