공공연히 개발하기 🧑‍💻/Machine Learning

[추천시스템] 성능 평가 지표 총정리 (정확도, 정밀도, 재현율, F1 Score, PR Cureve, ROC Curve, Precision/Recall@K, MAP@K, nDCG, Hit Rate@K)

공공연히 2024. 9. 7. 23:52

추천시스템의 성능을 명확하게 평가하기는 어렵다.
어느 정도의 정량적 평가는 가능하지만, 그것이 정답이라고 할 수는 없다.
사용자에 따라 주관적이며 도메인, 서비스, 목적성 등에 따라 기준이 달라질 수 있다.
하나의 Metric로 평가하기 보다, 여러 Metric를 통해 다각도에서 평가하는 것이 필요하다고 생각한다.

Table of Contents

1. 평가 지표
    - 비즈니스/서비스 관점
    - PV, CTR
2. 평가 방법
    - Offline Test
    - Online A/B Test
3. 성능 지표
    (1) 정확도, 정밀도, 재현율, F1 Score, PR Curve, ROC Curve
    (2) Precsion@K, Recalll@K, MAP, nDCG, Hit Rate
    (3) 평점 예측 방법과 손실 함수 (Cost Function) : RMSE, MAE

 

1. 평가 지표


비즈니스 / 서비스 관점

  • 추천 시스템 적용으로 인한 매출, PV의 증가
  • 새로운 추천 아이템으로 인한 유저의 CTR 상승

PV, CTR

  • PV(Page View): 홈페이지에 들어온 접속자가 둘러 본 페이지수.
    ex) 10명이 접속하여 10페이지씩 둘러봤다면 PV는 100
  • CTR (Click Through Rate): 쉽게 말해 클릭률. 광고가 노출되었을 때 얼마나 클릭을 했는가.
    • 일반적인 공식은 (클릭수/노출수)∗100
    • 예시) 추천상품이 100개 노출되었을 때 10번의 클릭이 일어났다면 CTR은 10%

 

2. 평가 과정


Offline Test

  • 새로운 추천 모델을 검증하기 위해 가장 먼저 필요한 단계
  • 이미 수집한 데이터를 Train,Valid,Test로 나누어 모델의 성능을 객관적인 지표로 평가
  • 보통 Offline Test에서 좋은 성능을 보여야 Online 서빙에 투입되지만,
  • 실제 서비스 상황에선 다양한 양상을 보임Serving Bias

Online A/B Test

  • Offline Test에서 검증된 가설이나 모델을 이용해 실제 추천 결과를 서빙하는 단계
  • 추천 시스템 변경 전후의 성능을 비교하는건이 아닌, 동시에 대조군A실험군B의 성능을 평가한다.
  • → 단, 대조군실험군의 환경은 동일해야 한다.
  • 실제 서비스를 통해 얻어지는 결과를 통해 최종 의사결정이 이뤄진다.
  • 대부분 현업에서 의사결정을 위해 사용하는 최종 지표는 모델 성능(RMSE, NDCG 등)이 아닌 매출, CTR 등의 비즈니스 / 서비스 지표

 

3. 성능 지표

(1) 정확도, 정밀도, 재현율, F1 Score, PR Curve, ROC Curve


▶️ 
Accuracy 정확도

  • 모델이 정확하게 분류한 비율 TP+TN/전체

▶️ Precision 정밀도

  • 모델이 참이라고 분류한 값 중에서 실제값이 참인 비율 TP/TP+FP
  • → 추천한 아이템 중 실제로 사용자가 관심을 보인 아이템의 비율

▶️ Recall 재현도(재현율)

  • 실제값이 참인 값 중에서 모델이 참이라고 분류한 비율 TP/TP+FN

▶️ F1 Score

  • 정밀도와 재현율의 조화 평균
  • 데이터가 불균형할 경우 사용
  • (2 * 정밀도 * 재현율) / (정밀도  +재현율)

정확도는 높을 수록 성능이 좋은 모델로 평가된다.

정밀도가 상대적으로 더 중요한 지표인 경우는
실제 Negative 음성인 데이터를 Positive 양성으로 잘못 판단하게 되면 업무상 영향이 큰 경우이다.
ex) 스팸메일분류

