【问题标题】:Calculation of AUC 95 % CI from Cross Validation (Python, sklearn)通过交叉验证计算 AUC 95 % CI (Python, sklearn)
【发布时间】:2020-05-18 07:32:47
【问题描述】:

我正在寻找从我的 5 倍 CV 计算 AUC 95 % CI 的正确方法。

n = 81 我的训练数据集

所以,如果我应用 5 倍 CV,它的平均值约为 . n = 16 在测试组的每一折中。

下面是我的 Python 代码。

folds = 5
seed = 42

# Grid Search
fit_intercept=[True, False]
C = [np.arange(1,41,1)]
penalty = ['l1', 'l2']
params = dict(C=C, fit_intercept = fit_intercept, penalty = penalty)

logreg = LogisticRegression(random_state = seed)

logreg_grid = GridSearchCV(logreg, param_grid = params , cv=folds, scoring='roc_auc',  iid='False')

# fit the grid with data
logreg_grid.fit(X_train, y_train)

# fit best estimator
logreg = logreg_grid.best_estimator_

# Calculate AUC in 5-fold Stratified CV
logreg_scores = cross_val_score(logreg, X_train, y_train, cv=folds, scoring='roc_auc')
print('LogReg:',logreg_scores.mean())

# LogReg Scores: [0.95714286, 0.85, 0.98333333, 0.85, 0.56666667]  
# Mean: 0.8414285714285714````

#AUC from LogReg = 0.8414

#Three ways I have tried to calculate the 95 % CI:

#LogReg Scores: [0.95714286, 0.85, 0.98333333, 0.85, 0.56666667]  
# Mean: 0.8414285714285714


                    ### First try ###
import statsmodels.stats.api as sms
conf = sms.DescrStatsW(logreg_scores).tconfint_mean(.05)
print(conf)

#Out: Lower 0.636, Upper: 1.047

                    ### Second Try ###
import scipy.stats
def mean_confidence_interval(data, confidence=0.95):
    a = 1.0 * np.array(data)
    n = len(a)
    m, se = np.mean(a), scipy.stats.sem(a)
    h = se * scipy.stats.t.ppf((1 + confidence) / 2, n-1)
    return m, m-h, m+h


mean_confidence_interval(logreg_scores, confidence=0.95)

#Out: Mid: 0.84, Lower: 0.64, Upper: 1.05)

                      ### Third ###
# interval = t * np.sqrt( (AUC * (1 - AUC)) / n)
# n = 16 (validation set), because the mean in of alle 5 folds is 16 aof my n = 81
# t = 2.120 (Source: https://www.sjsu.edu/faculty/gerstman/StatPrimer/t-table.pdf)

interval = 2.120 * np.sqrt( (0.8414285714285714 * (1 - 0.8414285714285714)) / 16)
print((.84 + interval)*100)
print(.84)
print((.84 - interval)*100)
print(interval)

# Output: Lower: 64.64 , Mid: 0.84, Upper: 103.36 , Interval: 0.194

我的问题:所有结果看起来都相似。但是,我做错了什么,因为我不明白 AUC 怎么能> 1.0?

感谢您的回复,期待您的回答。

干杯米沙

【问题讨论】:

    标签: python logistic-regression cross-validation confidence-interval auc


    【解决方案1】:

    我不确定它是否能解决您的问题,但我想这是因为您正在对极小的样本量 (n=5) 应用 t 检验。预计会有很大的差异,这就是为什么在您的情况下均值 + SD > 1。请注意,您的所有三种方法都是基于 t 检验的。

    要获得足够数量的比较,您可能需要尝试 1) 具有不同子类的多个重复 CV 或 2) 引导程序。关于CV的一些有用的讨论:CV

    【讨论】:

    • 非常有帮助,谢谢!如果您能帮助我解决我的最后一个问题,我已经发布了详细的答案,将不胜感激。
    【解决方案2】:

    这是一个非常有帮助的答案天临河!谢谢。

    我是这样实现的:

    from sklearn.model_selection import RepeatedStratifiedKFold
    
    cv = RepeatedStratifiedKFold(n_splits = 5, n_repeats = 100, random_state = seed)
    
    logreg_scores = cross_val_score(logreg, X_train, y_train, cv=cv, scoring='roc_auc')
    print('LogReg:',logreg_scores.mean())
    
    
    import scipy.stats
    def mean_confidence_interval(data, confidence=0.95):
        a = 1.0 * np.array(data)
        n = len(a)
        m, se = np.mean(a), scipy.stats.sem(a)
        h = se * scipy.stats.t.ppf((1 + confidence) / 2, n-1)
        return m, m-h, m+h
    
    mean_confidence_interval(logreg_scores, confidence=0.95)
    

    输出很好,因为现在我有 500 个 AUC。 >>> (0.8014285714285716, 0.7921705464185262, 0.810686596438617)

    但是我怎样才能实现这个概率呢?

    y_pred = cross_val_predict(logreg, X_train, y_train, cv=cv, method='predict_proba')
    

    如果我使用上面的代码,它会抛出一个错误:“cross_val_predict 仅适用于分区”

    【讨论】:

    • 我非常感谢您的尝试,我也赞成您的回答。但我不得不承认,错误对我来说看起来很陌生。您实际上可能会打开一个新问题,但使用您的完整代码,尤其是包括您的 minimally reproducible input data
    猜你喜欢
    • 2018-08-16
    • 2016-01-19
    • 2012-12-31
    • 2020-07-04
    • 2018-04-26
    • 1970-01-01
    • 2021-11-19
    • 2015-06-11
    • 2021-03-25
    相关资源
    最近更新 更多