比较2个ML模型的性能准确性之间的差异是否在统计上显着

时间:2019-02-02 22:43:58

标签: python machine-learning statistics cross-validation

这是我第一次使用堆栈交换,但是我需要一个问题的帮助(这不是家庭作业或作业问题):

我有两个决策树:var tabs = []; isTrue().then(res => { if (res) { tabs.push('some string'); } return tabs; }).then(arr => { console.log(arr); }); function isTrue() { //Just wrap your existing code in a Promise constructor return new Promise((resolve, reject) => { setTimeout(() => { //Pass whatever value you want to consume later to resolve resolve(true); }, 500) }); }D1 = DecisionTreeClassifier(max_depth=4,criterion = 'entropy',random_state=1)。当我针对给定的一组功能和相应的标签对它们两者执行5折交叉验证时,我发现它们在5折上的平均验证准确性分别为0.59和0.57。我如何确定他们的表现之间的差异是否统计显著与否? (P.S.我们将使用显着性水平= 0.01)。

请在此处说明是否缺少任何信息或有意义的术语。

1 个答案:

答案 0 :(得分:0)

这是一个很好的问题,答案并不那么简单。

本能地,大多数人会倾向于推荐Student's paired t-test;但是,正如《机器学习精通》的出色文章Statistical Significance Tests for Comparing Machine Learning Algorithms中所解释的那样,该测试实际上不适合这种情况,因为实际上违反了其假设:

  

实际上,这种[学生t检验]是比较的一种常见方法   分类器,也许有数百篇已发表论文使用此   方法。

     

问题在于,配对学生t检验的关键假设是   被侵犯。

     

即,每个样本中的观察值不是独立的。作为一部分   对于k折交叉验证程序,给定的观察将是   在训练数据集中使用(k-1)次。这意味着   估计的技能分数是相关的,而不是独立的,进而   检验中t统计量的计算将是   误导性错误以及对统计数据的任何解释和   p值。

本文继续推荐McNemar的测试(另请参见this,现已关闭,有关问题),该测试在statsmodels Python软件包中实现。我不会假装对它一无所知,而且我从未使用过它,所以您可能需要在这里自己进行进一步的挖掘...

尽管如此,如前所述,学生的t检验可能是“最后的手段”:

  

这是一个选择,但强烈建议不要这么做。

这就是我要在这里演示的内容;谨慎使用。

首先,您不仅需要平均值,而且还需要交叉验证的k折中的每一个k折中的性能指标的实际值。在scikit-learn中,这并不完全是微不足道的,但是我最近在Cross-validation metrics in scikit-learn for each data split上回答了一个相关问题,在这里我将使用scikit-learn的Boston数据集和两个决策树回归器来调整答案(您当然可以将它们调整为您自己的确切情况):

randomNo=randint(0,n)
print("This time you will choose a number, and the Computer will attempt to guess your number!")
print("Hello, what is your name:")
myName=str(input())


print("Alright "+myName+", "+"I will start to guess your number now!"+"\nchoose it, I will close my eyes.")
number=int(input())
time.sleep(2)
print("Okay, I will open my eyes now!")
time.sleep(2)
print("Can I start guessing now? Just answer with 'no' , 'yes'")
Answer=str(input())
if Answer[0:]=="no":
    time.sleep(1)
    print("all this for nothing.. bye")
if Answer[0:]=="yes":
    time.sleep(1)
    print("Alright let's go!")
    time.sleep(1)

print("my first guess is: ",randomNo)

while number!=randomNo:
    Userinput=input()

    if Userinput=="too big":
        x1=randomNo-1
        print(x1)
        randomNo=x1

    if Userinput=="too small":
        x1=randomNo+1
        print(x1)
        randomNo=x1

    if Userinput=="richtig":
        print("I win!")

from sklearn.model_selection import KFold from sklearn.datasets import load_boston from sklearn.metrics import mean_absolute_error from sklearn.tree import DecisionTreeRegressor X, y = load_boston(return_X_y=True) n_splits = 5 kf = KFold(n_splits=n_splits, shuffle=True) model_1 = DecisionTreeRegressor(max_depth = 4, criterion='mae',random_state=1) model_2 = DecisionTreeRegressor(max_depth = 8, criterion='mae', random_state=1) cv_mae_1 = [] cv_mae_2 = [] for train_index, val_index in kf.split(X): model_1.fit(X[train_index], y[train_index]) pred_1 = model_1.predict(X[val_index]) err_1 = mean_absolute_error(y[val_index], pred_1) cv_mae_1.append(err_1) model_2.fit(X[train_index], y[train_index]) pred_2 = model_2.predict(X[val_index]) err_2 = mean_absolute_error(y[val_index], pred_2) cv_mae_2.append(err_2) 包含我们第一个模型的5折中的每一个的度量值(这里是平均绝对误差-MAE):

cv_mae_1

,对于第二个模型,类似地cv_mae_1 # result: [3.080392156862745, 2.8262376237623767, 3.164851485148514, 3.5514851485148515, 3.162376237623762]

cv_mae_2

已经获得了这些列表,现在可以使用scipy的相应方法来简单地计算配对的t检验统计量和相应的p值:

cv_mae_2
# result
[3.1460784313725494,
 3.288613861386139,
 3.462871287128713,
 3.143069306930693,
 3.2490099009900986]

在我们的例子中,巨大的p值表示我们的MAE指标的均值之间在统计上没有显着差异。

希望这会有所帮助-不要犹豫,自己深入研究...