끄적이는 기록일지

[머신러닝] 04.지도학습-분류_(3) 분류 평가 지표 본문

AI실무

[머신러닝] 04.지도학습-분류_(3) 분류 평가 지표

시시나브로 2021. 10. 3. 02:47
728x90
 

[머신러닝] 04.지도학습-분류_(2) 의사결정나무-불순도

[머신러닝] 04.지도학습-분류_(1) 분류란 [머신러닝] 03.지도학습-회귀_(1) 회귀 아이스크림 가게를 운영한다고 가정하면 지금까지 판 데이터를 가지고 우리는 예상되는 아이스크림 판매량만 주문

kcy51156.tistory.com

1. 혼동 행렬(Confusion Matrix) - 분류 모델의 성능을 평가

- TP : 실제 Positive 인 값을 Positive 라고 예측(정답)

- TN : 실제 Negative 인 값을 Negative 라고 예측(정답)

- FP : 실제 Negative 인 값을 Positive 라고 예측(오답) – 1형 오류

- FN : 실제 Positive 인 값을 Negative 라고 예측(오답) – 2형 오류

2.  정확도(Accuracy)

- 전체 데이터 중에서 제대로 분류된 데이터의 비율로, 모델이 얼마나 정확하게 분류하는지를 나타낸다.

- 일반적으로 분류 모델의 주요 평가 방법으로 사용

- 그러나, 클래스 비율이 불균형 할 경우 평가 지표의 신뢰성을 잃을 가능성이 있음

3. 정밀도(Precision)

- 모델이 Positive라고 분류한 데이터 중에서 실제로 Positive인 데이터의 비율

- Negative가 중요한 경우 즉, 실제로 Negative인 데이터를 Positive라고 판단하면 안되는 경우 사용되는 지표

ex) 스팸 메일 판결을 위한 분류 문제

해당 메일이 스팸일 경우 Positive, 스팸이 아닐 경우 즉, 일반 메일일 경우 Negative

일반 메일을 스팸 메일(Positive)로 잘못 예측했을 경우 중요한 메일을 전달받지 못하는 상황이 발생할 수 있다.

                                                                                                                                                                

4. 재현율(Recall, TPR)

- 실제로 Positive인 데이터 중에서 모델이 Positive로 분류한 데이터의 비율

- Positive가 중요한 경우 즉, 실제로 Positive인 데이터를 Negative라고 판단하면 안되는 경우 사용되는 지표

ex) 악성 종양 여부 판결을 위한 검사

  악성 종양일 경우 Positive, 악성 종양이 아닐 경우 즉, 양성 종양일 경우 Negative

  악성 종양(Positive)을 양성 종양(Negative)으로 잘못 예측했을 경우 제 때 치료를 받지 못하게 되어 생명이 위급해질 수 있다.

5. 다양한 분류 지표의 활용

분류 목적에 따라 다양한 지표를 계산하여 평가

- 분류 결과를 전체적으로 보고 싶다면 → 혼동 행렬(Confusion Matrix) 

- 정답을 얼마나 잘 맞췄는지 → 정확도(Accuracy) 

- FP 또는 FN의 중요도가 높다면 → 정밀도(Precision), 재현율(Recall)

 

6. 실습

혼동 행렬(Confusion matrix) - 유방암 판단
2개의 클래스를 가진 분류 데이터를 이용하여 혼동 행렬을 직접 출력해보고,확인해보도록 하겠습니다.

1. confusion_matrix를 사용하여 test_Y에 대한 confusion matrix를 계산하여 cm에 저장해봅시다.

import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from sklearn.datasets import load_breast_cancer # 유방암 유무 판별 데이터를 불러오는 함수
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn import tree
from sklearn.metrics import confusion_matrix
from sklearn.utils.multiclass import unique_labels

"""
 6. sklearn에 저장된 데이터를 불러 옵니다.
 X(Feature 데이터) : 30개의 환자 데이터
 Y(Label 데이터) : 0 음성(악성), 1 양성(정상)
"""
X, Y = load_breast_cancer(return_X_y = True)
X = np.array(X)
Y = np.array(Y)

