캐글 스터디 1주차 평가지표

3 minute read

슬라이드1

“데이터가 뛰어노는 AI놀이터, 캐글” 참고하여 스터디를 진행하였고 책을 바탕으로 발표용 ppt를 만들었습니다.

문제가 있을 시 댓글 남겨주시거나 이메일 totoma3@naver.com 으로 연락주시기 바랍니다!

import numpy as np
import pandas as pd

슬라이드3

RMSE 코드

from sklearn.metrics import mean_squared_error

# y_true는 실젯값이고, y_pred는 예측값이다.
y_true = [1.0, 1.5, 2.0, 1.2, 1.8]
y_pred = [0.8, 1.5, 1.8, 1.3, 3.0]

#RMSE는 MSE에 루트를 씌운것이다.
rmse = np.sqrt(mean_squared_error(y_true, y_pred))
print(rmse)
#값으로 0.5531726674375732이 나온다.

슬라이드6

슬라이드7

슬라이드8

슬라이드9

혼동행렬 코드

from sklearn.metrics import confusion_matrix

# 0, 1로 표현되는 이진 분류의 실젯값과 예측값
y_true = [1, 0, 1, 1, 0, 1, 1, 0]
y_pred = [0, 0, 1, 1, 0, 0, 1, 1]

tp = np.sum((np.array(y_true) == 1) & (np.array(y_pred) == 1))
tn = np.sum((np.array(y_true) == 0) & (np.array(y_pred) == 0))
fp = np.sum((np.array(y_true) == 0) & (np.array(y_pred) == 1))
fn = np.sum((np.array(y_true) == 1) & (np.array(y_pred) == 0))

confusion_matrix1 = np.array([[tp, fp],
                              [fn, tn]])

print(confusion_matrix1)
#여기서의 결과로부터 TP는 3, FP는 1, FN은 2, TN은 2임을 알 수있다.
#[[3 1]
# [2 2]]

슬라이드11

정확도 코드

from sklearn.metrics import accuracy_score

# 0, 1로 표현되는 이진 분류의 실젯값과 예측값
y_true = [1, 0, 1, 1, 0, 1, 1, 0]
y_pred = [0, 0, 1, 1, 0, 0, 1, 1]
accuracy = accuracy_score(y_true, y_pred)
print(accuracy)
#0.625

슬라이드12

슬라이드13

슬라이드14

슬라이드15

로그 손실 코드

from sklearn.metrics import log_loss

# 0, 1로 나타나는 이진 분류의 실젯값과 예측 확률
y_true = [1, 0, 1, 1, 0, 1]
y_prob = [0.1, 0.2, 0.8, 0.8, 0.1, 0.3]

logloss = log_loss(y_true, y_prob)
print(logloss)
#0.7135581778200728
#다중 클래스 분류(로그 로스)
from sklearn.metrics import log_loss

# 3 클래스 분류의 실젯값과 예측값
y_true = np.array([0, 2, 1, 2, 2])
y_pred = np.array([[0.68, 0.32, 0.00],
                   [0.00, 0.00, 1.00],
                   [0.60, 0.40, 0.00],
                   [0.00, 0.00, 1.00],
                   [0.28, 0.12, 0.60]])
logloss = log_loss(y_true, y_pred)
print(logloss)
#0.3625557672904274

슬라이드17 슬라이드18 슬라이드19 슬라이드21

다중 클래스 분류(mean_f1,macro_f1,micro_f1)

from sklearn.metrics import f1_score

# 다중 레이블 분류의 실젯값·예측값은 평가지표 계산상으로는 행 데이터 × 클래스의 두값 행렬로 해야 다루기 쉬움
# 실젯값 - [[1,2], [1], [1,2,3], [2,3], [3]]
y_true = np.array([[1, 1, 0],
                   [1, 0, 0],
                   [1, 1, 1],
                   [0, 1, 1],
                   [0, 0, 1]])

# 예측값 - [[1,3], [2], [1,3], [3], [3]]
y_pred = np.array([[1, 0, 1],
                   [0, 1, 0],
                   [1, 0, 1],
                   [0, 0, 1],
                   [0, 0, 1]])

# mean-f1는 행 데이터마다 F1-score를 계산하여 평균을 취함
mean_f1 = np.mean([f1_score(y_true[i, :], y_pred[i, :]) for i in range(len(y_true))])

