본문 바로가기

공부기록/Python

[scikit-learn] F1 Score 산출

F1 Score 관련 설명 잘 되어있는 링크:

https://towardsdatascience.com/the-f1-score-bec2bbc38aa6

 

The F1 score

All you need to know about the F1 score in machine learning. With an example applying the F1 score in Python.

towardsdatascience.com

 

* Segmentation 결과값과 GT와의 정확도를 비교해야 해서 다시금 찾아보고 정리함

 

파일 내 클래스가 균형있게 분포되어 있지 않아 단순 정확도보단 F1 Score로 비교하는게 맞는 것 같다.

아래 두 가지 방식 중 하나 골라잡으면 될 것 같음.

  • f1_score: 스코어 평균 산출 (macro-단순 평균, weighted-많고 적음에 따라 가중 평균) 
  • classification_report: 각 클래스별 스코어 산출

1. 사용할 nifti 파일 불러오기(Ground Truth, Segmentation Result)

import nibabel as nib
import numpy as np

### nifti open
gt_nii = nib.load(gt_path)
res_nii = nib.load(res_path)

### flatten
gt_data = np.ravel(gt_nii.get_fdata())
res_data = np.ravel(res_nii.get_fdata())

 

2. f1_score 계산 

from sklearn.metrics import f1_score

### use f1_sgt_path, input_pathcore method in sklearn.metrics for calculating f1 score
f1 = f1_score(gt_data, res_data, labels=range({num of classes}), average='weighted') # OR macro
print(f1)

 

3. 혹은 classification_report로 각 클래스별 스코어 계산

from sklearn.metrics import f1_score, classification_report

f1 = classification_report(gt_data, res_data, labels=range({num of classes}), output_dict=True)
print(f1)

 

Output이 Dictionary Type으로 리턴되는데, Pandas Library를 사용하여 데이터프레임으로 만든 다음 저장할 수 있다.

+ support 부분은 각 클래스의 실제 갯수 카운팅한 결과값, accuracy와 마찬가지로 필요하지 않아 제거하였음

++ Dictionary Type으로 리턴된 결과값의 index가 0, 1, 2,... 등의 값으로 표시되는데 이름 바꿔주려고 class_list로 변경

++ pop() 메소드..시간 뺏기기도 싫고 귀찮아서 그냥 꼼수썼는데 다른 방법이 있지 않을까 싶다?

import pandas as pd

f1.pop('accuracy') # remove accuracy part(no needed)

class_list = ["Class1", "Class2", "Class3", "Class4", "Class5"]
avg_dict = {"macro avg": "Average (Macro)", "weighted avg": "Average (Weighted)"}

### not necessary
for i in range(5): f1[class_list[i]] = f1.pop(str(i))
for j in avg_dict.keys(): f1[avg_dict[j]] = f1.pop(j)

### dict to json or csv(pandas.dataframe format) > save
df = pd.DataFrame.from_dict(f1, orient="index")
df = df.drop(['support'], axis=1) # remove support part(no needed)

### save dataframe as CSV file to the output path
df.to_csv(output_path, encoding='UTF-8')

### Output sample ###
                    precision    recall  f1-score
Class1               0.984853  0.987019  0.985934
Class2               0.906874  0.873714  0.889986
Class3               0.953823  0.967866  0.960793
Class4               0.939222  0.945311  0.942257
Class5               0.915214  0.902075  0.908597
Average (Macro)      0.939997  0.935197  0.937513
Average (Weighted)   0.970451  0.970622  0.970515

'공부기록 > Python' 카테고리의 다른 글

Left-Right Flip Method 구현  (0) 2023.05.26
[tkinter] 간단 예제  (0) 2018.10.09