# 데이터 정보를 출력합니다
print('전체 샘플 개수: ',len(X))
print('X의 feature 개수: ',len(X[0]))

# 학습용 평가용 데이터로 분리합니다
train_X, test_X, train_Y, test_Y = train_test_split(X, Y, test_size=0.2, random_state = 42)

# 분리된 데이터 정보를 출력합니다
print('학습용 샘플 개수: ',len(train_Y))
print('클래스 0인 학습용 샘플 개수: ',len(train_Y)-sum(train_Y))
print('클래스 1인 학습용 샘플 개수: ',sum(train_Y),'\n')

print('평가용 샘플 개수: ',len(test_Y))
print('클래스 0인 평가용 샘플 개수: ',len(test_Y)-sum(test_Y)) # 음성
print('클래스 1인 평가용 샘플 개수: ',sum(test_Y),'\n') #양성

# DTmodel에 의사결정나무 모델을 초기화 하고 학습합니다
DTmodel = DecisionTreeClassifier()
DTmodel.fit(train_X, train_Y)

# test_X을 바탕으로 예측한 값을 저장합니다
y_pred = DTmodel.predict(test_X)

"""
1.혼동 행렬을 계산합니다
* confusion_matrix(y_true, y_pred) : 혼동 행렬을 위한 사이킷런 함수
"""
cm = confusion_matrix(test_Y, y_pred)
print('Confusion Matrix : \n {}'.format(cm))

# 혼동 행렬을 출력합니다
fig = plt.figure(figsize=(5,5))
ax = sns.heatmap(cm, annot=True)
ax.set(title='Confusion Matrix',
            ylabel='True label',
            xlabel='Predicted label')
fig.savefig("decistion_tree.png")



>>> 전체 샘플 개수:  569
X의 feature 개수:  30
학습용 샘플 개수:  455
클래스 0인 학습용 샘플 개수:  169
클래스 1인 학습용 샘플 개수:  286 

평가용 샘플 개수:  114
클래스 0인 평가용 샘플 개수:  43
클래스 1인 평가용 샘플 개수:  71 

Confusion Matrix : 
 [[40  3]
 [ 3 68]]

정확도(Accuracy) 계산하기
1. score를 사용하여 train_X에 대한 정확도를 계산하여 acc_train에 저장해봅시다.
2. score를 사용하여 test_X에 대한 정확도를 계산하여 acc_test에 저장해봅시다.

import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn import tree
from sklearn.metrics import confusion_matrix
from sklearn.utils.multiclass import unique_labels


# sklearn에 저장된 데이터를 불러 옵니다.
X, Y = load_breast_cancer(return_X_y = True)
X = np.array(X)
Y = np.array(Y)

# 학습용 평가용 데이터로 분리합니다
train_X, test_X, train_Y, test_Y = train_test_split(X, Y, test_size=0.2, random_state = 42)

# 분리된 데이터 정보를 출력합니다
print('학습용 샘플 개수: ',len(train_Y))
print('클래스 0인 학습용 샘플 개수: ',len(train_Y)-sum(train_Y))
print('클래스 1인 학습용 샘플 개수: ',sum(train_Y),'\n')

print('평가용 샘플 개수: ',len(test_Y))
print('클래스 0인 평가용 샘플 개수: ',len(test_Y)-sum(test_Y))
print('클래스 1인 평가용 샘플 개수: ',sum(test_Y),'\n')

# DTmodel에 의사결정나무 모델을 초기화 하고 학습합니다
DTmodel = DecisionTreeClassifier()
DTmodel.fit(train_X, train_Y)


# 예측한 값을 저장합니다
y_pred_train = DTmodel.predict(train_X)
y_pred_test = DTmodel.predict(test_X)

# 혼동 행렬을 계산합니다
cm_train = confusion_matrix(train_Y, y_pred_train)
cm_test = confusion_matrix(test_Y, y_pred_test)
print('train_X Confusion Matrix : \n {}'.format(cm_train))
print('test_X Confusion Matrix : \n {}'.format(cm_test))

