统计小白如何计算各个指标的95%CI以及两个AUC之间的Delong Test

统计小白如何计算各个指标的95%CI以及两个AUC之间的Delong Test

目录第一部分:计算各个指标的95%CI(1)指标计算公式(2)95%CI计算公式(3)计算实现方式TP、TN、FP、FN的获取方式1:利用现成的网站方式2::Python代码实现第二部分:两个AUC之间的Delong Test

第一部分:计算各个指标的95%CI

(1)指标计算公式

根据论文需要,指标包括AUC(AUC的所有计算见第二部分)、精度ACC、敏感度SEN、特异度SPE、正预测值PPV、负预测值NPV、F1分数

各计算公式如下:

\(\text{ACC} = \frac{TP + TN}{TP + TN + FP + FN}\)

\(\text{SEN} = \frac{TP}{TP + FN}\)

\(\text{SPE} = \frac{TN}{TN + FP}\)

\(\text{PPV} = \frac{TP}{TP + FP}\)

\(\text{NPV} = \frac{TN}{TN + FN}\)

\(\text{F1} = 2 \times \frac{\text{PPV} \times \text{SEN}}{\text{PPV} + \text{SEN}}\)

其中,\(TP=True Positive, TN=True Negative, FP=False Positive, FN=False Negative\)

(2)95%CI计算公式

采用正态近似法(前提是假设数据分别为正态分布,未必都适用哦)

计算公式为\(\hat{p} \pm z_{\frac{\alpha}{2}} \times SE\)

其中:

\(\hat{p}\)为估计值(如ACC等)

\(z_{\frac{\alpha}{2}}\)为标准正态分布的临界值(通常取1.96对应于95%置信区间)

\(SE\)为标准误,其计算公式为\(SE = \sqrt{\frac{\hat{p}(1 - \hat{p})}{n}}\),n为样本总数,不同指标的n不同,是计算指标时的分母

(3)计算实现方式

TP、TN、FP、FN的获取

注意python相关函数与Medcalc软件的在从预测概率获取预测标签过程中的差异

python:默认情况下,预测为1的概率>0.5则预测label为1

Medcalc:通过约登指数得到划分label为0和1的预测概率的阈值

方式1:利用现成的网站

进入网站后,只需要输入True Positive, True Negative, False Positive, False Negative四个变量后点击计算即可。网站1中还需输入\(1-\alpha\)为0.95,网站2中似乎是默认的

网站1:https://www2.ccrb.cuhk.edu.hk/stat/confidence interval/Diagnostic Statistic.htm

网站2:http://vassarstats.net/clin1.html#return

根据我自己的结果,网站1更准确,网站2的95%CI会有点偏差,但是因为其并未给出计算公式,具体原因不得而知

然而,这些网站计算的指标其实是不全的,只包括SEN、SPE、PPV和NPV。如果需要更全指标的结果,可使用下一节的python代码得到

方式2::Python代码实现

代码如下,按照公式计算,与网站1的结果完全一致:

import pandas as pd

import math

import scipy.stats as stats

# 定义计算各项指标及其95%置信区间的函数

def calculate_metrics(TP, TN, FP, FN):

# 总样本数

n = TP + TN + FP + FN

# 计算各个指标

ACC = (TP + TN) / n

SEN = TP / (TP + FN)

SPE = TN / (TN + FP)

PPV = TP / (TP + FP)

NPV = TN / (TN + FN)

F1 = 2 * (PPV * SEN) / (PPV + SEN)

# 计算标准误

SE_ACC = math.sqrt(ACC * (1 - ACC) / n)

SE_SEN = math.sqrt(SEN * (1 - SEN) / (TP + FN))

SE_SPE = math.sqrt(SPE * (1 - SPE) / (TN + FP))

SE_PPV = math.sqrt(PPV * (1 - PPV) / (TP + FP))

SE_NPV = math.sqrt(NPV * (1 - NPV) / (TN + FN))

SE_F1 = math.sqrt(F1 * (1 - F1) / n)

# Z值

z = stats.norm.ppf(0.975)

# 计算95%置信区间

CI_ACC = (ACC - z * SE_ACC, ACC + z * SE_ACC)

CI_SEN = (SEN - z * SE_SEN, SEN + z * SE_SEN)

CI_SPE = (SPE - z * SE_SPE, SPE + z * SE_SPE)

CI_PPV = (PPV - z * SE_PPV, PPV + z * SE_PPV)

CI_NPV = (NPV - z * SE_NPV, NPV + z * SE_NPV)

CI_F1 = (F1 - z * SE_F1, F1 + z * SE_F1)

# 返回结果

return {

"ACC": round(ACC, 3),

"CI_ACC_Lower": round(CI_ACC[0], 3),

"CI_ACC_Upper": round(CI_ACC[1], 3),

"SEN": round(SEN, 3),

"CI_SEN_Lower": round(CI_SEN[0], 3),

"CI_SEN_Upper": round(CI_SEN[1], 3),

"SPE": round(SPE, 3),

"CI_SPE_Lower": round(CI_SPE[0], 3),

"CI_SPE_Upper": round(CI_SPE[1], 3),

"PPV": round(PPV, 3),

"CI_PPV_Lower": round(CI_PPV[0], 3),

"CI_PPV_Upper": round(CI_PPV[1], 3),

"NPV": round(NPV, 3),

"CI_NPV_Lower": round(CI_NPV[0], 3),

"CI_NPV_Upper": round(CI_NPV[1], 3),

"F1": round(F1, 3),

"CI_F1_Lower": round(CI_F1[0], 3),

"CI_F1_Upper": round(CI_F1[1], 3)

}

# 示例数据:TP, TN, FP, FN

TP = 64

TN = 101

FP = 14

FN = 13

# 计算指标

metrics = calculate_metrics(TP, TN, FP, FN)

# 创建一个DataFrame用于保存结果

df = pd.DataFrame([metrics])

# 输出为CSV文件

df.to_csv(r'metrics.csv', index=False)

print(df)

第二部分:两个AUC之间的Delong Test

关于AUC及其95%CI的计算,以及两个AUC之间的Delong Test,都是用Medcalc这个软件最方便

关于如何使用Medcalc软件,可参考:https://zhuanlan.zhihu.com/p/76351802

简单介绍如下,可以自己摸索一下:

1、点击File——New,新建一个工作表,把预测概率(或者其他形式,这里指机器学习模型预测各个样本为正样本的概率)和label(ground truth标签)粘贴进来,第一行为列名(以识别对应列的数据),不同列对应于不同模型的结果

2、点击Statistics——ROC curves,如果你只需要算一列结果的AUC,则选择ROC curve analysis;如果需要比较多个AUC,且共用一列的label,则选择Comparison of ROC curves

3、会跳出一个页面,在Variables下选择需要得到AUC的数据列的列名(多个比较则选多个);在Classification Variable下选择label列的列名,并且在其下面的define status里输入你在label列中用什么表示正样本,什么表示负样本

4、在对比ROC曲线时,跳出的页面右侧可以选择使用Delong test还是Hanley & McNeil

5、最后点击OK即可,会跳出结果页面,里面ROC曲线,AUC,其95%CI,两两ROC曲线比较得到的P值,等等,应有尽有

相关推荐