728x90
반응형
오늘은 임상적 평가에 있어 많이 사용되는 평가지표인 민감도, 특이도에 대해 포스팅하겠다.
민감도 특이도 계산
우선 정답과 예측에 대한 예시를 들기 위해 random 함수와 각 개수를 쉽게 카운트하는 Counter 함수를 import 한다.
[라이브러리 임포트]
import random
from collections import Counter
그 후 예시를 들기 위해 양성은 '1', 음성은 '0'으로 정하여 정답과 예측을 랜덤으로 10개씩 구성했다.
[정답 & 예측 예시 생성]
gt,pred = [],[]
for _ in range(10):
gt.append(random.randint(0,1))
pred.append(random.randint(0,1))
예시는 다음과 같다.
print(gt) # [1, 1, 1, 0, 1, 0, 1, 0, 0, 0]
print(pred) # [1, 0, 1, 1, 0, 0, 1, 1, 1, 1]
[TP, FP, TN, FN 계산]
TP : True Positive - 양성 (정답), 양성 (예측)
FP : False Postive - 음성 (정답), 양성 (예측)
TN : True Negative - 음성 (정답), 음성 (예측)
FN : False Negative - 양성 (정답), 음성 (예측)
TP,TN,FP,FN = 0,0,0,0
for g,p in zip(gt,pred):
if p == 1:
if p == g:
TP += 1
elif p != g:
FP += 1
elif p == 0:
if p == g:
TN += 1
elif p != g:
FN += 1
** 임상적으로는 TP, FP가 큰의미를 지님. 암환자에게 암이 있다고 얘기하는것도 중요하지만, 암이 없는데 있다고 진단하여 수술 혹은 시술을 하게 되면 환자, 병원 모두에 악영향.
예시는 다음과 같다.
print(TP,TN,FP,FN) # 3 1 4 2
[민감도, 특이도 계산]
Sensitivity (민감도) : TP / (TP + FN)
- 정답이 양성인 경우 양성으로 예측한 비율
Specificity (특이도) : TN / (TN + FP)
- 정답이 음성인 경우 음성으로 예측한 비율
sensitivity = TP / (TP + FN) # 민감도
specificity = TN / (TN + FP) # 특이도
print(sensitivity,specificity) # 0.6 0.2
다른 방법의 민감도 특이도 계산
위 코드와 같이 민감도와 특이도를 구할 수 있지만 Detection 모델로 부터 산출된 예측의 경우 TN 혹은 FN을 구하기 쉽지 않다.
따라서 본 포스팅의 목적인 다른 방법을 이용하여 민감도와 특이도를 구하는 방법을 소개하고자 한다.
[위양성률 계산]
FPR (위양성률) = FP / (TN + FP) = 1 - Specificity
위양성률은 수식에서 알 수 있듯이 특이도와 연관이 깊다.
FPR = FP / (TN + FP) # 위양성률
print(1-specificity == FPR) # True
[개수 비교]
민감도의 분모는 TP + FN로 정답들 중 양성인 개수이며,
위양성률의 분모는 TP + FP로 정답들 중 음성인 개수이며,
FP는 예측들 중 양성인 개수에 TP를 제외하면 산출된다.
gt_negative = Counter(gt)[0] # 정답 중 negative인 개수 # 5
gt_positive = Counter(gt)[1] # 정답 중 positive인 개수 # 5
pred_positive = Counter(pred)[1] # 예측 중 positive인 개수 # 7
print(gt_positive == TP + FN) # 정답 중 postivie인 개수 = 민감도의 분모 # True
print(gt_negative == TN + FP) # 정답 중 negative인 개수 = 위양성률의 분모 # True
print(pred_positive - TP == FP) # 예측 중 positive인 개수 = TP + FP # True
[민감도, 특이도 비교]
위 수식들을 종합하여 정리하면,
Sensitivity = TP / 양성 정답
Specificity = 1 - (FP / 음성 정답) = 1 - ((양성 예측 - TP) / 음성 정답)
로 정리할 수 있다.
print(sensitivity == TP / gt_positive) # True
print(specificity == round(1 - ((pred_positive - TP) / gt_negative), 1)) # True
[민감도, 특이도 함수 생성]
즉 정답, 예측, TP에 대한 정보만 있다면 민감도와 특이도를 구할 수 있다.
def cal_eval(gt,pred,TP):
gt_negative = Counter(gt)[0]
gt_positive = Counter(gt)[1]
pred_positive = Counter(pred)[1]
sensitivity = TP / gt_positive
specificity == 1 - ((pred_positive - TP) / gt_negative)
return sensitivity, specificity
[민감도, 특이도 함수 사용 예시]
gt,pred = [],[]
for _ in range(100):
gt.append(random.randint(0,1))
pred.append(random.randint(0,1))
TP = 0
for g,p in zip(gt,pred):
if p == 1 and p == g:
TP += 1
sensitivity, specificity = cal_eval(gt,pred,TP)
728x90
반응형
'Python > 의료영상처리' 카테고리의 다른 글
[Python] Dicom 의료영상 tag 읽기 (0) | 2023.01.31 |
---|---|
[Python] nrrd 파일 읽고 시각화 하기 (0) | 2023.01.29 |
[Python] mhd 파일 읽고 시각화 하기 (0) | 2023.01.29 |
[Python] nifti 파일 읽고 시각화하기 (0) | 2023.01.26 |
[Python] SimpleITK - CT 영상 읽는법 (0) | 2022.08.30 |
댓글