"""
1. 정확도를 계산합니다.
"""
# accuracy_score(Y_true, Y_pred) 이용하여 구할 수도 있음
acc_train = DTmodel.score(train_X, train_Y)
# acc_train = accuracy_score(Y_true, Y_pred_train)
acc_test = DTmodel.score(test_X, test_Y)
#acc_test = accuracy_score(Y_true, Y_pred_test)

# 정확도를 출력합니다.
print('train_X Accuracy: %f' % (acc_train))
print('test_X Accuracy: %f' % (acc_test))



>>> 학습용 샘플 개수:  455
클래스 0인 학습용 샘플 개수:  169
클래스 1인 학습용 샘플 개수:  286 

평가용 샘플 개수:  114
클래스 0인 평가용 샘플 개수:  43
클래스 1인 평가용 샘플 개수:  71 

train_X Confusion Matrix : 
 [[169   0]
 [  0 286]]
test_X Confusion Matrix : 
 [[40  3]
 [ 3 68]]
train_X Accuracy: 1.000000
test_X Accuracy: 0.947368

정밀도(Precision), 재현율(Recall) 계산하기 - 유방암 판단

1. precision_score를 사용하여 학습용, 평가용 데이터에 대한 정밀도를 계산하여 precision_train, precision_test에 저장해봅시다.
2. recall_score를 사용하여학습용, 평가용 데이터에 대한 재현율을 계산하여 recall_train, recall_test에 저장해봅시다.

import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from sklearn.datasets import load_breast_cancer # 유방암 유무 판별 데이터를 불러오는 함수
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn import tree
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score


"""
 sklearn에 저장된 데이터를 불러 옵니다.
 X(Feature 데이터) : 30개의 환자 데이터
 Y(Label 데이터) : 0 음성(악성), 1 양성(정상)

"""
X, Y = load_breast_cancer(return_X_y = True)
X = np.array(X)
Y = np.array(Y)

# 학습용 평가용 데이터로 분리합니다
train_X, test_X, train_Y, test_Y = train_test_split(X, Y, test_size=0.2, random_state = 42)

# DTmodel에 의사결정나무 모델을 초기화 하고 학습합니다
DTmodel = DecisionTreeClassifier()
DTmodel.fit(train_X, train_Y)


# 예측한 값을 저장합니다
y_pred_train = DTmodel.predict(train_X)
y_pred_test = DTmodel.predict(test_X)

# 혼동 행렬을 계산합니다
cm_train = confusion_matrix(train_Y, y_pred_train)
cm_test = confusion_matrix(test_Y, y_pred_test)
print('train_X Confusion Matrix : \n {}'.format(cm_train))
print('test_X Confusion Matrix : \n {}'.format(cm_test),'\n')

"""
1. 정밀도를 계산합니다.
* precision_score(train_Y, y_pred_train)
: 학습용 데이터에 대한 정밀도(precision) 값을 계산합니다.
"""
precision_train = precision_score(train_Y, y_pred_train)
precision_test = precision_score(test_Y, y_pred_test)

# 정밀도를 출력합니다.
print('train_X Precision: %f' % (precision_train))
print('test_X Precision: %f' % (precision_test),'\n')

"""
2. 재현율을 계산합니다.
* recall_score(train_Y, y_pred_train)
: 학습용 데이터에 대한 재현율(recall) 값을 계산합니다.
"""
recall_train = recall_score(train_Y, y_pred_train)
recall_test = recall_score(test_Y, y_pred_test)

# 재현율을 출력합니다.
print('train_X Recall: %f' % (recall_train))
print('test_X Recall: %f' % (recall_test))



>>> train_X Confusion Matrix : 
 [[169   0]
 [  0 286]]
test_X Confusion Matrix : 
 [[39  4]
 [ 3 68]] 

train_X Precision: 1.000000
test_X Precision: 0.944444 

train_X Recall: 1.000000
test_X Recall: 0.957746

- 학습용은 다 맞았기 때문에 1로 나오고 평가용은 약간 벗어난 것을 확인할 수 있다.

728x90
Comments