使用标准误差与 CV 进行模型比较

数据挖掘 scikit-学习 交叉验证 机器学习模型
2021-09-30 06:18:45

通过 发现 ML 世界sklearn,我正在我的数据集上测试一大组模型。这是为了学习目的,也是为了工作,所以我希望最终模型尽可能准确,同时我可以在我对 ML 的理解方面取得进步。

我已经将我的数据集(16k 行)分成 80% 的训练和 20% 的测试,并且我正在测试至少KNN, Logistic, DecisionTree, RandomForest,NaivesBayes也许SVC(如果我的计算机可以处理的话),BaggingBoosting我发现如何.

我的训练样本有 4 种方式:2 组特征(95 和 11),是否标准化(带有 a StandardScaler)。

我的结果是二元的,我正在使用自定义记分器“改进”,它可以最大限度地增加第 30 个百分位数的阳性数(在我的帖子末尾使用代码更容易得到它),以及specificityroc_auc

对于每个数据集,我交叉验证(以随机状态分层和打乱,5 次折叠,尽可能重复)我发现相关的所有超参数,并对每个训练样本重复此操作。

对于每个交叉验证,我使用我的记分器进行改装,以便比较模型和数据集之间的结果。对于我迄今为止测试过的模型,我的mean_test_amelioration范围从 +42% 到 +114%。

最后,我将测量所选模型在测试样本上的性能并报告结果。

我想这对专业人士来说可能会觉得很麻烦(而且我可能正在建造一辆坦克来杀死苍蝇),但我已经以这种方式学到了很多东西。

我只是比较所有这些模型,mean_test_amelioration并没有考虑标准错误(例如)。这会导致过度拟合,使我的最终模型不能很好地泛化吗?如果是,我如何考虑可变性?

任何教育链接也非常受欢迎。

PS:因为这可能是相关的,这是我的自定义记分器代码:

def get_amelioration(y_true, y_pred, **kwargs):
    """
       If I select 30% of my sample with this algorithm, I will have 
       `amelioration`% more positives in my selection than without

       :use as: make_scorer(get_amelioration, needs_proba=True, N=30)
    """

    N = kwargs.pop('N', False)
    if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs)

    decisions = (y_pred > np.percentile(y_pred, 100-N)).astype(int)

    tn, fp, fn, tp = metrics.confusion_matrix(y_true, decisions).ravel()
    v = (fp+tp)/(tn+fp+fn+tp)
    r = tp/(fp+tp)
    r_base = np.mean(y_true) #around 15% in my sample, expected to be stable
    amelioration = 100*(r/r_base-1)
#    print("N=%i, v=%0.3f, amelioration=%0.3f" %(N,v, amelioration))
    if v<0.75*N/100: return 0
    return amelioration
1个回答

有可能,但是,这通常不是很大的问题。如果您想考虑标准误差,一种可能性如下:

  1. 您计算最佳性能模型的标准误差(使用您的amelioration指标)
  2. 考虑在一个标准误差内执行的所有模型(或者如果您愿意,可以更少)
  3. 选择决策边界最简单的模型

这是基于奥卡姆剃刀的启发式(!) ,更简单的模型倾向于更好地概括。但是,请记住,对于复杂的问题,更简单的模型可能就是这样:更简单。他们不必更准确。

或者,如果您的主要目标是限制您对这种可变性的暴露,您可以选择具有最小标准误差的模型,而不是 3。

还要记住,K-Fold Cross-Validation 的方差没有无偏估计量,因此这种方法带来了它自己的不确定性。

一般来说,我只会关注标准误差,如果不是太在意,就选择数值性能最好的模型。