# macro-f1에서는 행 데이터마다 F1-score를 계산하여 평균을 취함
n_class = 3
macro_f1 = np.mean([f1_score(y_true[:, c], y_pred[:, c]) for c in range(n_class)])

# micro-f1에서는 행 데이터 × 클래스의 쌍으로 TP/TN/FP/FN을 계산하여 F1-score를 구함
micro_f1 = f1_score(y_true.reshape(-1), y_pred.reshape(-1))

print(mean_f1, macro_f1, micro_f1)
# 0.5933, 0.5524, 0.6250

# scikit-learn 메소드를 사용하여 계산 가능
mean_f1 = f1_score(y_true, y_pred, average='samples')
macro_f1 = f1_score(y_true, y_pred, average='macro')
micro_f1 = f1_score(y_true, y_pred, average='micro')
print(mean_f1, macro_f1, micro_f1)

#0.5933333333333334 0.5523809523809523 0.6250000000000001
#0.5933333333333334 0.5523809523809523 0.6250000000000001

QWK(Quadratic weighted kappa)

슬라이드23

슬라이드24

Quadratic weighted kappa(클래스간 순서 관계가 있는 다중 클래스)

from sklearn.metrics import confusion_matrix, cohen_kappa_score

# quadratic weighted kappa을 계산하는 함수
def quadratic_weighted_kappa(c_matrix):
    numer = 0.0
    denom = 0.0

    for i in range(c_matrix.shape[0]):
        for j in range(c_matrix.shape[1]):
            n = c_matrix.shape[0]
            wij = ((i - j) ** 2.0) #실젯값과 예측값 차의 제곱             
            oij = c_matrix[i, j]   #실젯값의 클래스가 I, 예측값의 클래스가 j인 행 데이터 수
            eij = c_matrix[i, :].sum() * c_matrix[:, j].sum() / c_matrix.sum()
            #실제값이 i인 비율 X 예측값이 j인 비율 X 데이터 전체의 행 데이터 수
            numer += wij * oij  
            denom += wij * eij

    return 1.0 - numer / denom

# y_true는 실젯값 클래스 목록, y_pred는 예측값 클래스 목록
y_true = [1, 2, 3, 4, 3]
y_pred = [2, 2, 4, 4, 5]

# 혼동행렬을 계산
c_matrix = confusion_matrix(y_true, y_pred, labels=[1, 2, 3, 4, 5])

# quadratic weighted kappa를 계산
kappa = quadratic_weighted_kappa(c_matrix)
print(kappa)
# 0.6154 (소수점 5번째자리 반올림)

# scikit-learn의 메소드로도 계산 가능
kappa = cohen_kappa_score(y_true, y_pred, weights='quadratic')
print(kappa)
#0.6153846153846154
#0.6153846153846154

슬라이드26

MAP@K(Recommendation(추천))

# K=3、행의 수는 5개, 클래스는 4종류
K = 3

# 각 행의 실젯값
y_true = [[1, 2], [1, 2], [4], [1, 2, 3, 4], [3, 4]]

# 각 행에 대한 예측값 - K = 3이므로, 일반적으로 각 행에 각각 3개까지 순위를 매겨 예측
y_pred = [[1, 2, 4], [4, 1, 2], [1, 4, 3], [1, 2, 3], [1, 2, 4]]

# 각 행의 average precision을 계산하는 함수
def apk(y_i_true, y_i_pred):
    # y_pred가 K이하의 길이이고 모든 요소가 달라야 함
    assert (len(y_i_pred) <= K)
    assert (len(np.unique(y_i_pred)) == len(y_i_pred))

    sum_precision = 0.0
    num_hits = 0.0

    for i, p in enumerate(y_i_pred):
        if p in y_i_true:
            num_hits += 1
            precision = num_hits / (i + 1)
            sum_precision += precision

    return sum_precision / min(len(y_i_true), K)

# MAP@K을 계산하는 함수
def mapk(y_true, y_pred):
    return np.mean([apk(y_i_true, y_i_pred) for y_i_true, y_i_pred in zip(y_true, y_pred)])

# MAP@K을 요청
print(mapk(y_true, y_pred))
# 0.6499999999999999

# 정답 수가 같아도 순서가 다르면 점수도 다름
print(apk(y_true[0], y_pred[0]))
print(apk(y_true[1], y_pred[1]))
# 1.0
# 0.5833

Leave a comment