首页 文章

当使用具有小 balancer 数据集的GridSearchCV时,sklearn.SVC返回完全不同的预测(模型)

提问于
浏览
0

当使用sklearn.GridSearchCV而不是sklearn.SVC(概率=真)时,当训练数据很小且 balancer (相对较小且不 balancer )时,将返回完全不同的预测/模型 . 考虑这个例子:

from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn import svm, datasets
iris = datasets.load_iris()
# Take the first two features. We could avoid this by using a two-dim dataset
X = iris.data[:, :2]
y = iris.target

index = [0,1,2,3,51,52,53,54]
index_unequal = [0,1,2,3,51,52,53,54,55]
new_predictions = [5, 6, 7, 56, 57, 58]
pred_mat, pred_y = X[new_predictions], y[new_predictions]
c_s = [0.01, 0.1, 1.0, 10.0, 100.0]
gamma = [1e-4, 1e-3, 1e-2, 1e-1, 1, 10]
svc_params = [{'kernel': ['rbf'], 'gamma': gamma, 'C': c_s},
              {'kernel': ['linear'], 'C': c_s}]
mat, ye = X[index], y[index]
mat_unequal, y_unequal = X[index_unequal], y[index_unequal]

balanced = GridSearchCV(SVC(probability=True), svc_params, cv=4).fit(mat, ye)
unbalanced = GridSearchCV(SVC(probability=True), svc_params, cv=4).fit(mat_unequal, y_unequal)

print(balanced.predict_proba(pred_mat))
print(unbalanced.predict_proba(pred_mat))

在 balancer 数据上训练的模型返回所有新数据的概率 0.5 ,而使用不 balancer 数据训练的模型返回人们通常期望的结果 . 我知道这个例子中使用的训练数据很小,但只有1的差异,我很好奇是什么机制被改变,以给出这种截然不同的模型/概率 .

Update #1 在深入研究这一点之后,考虑下面的Vivek响应(感谢真正伟大的链接!),了解 predictpredict_proba 之间的区别是成功的一半 . 我可以选择GridSearch的评分函数来优化概率而不是决策函数(例如,将 scoring='neg_log_loss' 添加到我的 GridSearchCV 调用中) . 这将在两个模型之间提供更好的恢复 . 但是,我仍然对上述问题的结果感到好奇 . 如果你深入研究两个模型之间的区别,唯一的两个区别是附加数据和交叉验证生成器(即 StratifiedKFold 上的cv属性)选择分割数据的方式 . 例如,考虑这些分层的k折指数:

balanced_cv_iter = [(np.array([1, 2, 3, 5, 6, 7]), np.array([0, 4])),
            (np.array([0, 2, 3, 4, 6, 7]), np.array([1, 5])),
            (np.array([0, 1, 3, 4, 5, 7]), np.array([2, 6])),
            (np.array([0, 1, 2, 4, 5, 6]), np.array([3, 7]))]

unbalanced_cv_iter = [(np.array([1, 2, 3, 6, 7, 8]), np.array([0, 4, 5])),
              (np.array([0, 2, 3, 4, 5, 7, 8]), np.array([1, 6])),
              (np.array([0, 1, 3, 4, 5, 6, 8]), np.array([2, 7])),
              (np.array([0, 1, 2, 4, 5, 6, 7]), np.array([3, 8]))]

balanced_cv_iter_new = [(np.array([1, 2, 3, 5, 6]), np.array([0, 4, 7])),
            (np.array([0, 2, 3, 4, 6, 7, 1]), np.array([5])),
            (np.array([0, 1, 3, 4, 5, 7, 2]), np.array([6])),
            (np.array([0, 1, 2, 4, 5, 6]), np.array([3, 7]))]

balanced_cv_iterunbalanced_cv_iter 是上述代码生成的两个潜在列表,与两个模型的训练/测试数据相关 . 但是,如果我们通过使训练/测试具有一些奇数个元素(不 balancer 的训练/测试集)来改变 balanced_cv_iter ,那么我们可以得到 balanced_cv_iter_new . 这样做会导致 balancer 模型和非 balancer 模型之间的预测相似 . I guess the lesson here is to optimize for the intended use of the model (i.e. choose a scoring function that aligns with the use of the model)? 但是,如果对于为什么GridSearch选择具有超级参数的SVM估计器导致在不 balancer 框架下获得更好的概率模型,我还想知道 .

1 回答

  • 0

    你看错了 . 这与GridSearchCV无关 . 但是用svm .

    你看,你试图在SVC上使用 predict_proba() ,这已知有令人困惑的输出,这些输出可能与 predict() 函数的实际输出不匹配 .

    我用一个小改动运行你的代码:

    print(balanced.predict(pred_mat))
    print(unbalanced.predict(pred_mat))
    

    输出是:

    [0 0 0 1 0 1]
    [0 0 0 1 1 1]
    

    如你所见,这两种情况没有太大区别 . 在这两个输出中我能想到的唯一差异来源是你在第二种情况下有关于第二类的1个额外数据,这有助于比第一种情况更好地识别它 . 您可以通过更改类的示例来验证 .

    现在关于为什么predict_proba给出这样的结果的解释请看:

    一个scikit开发人员在StackOverflow上

    另一个scikit开发者的差异

相关问题