- 第一部分:计算各个指标的95%CI
- 指标计算方式
- 95%CI计算方式
- 计算实现方式
- 方式1:利用现成的网站
- 方式2::Python代码实现
- 第二部分:两个AUC之间的Delong Test
第一部分:计算各个指标的95%CI
指标计算方式
根据论文需要,指标包括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\)
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不同,是计算指标时的分母
计算实现方式
方式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) / nSEN = 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值,等等,应有尽有