본문 바로가기

AI & Computer Science

AI 모델 성능 평가를 위한 R 코드: 신뢰 구간(CI) 계산 가이드(파이썬)

반응형
AI 모델 성능 평가를 위한 완벽한 가이드: 성능 지표와 신뢰 구간 계산

AI 모델을 개발하고 평가하는 과정에서, 모델의 성능을 정확히 측정하고 그 결과를 신뢰할 수 있도록 하는 것은 매우 중요합니다.
특히, 정확도(Accuracy), 민감도(Sensitivity), 특이도(Specificity), 양성예측도(PPV), 음성예측도(NPV)와 같은 주요 성능 지표는 모델이 얼마나 잘 예측하는지를 보여주는 중요한 척도입니다. 그러나 이러한 지표들은 단순한 값 이상을 의미하며, 신뢰 구간(CI)을 함께 계산함으로써 그 값의 신뢰성을 평가할 수 있습니다.

 

이 포스팅에서는 Python 코드를 활용해 AI 모델의 성능 지표와 그 신뢰 구간을 간단하게 계산하는 방법을 소개합니다. 반복적인 작업을 자동화하고, 필요할 때마다 쉽게 사용할 수 있도록 하나의 통합된 스크립트를 통해, AI 모델을 평가할 때마다 시간을 절약하고 효율성을 높일 수 있습니다.

 

0. 전체 py 코드

import numpy as np
import pandas as pd
from sklearn.metrics import roc_auc_score, roc_curve
from sklearn.utils import resample

# 이 함수는 AI 모델의 예측값과 실제 라벨을 비교하여 기본적인 성능 지표를 계산합니다.
# 계산되는 지표는 정확도(Accuracy), 민감도(Sensitivity), 특이도(Specificity), 양성예측도(PPV), 음성예측도(NPV)입니다.
def calc_metrics(data):
    tp = np.sum((data['predictions'] == 1) & (data['label'] == 1))
    tn = np.sum((data['predictions'] == 0) & (data['label'] == 0))
    fp = np.sum((data['predictions'] == 1) & (data['label'] == 0))
    fn = np.sum((data['predictions'] == 0) & (data['label'] == 1))

    acc = (tp + tn) / (tp + tn + fp + fn)
    sens = tp / (tp + fn)
    spec = tn / (tn + fp)
    ppv = tp / (tp + fp)
    npv = tn / (tn + fn)

    return np.array([acc, sens, spec, ppv, npv])

# 이 함수는 Bootstrap 방법을 사용하여 성능 지표에 대한 신뢰 구간(CI)을 계산합니다.
# 신뢰 구간은 성능 지표의 불확실성을 나타내며, 모델 평가의 신뢰성을 높이는 데 사용됩니다.
def get_ci(final, nPos, nNeg):
    tp = round(final['sens'] * nPos)
    fn = round(nPos - tp)
    tn = round(final['spec'] * nNeg)
    fp = round(nNeg - tn)
    
    data_boot = pd.DataFrame({
        'predictions': np.concatenate([np.ones(tp + fp), np.zeros(tn + fn)]),
        'label': np.concatenate([np.ones(tp), np.zeros(fp), np.ones(fn), np.zeros(tn)])
    })

    results = np.array([calc_metrics(resample(data_boot)) for _ in range(1000)])
    
    target_metrics = ["acc", "sens", "spec", "ppv", "npv"]
    for i, metric in enumerate(target_metrics):
        if final[metric] == 1:
            CI = [1.0, 1.0]
        else:
            CI = np.percentile(results[:, i], [2.5, 97.5])
        final[metric] = f"{round(final[metric], 3)} ({round(CI[0], 3)}-{round(CI[1], 3)})"
    
    return final