재현율이 상대적으로 더 중요한 지표인 경우는
실제 Positive 양성인 데이터를 Negative 음성으로 잘못 판단하게 되면 업무상 영향이 큰 경우이다.
ex) 독감, 암 양성 여부

정밀도재현율은 서로 반비례관계에 있다.
정밀도재현율은 모두 TP를 높이는 데에 초점을 맞추지만,
재현율FN을 낮추는 데에, 정밀도는 FP를 낮추는 데에 집중한다.
이러한 특성 때문에 정밀도재현율은 서로 보완적인 지표로 분류의 성능을 평가하는데 사용된다.

가장 좋은 결과는 정밀도와 재현율이 모두 높은 수치를 갖는 경우이다.
하지만 둘 중 하나라도 매우 낮은 결과를 나타낸다면 바람직하지 않다고 할 수 있다.

▶️ PR Curve 정밀도 재현율 곡선

from sklearn.metrics import plot_precision_recall_curve

fig, ax = plt.subplots()
for m in models:
    plot_precision_recall_curve(m, X_test, y_test, ax=ax)
ax.axhline(0.9, c='w', ls="--", lw=1, alpha=0.5)
ax.axvline(0.9, c='w', ls="--", lw=1, alpha=0.5)
ax.set_title("PR Curve")

https://cosmiccoding.com.au/tutorials/pr_vs_roc_curves/

 

▶️ ROC Curve 

from sklearn.metrics import plot_roc_curve

fig, ax = plt.subplots()
for m in models:
    plot_roc_curve(m, X_test, y_test, ax=ax)
ax.axhline(0.9, c='w', ls="--", lw=1, alpha=0.5)
ax.axvline(0.1, c='w', ls="--", lw=1, alpha=0.5)
ax.set_title("ROC Curve");

https://cosmiccoding.com.au/tutorials/pr_vs_roc_curves/

PR 곡선과 유사한 ROC 곡선은 모든 임계값에서 참 양성률(TPR)과 거짓 양성률(FPR)을 계산한 후,
FPR에 대한 TPR를 나타낸 곡선이다.
곡선이 좌상단에 붙을수록 높은 성능을 의미한다고 할 수 있다.

TPR은 recall(민감도)
FPR(폴아웃, 1 - TNR, 일명 1 - 특이도)는 총 거짓수에 대한 거짓 양성(거짓 양성 + 참 음성)

모든 실제 값 중 몇 개나 성공적으로 추천했는가
FPR은 거짓 양성으로 오염시킬 가능성 높다는 것을 의미한다.

(2) Precsion@K, Recalll@K, MAP, nDCG, Hit Rate

논문이나 A/B Test에서는 nDCG, Hit Rate를 자주 사용한다.

▶️ Precision/Recall@K

  • Precision@K : 정밀도. 추천한 아이템 K개 중에 실제 사용자가 관심있는 아이템의 비율
  • Recall@K : 재현율. 유저가 관심있는 전체 아이템 가운데 우리가 추천한 아이템의 비율
  • 순서를 고려하지 않음
  • 예시

- 추천 아이템 개수 : K = 5
- 추천 아이템 중 유저가 관심있는 아이템 개수 : 2
- 유저가 관심있는 아이템의 전체 개수 : 3
    → Precision@5 = 52, Recall@5 = 32

 

▶️ MAP (Mean Average Precision)@K

  • 성능 평가에 순서 개념을 도입한 것
  • 추천시스템의 경우 무엇을 앞에 나열했는지가 매우 중요함
  • 사용자가 관심을 더 많이 가질만한 아이템을 상위에 추천해 주는 것이 매우 중요

Average Precision

$$
AP@K = \frac{1}{m}\sum_{i=1}^KPrecision@i
$$

  • Precision@1부터 Precision@K 까지의 평균값을 의미
  • Precision@K와 다르게 연관성 있는 아이템을 더 높은 순위에 추천할 경우 점수가 상승

MAP

