캡쳐 사진 및 글작성에 대한 도움 출저 : 유튜브 - 허민석님


Confusion Matrix

머신러닝이 얼마나 잘 예측하는지를 나타내주는 Matrix가 바로 Confusion Matrix이다.


예를 들어, 만들어진 머신러닝 모델에
A를 입력하였더니, A라고 판단했다. 아래 테이블에 input A에 대한 output A가 1로 찍힌다.

image


이번에는 B가 조금 희미하게 input되었더니, 우리의 머신러닝 모델은 D라고 판단했다.
이 때는 input B에 대한 output D칼럼에 1이 찍힌다.
image


다음으로 C, D는 잘 판단하여 각각 (C,C) (D,D)에 1이 들어갔다.

imageimage


이번에는 희미한 D를 input하였는데도, D라고 잘 판단했다.
(D,D)는 +1이 된 2가 들어갔다.

image



이렇게 찍은 테이블이 바로 Confusion Matrix이다.
input A에 대해서는 전체 1개 중에 1개를 A로 잘 맞추었다. C와 D역시 전체 1개, 2개 중에 전부 잘 맞추었다.
반면 input B에 대하여 전체 2개의 input가운데, 1개는 잘 맞추었지만, 다른 1개는 잘못판단하였다.

이렇게 머신이 잘맞추었는지, 혼동은 없었는지 판단하는 matrix가 바로 confusion matrix인 것이다.
image


데이터 사이언스에서는 눈으로 보이는 혼동이외에, 조금더 과학적인 방법으로 성능을 확인할 수 있다.
그 종류로는

  1. Accuracy
  2. Precision
  3. Recall
  4. F1 score

등등 이 있다.


실습




4. Confusion matrix
In [16]:
import seaborn as snsimport pandas as pdimport matplotlib.pyplot as plt%matplotlib inlinesns.set(font_scale=2) # 혼동행렬 폰트 크기! 1이면 너무 작다.

1. 혼동없는 혼동행렬 만들기

In [18]:
# array로 행렬만들기 -> df에 넣으면서 인덱스+칼럼명 주기 -> heatmaparray = [    [5, 0, 0, 0],    [0, 10, 0, 0],    [0, 0, 15, 0],    [0, 0, 0, 5],]#인덱스와 컬럼을 문자열--> 리스트로 인식되어서 하나씩 입력되도록df_cm= pd.DataFrame(array,                   index = [ i for i in "ABCD"],                    columns=[i for i in 'ABCD']                   )#맷플롯립으로는 figure 사이즈와 타이틀 정하기plt.figure(figsize=(10, 7)) # 7, 7 주면 정사각형이 안된다. 옆에 게이지 때문에 더 줘야함plt.title('confusion matrix without confusion')#시본으로 df를 히트맵으로 만들기sns.heatmap(df_cm, annot=True) # annot 옵션이 각 cell안에 숫자를 나타내게 한다.
Out[18]:
<matplotlib.axes._subplots.AxesSubplot at 0x2bc302f6a90>

2. 혼동이 있는 혼동행렬 만들기

In [40]:
array = [    [9, 1, 0, 0],    [1, 15, 3, 1],    [5, 0, 24, 1],    [0, 4, 1, 15],]df_cm= pd.DataFrame(array,                   index = [ i for i in "ABCD"],                    columns=[i for i in 'ABCD']                   )plt.figure(figsize=(10, 7))plt.title('confusion matrix without confusion')sns.heatmap(df_cm, annot=True)
Out[40]:
<matplotlib.axes._subplots.AxesSubplot at 0x2bc314cf208>

대각선이 밝은색위주로 되어있으니, 나름대로 잘 작동을 하는 모델임을 판단한다

하지만 Normalization 하지 않았기 때문에, 어떤 input에 대해 효과적인지 쉽게 대답할 수 없다.

3. Normalization한 혼동행렬 만들기

  • 각 A,B,C,D의 input되는 갯수가 다르기 때문에 어느것이 정확도가 더 좋은지 제대로 알아보기 힘들다.

3-1. 노멀리제이션 먼저 하기

In [41]:
import numpy as npfrom numpy import linalg as LA
In [42]:
# 1. 혼동행렬(array상태)의 가로방향별로  각 input별 합을 구한다.total = np.sum(array, axis=1)total
Out[42]:
array([10, 20, 30, 20])
In [43]:
total[:, None]
Out[43]:
array([[10],       [20],       [30],       [20]])
  1. 각 칼럼별 합을 나누는데, 그냥 나누면 안된다array = array / totalarray
In [44]:
# 2. 각 input의 총 갯수를 None인덱싱한 total을 이용하여,  ( total [ : , None])#    각 예측값의 합 [10,20,30,20] 을 칼럼이 없도록 행으로 세운다#    [10],#    [20],#    [30],#    [20],#    이를 통해, 가로별 합을 가로별로 나눌 수 있게 된다. 그러면 가로별 총 합은 1이 될 것이다.array = array / total[:,None]array
Out[44]:
array([[0.9       , 0.1       , 0.        , 0.        ],       [0.05      , 0.75      , 0.15      , 0.05      ],       [0.16666667, 0.        , 0.8       , 0.03333333],       [0.        , 0.2       , 0.05      , 0.75      ]])

3-2. Normalization된 array로 히트맵 그리기

In [45]:
df_cm= pd.DataFrame(array,                   index = [ i for i in "ABCD"],                    columns=[i for i in 'ABCD']                   )plt.figure(figsize=(10, 7))plt.title('confusion matrix without confusion')sns.heatmap(df_cm, annot=True)
Out[45]:
<matplotlib.axes._subplots.AxesSubplot at 0x2bc3155c6d8>

이제 대각선이 각각 input별로 몇퍼센트를 맞추었는지 알 수 있다.


+ Recent posts