# 이 함수는 주어진 데이터에 대해 ROC 곡선과 AUC를 계산하고, 그 외의 성능 지표들을 산출하여 신뢰 구간(CI)과 함께 반환합니다.
# 이 함수는 AI 모델의 종합적인 성능을 평가하는 데 사용됩니다.
def get_metrics(data):
    fpr, tpr, thresholds = roc_curve(data['label'], data['pred'])
    auc = roc_auc_score(data['label'], data['pred'])
    auc_ci = np.percentile([roc_auc_score(data['label'], resample(data['pred'])) for _ in range(1000)], [2.5, 97.5])
    auc_result = f"{round(auc, 3)} ({round(auc_ci[0], 3)}-{round(auc_ci[1], 3)})"

    res = pd.DataFrame({'sens': tpr, 'spec': 1-fpr, 'thresh': thresholds})
    res['acc'] = (res['sens'] * np.sum(data['label'] == 1) + res['spec'] * np.sum(data['label'] == 0)) / len(data)
    res['ppv'] = res['sens'] * np.sum(data['label'] == 1) / (res['sens'] * np.sum(data['label'] == 1) + (1 - res['spec']) * np.sum(data['label'] == 0))
    res['npv'] = res['spec'] * np.sum(data['label'] == 0) / (res['spec'] * np.sum(data['label'] == 0) + (1 - res['sens']) * np.sum(data['label'] == 1))
    final = res.loc[res['sens'] + res['spec'] - 1 == (res['sens'] + res['spec'] - 1).max(), ['sens', 'spec', 'acc', 'ppv', 'npv']].iloc[0].to_dict()
    final['AUC'] = auc_result
    
    nPos = np.sum(data['label'] == 1)
    nNeg = np.sum(data['label'] == 0)
    
    return get_ci(final, nPos, nNeg)

# 이 메인 함수는 전체 파이프라인을 실행하여 데이터에 대해 성능 지표를 계산하고, 결과를 출력합니다.
if __name__ == "__main__":
    data = pd.DataFrame({
        'label': np.random.choice([0, 1], 300, replace=True),
        'pred': np.random.rand(300)
    })

    final_metrics = get_metrics(data)
    print(final_metrics)

 

 

 

코드를 한줄한줄 뜯어볼까요?

1. calc_metrics.py

#calc_metrics.py

import numpy as np

def calc_metrics(data):
    tp = np.sum((data['predictions'] == 1) & (data['label'] == 1))
    tn = np.sum((data['predictions'] == 0) & (data['label'] == 0))
    fp = np.sum((data['predictions'] == 1) & (data['label'] == 0))
    fn = np.sum((data['predictions'] == 0) & (data['label'] == 1))

    acc = (tp + tn) / (tp + tn + fp + fn)
    sens = tp / (tp + fn)
    spec = tn / (tn + fp)
    ppv = tp / (tp + fp)
    npv = tn / (tn + fn)

    return np.array([acc, sens, spec, ppv, npv])​
이 파일은 AI 모델의 성능 평가를 위한 주요 지표들을 계산하는 함수를 정의합니다. 이 함수는 입력된 데이터에서 예측값과 실제 라벨을 비교하여, 정확도(Accuracy), 민감도(Sensitivity), 특이도(Specificity), 양성예측도(PPV), 음성예측도(NPV)와 같은 성능 지표를 계산합니다. 이러한 지표들은 모델이 얼마나 잘 작동하는지를 평가하는 데 중요한 역할을 합니다.

 

2. get_ci.py

# get_ci.py

import numpy as np
import pandas as pd
from calc_metrics import calc_metrics
from sklearn.utils import resample

def get_ci(final, nPos, nNeg):
    tp = round(final['sens'] * nPos)
    fn = round(nPos - tp)
    tn = round(final['spec'] * nNeg)
    fp = round(nNeg - tn)
    
    data_boot = pd.DataFrame({
        'predictions': np.concatenate([np.ones(tp + fp), np.zeros(tn + fn)]),
        'label': np.concatenate([np.ones(tp), np.zeros(fp), np.ones(fn), np.zeros(tn)])
    })

    results = np.array([calc_metrics(resample(data_boot)) for _ in range(1000)])
    
    target_metrics = ["acc", "sens", "spec", "ppv", "npv"]
    for i, metric in enumerate(target_metrics):
        if final[metric] == 1:
            CI = [1.0, 1.0]
        else:
            CI = np.percentile(results[:, i], [2.5, 97.5])
        final[metric] = f"{round(final[metric], 3)} ({round(CI[0], 3)}-{round(CI[1], 3)})"
    
    return final