$$
MAP@K = \frac{1}{|U|}\sum_{u=1}^{|U|}(AP@K)_{u}
$$

  • 모든 유저에 대한 Average Precision 값의 평균 → 추천 시스템의 성능
  • MAP에서는 K라는 값을 설정. K는 추천리스트의 어디까지만 평가할 것인가 결정하는 index 값
  • 각 class 마다 한 AP를 갖게 되는데, 모든 class의 AP에 대해 평균값을 낸 것이 바로 mAP(mean AP)이다.
    즉, 모든 class에 대하여 Precision/Recall의 값을 avg취한 것이라고 볼 수 있다.

 

▶️ nDCG (Normalized Discounted Cumulative Gain)

  • 추천 시스템에 가장 많이 사용되는 지표 중 하나, 원래는 검색Information Retrieval에서 등장한 지표
  • Precision@K, MAP@K와 마찬가지로 Top K 추천 리스트를 만들고 유저가 선호하는 아이템을 비교하여 값을 구한다.
  • MAP는 관련 여부를 binary(0/1)로 평가하지만,
  • nDCG는 관련도 값을 사용할 수 있기 때문에, 유저에게 더 관련 있는 아이템을 상위로 노출시키는지 알 수 있다.
  • 랭킹 기반이므로, 랭킹에 민감하다. 순서에 가중치를 부여한다.
  • 관련성 높은 결과를 상위권에 노출시켰는 지를 기반으로 만들어야 한다.
  • 정보검색(Information Retrieval)에서 많이 사용되었음. (집합적인 정보로부터 원하는 내용과 관련이 있는 부분을 얻어 내는 행위)
  • Binary 변수도 계산 가능

Relevance Score, 관련성 점수

  • 사용자가 특정 아이템과 얼마나 관련이 있는지를 나타내는 값
  • Relevance 값은 정해진 것이 아니고 추천의 상황에 맞게 정해야 한다.
  • 해당 상품을 얼마나 클릭했는지, 혹은 클릭 여부 등 다양한 방법으로 선정 가능

CG (Cumulative Gain)

$$
CG_{p} = \sum_{i=1}^prel_{i}
$$

  • 상위 p개의 추천 결과들의 관련성(rel, relevance)의 누적합
  • 상위 p개의 추천 결과들을 모두 동일한 비율로 계산
  • rel은 단순히 binary value이거나 문제에 따라 세분화될 수 있음

DCG (Discounted Cumulative Gain)

$$
DCG_{p} = \sum_{i=1}^p\frac{rel_{i}}{log_{2}(i+1)}
$$

$$
DCG_{p} = \sum_{i=1}^p\frac{2^{rel_{i}}-1}{log_{2}(i+1)}
$$

  • 랭킹 순서에 따라 점점 비중을 줄여 rel 결과 계산
  • 로그함수를 분모로 두면
  • 하위권 결과에 패널티 주는 방식
  • 두 개의 수식 존재 rel이 binary value이면 두 식이 같아짐
  • 특정 순위까지는 discount를 하지 않는 방법 등의 다양한 변형식을 사용하기도 함
  • DCG는 p값이 다르면, DCG 값 자체로는 성능의 비교를 할 수 없음

nDCG (Normalized Discounted Cumulative Gain)

$$
nDCG_{p} = \frac{DCG_{p}}{IDCG_{p}}
$$

$$
IDCG_{p} = \sum_{i=1}^p\frac{rel_{i}^{opt}}{log_{2}(i+1)}
$$

  • DCGIDCG로 나눈 값. IDCG는 선택된 p개 결과로 가질 수 있는 가장 큰 DCG 값
  • NDCG 0~1사이의 값을 가지며 1에 가까울수록 우수한 성능을 가진 시스템으로 본다.
  • 기존의 DCG는 랭킹 결과의 길이 p에 따라 값이 많이 변함. p가 커질수록 누적합인 DCG는 커짐
  • p에 상관없이 일정 스케일의 값을 가지도록 normalize가 필요함
  • nDCG는 p값에 어느정도 독립적이며, 일정 범위의 작은 스케일을 갖게 된다.

nDCG그래프 Python code

