추천시스템의 평가 지표

JISU LIM·2023년 4월 9일

Recommended System

목록 보기
1/6
post-thumbnail

추천 시스템의 평가 지표

Offline Test

Offline Test란

  • 새로운 추천 모델을 검증하기 위해 가장 우선적으로 수행되는 단계이다.
    • 유저로부터 수집한 데이터를 train/valid/test로 나누어 모델의 성능을 객관적인 지표로 평가한다.
  • 이에 사용되는 성능 지표는 랭킹 문제와 예측 문제에 따라 다르게 사용될 수 있다.
    • 랭킹 문제 : Precision@K, Recall@K, MAP@K, NDCG@K, HitRate
    • 예측 문제 : RMSE, MAE

Precision/Recall @K

Pricision@K

  • 유저에게 추천한 K개의 아이템 중 실제 유저가 관심 있는 아이템의 비율이다.
  • 5개의 아이템을 유저에게 추천했을 때 5개의 아이템 중 유저가 관심있는 아이템이 2개라면 precision@5=2/5{\text precision@5} = 2/5로 계산할 수 있다.

Recall@K

  • 유저가 관심있는 아이템 중 유저에게 추천한 아이템의 비율이다.
  • 마찬가지로 5개의 아이템을 유저에게 추천했고, 유저가 관심 있는 아이템이 3개 있을 때 그 중 유저에게 추천한 아이템이 2개라면 recall@5=2/3recall@5 = 2/3으로 계산할 수 있다.

🧑‍💻 code

def get_precision(relevant, recommend):
    # 추천한 K개 아이템 가운데 실제 사용자가 관심 있는 아이템 비율
    _intersection = set(recommend).intersection(set(relevant))
    return len(_intersection) / len(recommend)

def get_recall(relevant, recommend):
    # 사용자가 관심 있는 전체 아이템 가운데 추천한 아이템 비율
    _intersection = set(recommend).intersection(set(relevant))
    return len(_intersection) / len(relevant)

Mean Average Precision(MAP)@K

AP@K

  • Precision@1부터 Precision@K까지의 평균값을 의미한다.
  • 관련 아이템을 더 높은 순위에 추천할 수록 AP@K 점수가 높아지는 특징이 있다.

AP@K=1mi=1KPrecision@iAP@K = {\frac {1} {m}}\sum^K_{i=1}Precision@i

MAP@K

  • 모든 유저에 대한 Average Precision 값을 평균해준 값이다.

MAP@K=1Uu=1U(AP@K)uMAP@K = {\frac {1} {|U|}}\sum^{|U|}_{u=1}\left(AP@K\right)_u

🧑‍💻 코드

def get_average_precision(relevant, recommend):
    # Precision@1부터 Precision@K까지의 평균값
    _precisions = []
    
    for i in range(len(recommend)):
        _recommend = recommend[:i+1]
        _precisions.append(get_precision(relevant, _recommend))
    
    return np.mean(_precisions)

Nomalized Discounted Cumulative Gain(NDCG)

NDCG란

  • 검색(Information Retrieval)에서 등장한 지표로, 추천 시스템에 가장 많이 사용되는 지표 중 하나이다.
  • Precision@K, MAP@K와 마찬가지로 Top K 리스트를 만들고 유저가 선호하는 아이템을 이용해 값을 구하는 방식이며, MAP@K와 마찬가지로 추천 순서에 가중치를 더 많이 두어 평가한다.
  • 값이 1에 가까울 수록 좋다.

NDCG Formula

  • Cumulative Gain
    • 상위 K개 아이템에 대하여 관련도를 단순히 합한 것이다.

    • CGk=i=1KreliCG_k = \sum^K_{i=1}{\text rel}_i

      cg_lst = [1 if item in relevant_item else 0 for item in recommentd_item]
      cg = np.sum(cg_lst)
  • Discounted Cumulative Gain
    • 순서에 따라 Cumulative Gain을 Discount한 것이다.

    • DCGK=i=1Krelilog2(i+1)DCG_K = \sum^K_{i=1}{\frac {\text rel_i} {\log_2\left(i+1\right)}}

    • 나중에 추천될 수록 로그 항의 값이 커져 전체 값이 Discount된다.

      dcg_lst = np.divide(cg_lst, np.log2(np.arange(k) + 2))
      dcg = np.sum(dcg_lst)
  • Ideal DCG
    • 이상적인 추천이 일어났을 때의 DCG 값이다. 사용자가 어떤 아이템을 선호하는지 모두 알고있다고 가정해야 알 수 있는 값이며, 당연히 가능한 DCG 값 중에 가장 큰 값이다.

    • IDCG=i=1Krelioptlog2(i+1)IDCG = \sum^K_{i=1}{\frac {{\text rel}^{\text opt}_i} {\log_2\left(i+1\right)}}

      # 이상적인(선호하는 아이템을 먼저 추천) 상황 cg 값을 구함
      k_for_icg = min(k, len(relevant_item))
      icg = np.zeros(k)
      for i in range(k_for_icg):
          icg[i] += 1
      
      idcg = np.sum(np.divide(icg, np.log2(np.arange(k) + 2))
  • Normalized DCG
    • 추천 결과에 따라 구해진 DCG를 IDCG로 나눈 값이다.

    • NDCG=DCGIDCGNDCG = {\frac {DCG} {IDCG}}

      ndcg = dcg/idcg
profile
Grow Exponentially

0개의 댓글