이 파일은 'calc_metrics' 함수를 사용하여 모델의 성능 지표에 대한 신뢰 구간(CI)을 계산하는 기능을 제공합니다. 신뢰 구간은 모델 성능의 불확실성을 나타내며, Bootstrap 방법을 이용하여 1000번의 반복 샘플링을 통해 계산됩니다. 이 파일은 최종적인 성능 지표에 신뢰 구간을 부여하여, 보다 신뢰할 수 있는 평가 결과를 제공합니다.

 

3. get_metrics.py

# get_metrics.py

import numpy as np
import pandas as pd
from sklearn.metrics import roc_auc_score, roc_curve
from get_ci import get_ci

def get_metrics(data):
    fpr, tpr, thresholds = roc_curve(data['label'], data['pred'])
    auc = roc_auc_score(data['label'], data['pred'])
    auc_ci = np.percentile([roc_auc_score(data['label'], resample(data['pred'])) for _ in range(1000)], [2.5, 97.5])
    auc_result = f"{round(auc, 3)} ({round(auc_ci[0], 3)}-{round(auc_ci[1], 3)})"

    res = pd.DataFrame({'sens': tpr, 'spec': 1-fpr, 'thresh': thresholds})
    res['acc'] = (res['sens'] * np.sum(data['label'] == 1) + res['spec'] * np.sum(data['label'] == 0)) / len(data)
    res['ppv'] = res['sens'] * np.sum(data['label'] == 1) / (res['sens'] * np.sum(data['label'] == 1) + (1 - res['spec']) * np.sum(data['label'] == 0))
    res['npv'] = res['spec'] * np.sum(data['label'] == 0) / (res['spec'] * np.sum(data['label'] == 0) + (1 - res['sens']) * np.sum(data['label'] == 1))
    final = res.loc[res['sens'] + res['spec'] - 1 == (res['sens'] + res['spec'] - 1).max(), ['sens', 'spec', 'acc', 'ppv', 'npv']].iloc[0].to_dict()
    final['AUC'] = auc_result
    
    nPos = np.sum(data['label'] == 1)
    nNeg = np.sum(data['label'] == 0)
    
    return get_ci(final, nPos, nNeg)
이 파일은 주어진 데이터에 대해 ROC 곡선, AUC, 그리고 기타 성능 지표들을 계산하고, 신뢰 구간(CI)을 포함한 최종 평가 결과를 반환합니다. 여기서 AUC는 모델의 전체적인 분류 성능을 나타내며, ROC 곡선을 기반으로 계산됩니다. 최종적으로 계산된 성능 지표들은 'get_ci' 함수를 통해 신뢰 구간을 가지게 됩니다.

 

4. main.py

# main.py

import numpy as np
import pandas as pd
from get_metrics import get_metrics

# 데이터 정의
data = pd.DataFrame({
    'label': np.random.choice([0, 1], 300, replace=True),
    'pred': np.random.rand(300)
})

# 메트릭스 계산
final_metrics = get_metrics(data)
print(final_metrics)
이렇게 네 개의 파일이 서로 연결되어 AI 모델의 성능을 평가하고, 신뢰할 수 있는 결과를 제공합니다. 이 코드를 통해 매번 반복되는 작업을 자동화하고, 필요할 때마다 성능 지표를 쉽게 계산할 수 있습니다.

 

마무리하며

AI 모델의 성능을 평가하는 과정은 데이터 사이언스와 머신러닝에서 중요한 단계입니다. 이 포스팅에서 제공한 Python 코드를 활용하면, 모델의 성능 지표를 간편하게 계산할 수 있을 뿐만 아니라, 신뢰 구간을 통해 결과의 신뢰성을 높일 수 있습니다. 이를 통해 모델의 실제 예측력을 보다 정확하게 평가하고, 결과를 신뢰할 수 있는 방식으로 보고할 수 있습니다.

 

이제 반복적인 성능 평가 작업에서 벗어나, 이 코드를 필요할 때마다 자유롭게 활용해 보세요. 시간을 절약하고 효율성을 높이는데 도움이 될 것입니다. 앞으로도 더 나은 모델 평가와 개선을 위해, 이 코드들을 적극적으로 활용하시길 바랍니다.

반응형