# gt: key는 playlist id, value는 song list인 answer dic
# rec: key는 playlist id, value는 song list인 rec dic
# one_gt는 gt item 하나, one_rec는 rec item 하나
# score는 모든 플레이리스트 nDCG의 평균
# 100개 추천으로, idcg 구할때도 len(gt)이되 len(gt)>100인 경우 len(gt)=100으로 두고 계산

def ndcg(one_gt, one_rec):
  dcg = 0.0

  if len(one_gt) >= 100:
    idcg = sum((1.0/np.log(i+1) for i in range(1, 101)))

  else:
    idcg = sum((1.0/np.log(i+1) for i in range(1, len(one_gt)+1)))

  for i, r in enumerate(one_rec):
    if r in one_gt:
      dcg += 1.0/np.log(i+2)

  return dcg/idcg

## score = 모든 playlist의 ndcg를 평균한 값
score = sum(ndcg(gt[i], rec[i]) for i in rec.keys())/len(rec)

 

🔵 DCG와 nDCG 비교 그래프

  • DCG는 p값이 다르면, DCG 값 자체로는 성능의 비교를 할 수 없음

https://jo yae.github.io/2020-09-02-nDCG/

 

  • nDCGp값에 어느정도 독립적이며, 작은 스케일을 갖게됨

https://jo yae.github.io/2020-09-02-nDCG/

 

▶️ Hit Rate @K

$$
Hit \ Rate = \frac{no. \ of \ hit \ user}{no. \ of \ user}
$$

적중률

Leave-One-Out Cross-Validation

1. 특정 유저의 선호하거나 클릭했던 모든 Item을 가져온다.
2. 모든 Item가운데 하나만 의도적으로 제거한다.
3. 남은 Item들을 가지고 추천 모델을 학습한 뒤, Top K 추천 리스트를 추출
4. K개의 추천 리스트 가운데 아까 제거한 Item이 있다면 hit, 아니면 hit가 아니다.

'leave-one-out' 이 포함된 적중률은 매우 큰 데이터 세트를 가지고 있지 않는 한 측정하기가 매우 작고 어려운 경향이 있다.

ARHR (Average Reciprocal Hit Rate)

  • 평균 왕복 적중률
  • 측정 항목은 적중률과 비슷하지만 최상위 목록에서 조회수가 표시되는 위치를 설명하여 하단 슬롯보다 상단 슬롯의 항목을 성공적으로 추천하면 더 많은 크레딧을 얻게 된다.

Cumulative hit rate (cHR)

  • 누적 적중률
  • 목록에서 사용자가 찾아야 할 추천 사항이 너무 적은 경우
  • 일부 항목이 임계 값 미만인 경우 적중을 버리는 것

Rating hit rate (rHR)

 

(3) 평점 예측 방법과 손실 함수 (Cost Function) : RMSE, MAE

위의 성능 지표와는 달리 평점을 예측하는 '평점 예측' 평가 방법이다.
각 사용자의 아이템에 대한 예측 평점과, 정답 평점을 바탕으로 두 평점의 차이로 성능을 평가한다.

손실함수 (Cost Fucntion)는 예측 데이터와 실제 결과를 비교해 오차 정도를 표시하는 함수이다.
손실함수를 거쳐 오차(Error)가 적은 경로를 찾아가며 최종 모델을 완성시킨다.

사용자가 아이템에 대한 피드백을 남긴다. 이는 실제값이다.
학습한 모델의 학습 데이터에서 일부를 추출해 테스트 데이터셋을 설정한다. 이는 예측값이다.
테스트 데이터와 피드백 데이터를 비교하여 실제값을 얼마나 정확히 예측하는지를 통해 성능을 평가한다.

예측값과 실측값의 차이를 성능 지표로 표현하는 손실함수를 그린다. 

오차(Error)가 적을수록 추천 성능이 좋다고 평가할 수 있지만,
그러나 이를 통해 확인한 성능 지표가 높다고 해서 꼭 좋은 추천 결과를 내는 것은 아니다.

▶️ MAE (Mean Absolute Error)

  • 실제 평점과 예측 평점 간의 절대 오차의 평균
  • 직관적이고 해석이 용이하다.
  • 하지만 평균 계산이므로 오차가 큰 경우 등 이상치에 쉽게 영향을 받는다.
  • 1 미만의 오차는 더 작아지고 그 이상의 잔차는 더 커진다. (오차의 왜곡현상)

$$ \text{MSE}(y, \hat{y}) = \frac{\sum_{i=0}^{N - 1} (y_i - \hat{y}_i)^2}{N} $$


Python code

from numpy import array
from permetrics.regression import RegressionMetric

# For 1-D array
y_true = array([3, -0.5, 2, 7])
y_pred = array([2.5, 0.0, 2, 8])

evaluator = RegressionMetric(y_true, y_pred)
print(evaluator.mean_squared_error())

# For > 1-D array
y_true = array([[0.5, 1], [-1, 1], [7, -6]])
y_pred = array([[0, 2], [-1, 2], [8, -5]])

evaluator = RegressionMetric(y_true, y_pred)
print(evaluator.MSE(multi_output="raw_values"))

 

▶️ RMSE (Root Mean Square Error)

  • 실제 평점과 예측 평점 간의 절대 오차의 평균에 루트를 취한 것이다. 즉, MSE에 루트를 취한 것
  • MSE는 제곱을 하는 때문에 단위가 커진다. 루트를 적용해 스케일을 조정하는 역할을 한다.
  • 루트를 씌움으로써 실제값과 예측값이 유사한 단위를 가지도록 한다.
  • MSE의 오차 왜곡 현상을 완화시켜준다.
  • RMSE는 미분이 가능하기 때문에 모델 학습에도 많이 사용된다.

$$ \text{RMSE}(y, \hat{y}) = \sqrt{\frac{\sum_{i=0}^{N - 1} (y_i - \hat{y}_i)^2}{N}} $$


Python code

from numpy import array
from permetrics.regression import RegressionMetric

# For 1-D array
y_true = array([3, -0.5, 2, 7])
y_pred = array([2.5, 0.0, 2, 8])

evaluator = RegressionMetric(y_true, y_pred)
print(evaluator.root_mean_squared_error())

# For > 1-D array
y_true = array([[0.5, 1], [-1, 1], [7, -6]])
y_pred = array([[0, 2], [-1, 2], [8, -5]])

evaluator = RegressionMetric(y_true, y_pred)
print(evaluator.RMSE(multi_output="raw_values"))

 

<관련글>

2024.09.02 - [공공연히 개발하기 🧑‍💻/Machine Learning] - [추천시스템] 추천시스템 성능 평가 - 평가 지표 (mAP@K, nDCG 총정리)

 

[추천시스템] 추천시스템 성능 평가 - 평가 지표 (mAP@K, nDCG 총정리)

추천시스템, 추천 모델의 다양한 성능 평가 방법 중 mAP와 nDCG 평가 지표에 대해 알아보자.1. MAP@K- Precision, Recall- Cutoff (@K)- Average Precision (AP@K)- Mean Average Precision (MAP@K)2. nDCG- Relevance score, 관련성 점

imlookingformyjob.tistory.com

2024.09.06 - [공공연히 개발하기 🧑‍💻/Machine Learning] - [추천시스템] 추천알고리즘 선택 1 - 협업필터링(CF), 컨텐츠기반필터링(CB)

 

[추천시스템] 추천알고리즘 선택 1 - 협업필터링(CF), 컨텐츠기반필터링(CB)

추천시스템을 개발할 때 가장 중요한 부분은 무엇일까? 다양한 의견이 있겠지만, 추천의 기반이 되는 알고리즘, 추천모델의 선택은 신중하게 선택해야 하는 측면임은 분명하다.활용할 데이터의

imlookingformyjob.tistory.com

2024.09.05 - [공공연히 개발하기 🧑‍💻/Machine Learning] - [추천시스템] 그래프와 추천시스템 : 1. 그래프 이론의 기초

 

[추천시스템] 그래프와 추천시스템 : 1. 그래프 이론의 기초

Boost course의 강의 내용 정리>1. 그래프 이론의 기초1.1 그래프란 무엇이고 왜 중요할까     1.1.1 그래프란 무엇일까    1.1.2 그래프가 왜 중요할까?1.2 그래프 관련 인공지능 문제    - 정점 분류(No

imlookingformyjob.tistory.com

 

 

References