Data/ML & DL

[Colab] 추천시스템 implicit 라이브러리 성능 평가

sennysideup 2024. 1. 19. 09:11
반응형

현재 마무리 중인 프로젝트에서 추천시스템 task를 맡았습니다. 오늘은 implicit 라이브러리를 활용하여 추천시스템을 구축하고, 성능을 검증하는 방법을 알아보려고 합니다. 튜토리얼 코드에 성능 평가 코드가 없어서 조금 헤맸던 기억이 있네요.

 

이전 포스팅

  • BPR 논문 리뷰
 

[논문 리뷰] BPR : bayesian personalized ranking from implicit feedback

논문 : https://arxiv.org/abs/1205.2618 더보기 오역, 오류 등은 댓글로 말씀 부탁드립니다! 문제 상황 상품 추천 : 선호도 기반 사용자 맞춤형 ranking 계산 선호도 : 과거 구매 기록 및 열람 기록을 통해 계

lifeofsw.tistory.com

  • implicit 라이브러리로 bpr 구현하기
 

[논문 코드] BPR 코드 적용 with implicit

implicit 라이브러리를 활용해서 BPR 방법을 적용한 MF 모델의 성능을 확인하는 코드입니다. Implicit 라이브러리 공식 문서 http://Recommendation Models — Implicit 0.6.1 documentation (benfred.github.io) 공식 코드 htt

lifeofsw.tistory.com

 

성능 평가 지표

implicit 라이브러리 사용 시 precision, map, ndcg, auc를 확인할 수 있습니다.

precision, map, auc는 object detection에서도 사용되는 지표라서 익숙하지만, ndcg는 추천시스템에 특화된 평가 지표입니다.

ndcg를 계산하는 과정은 아래와 같습니다.

  1. 모델이 예측한 추천 목록을 사용자의 선호도(평점 등) 순으로 정렬
  2. 각 상품의 선호도 점수와 순위에 따라 가중치를 부여하여 최종 점수를 계산
  3. 최종 점수가 0~1 사이의 값을 가지도록 정규화

 

하이퍼 파라미터 튜닝

implicit 라이브러리에서는 하이퍼 파라미터 튜닝을 위한 함수가 따로 없습니다.

그래서 반복문으로 그리드 서치와 비슷하게 성능을 평가할 수 있도록 구현했습니다.

# 하이퍼 파라미터 튜닝을 위한 딕셔너리 생성
params = {"factors": [5,10,15],
          "regularization": [0.001, 0.005, 0.01],
          "iterations" : [20, 30, 40]}

# 튜닝 결과 저장할 리스트
factors = []
regularization = []
iterations = []
ndcg_result = []
precision_result = []

k = 0
for f in params["factors"]:
  k += 1
  print(k)
  for r in params["regularization"]:
      for i in params["iterations"]:
        # 모델 학습
        als = AlternatingLeastSquares(factors = f, regularization= r,
                            iterations= i, random_state = 42, num_threads = 1)
        als.fit(train)
        # 성능 평가
        metrics = ranking_metrics_at_k(als, train, test, K=10, show_progress=False)
        ndcg = metrics['ndcg']
        precision = metrics['precision']
        # 결과 저장
        factors.append(f)
        regularization.append(r)
        iterations.append(i)
        ndcg_result.append(ndcg)
        precision_result.append(precision)
        
# 튜닝 결과를 데이터 프레임으로 저장
result = pd.DataFrame({"factors":factors, "regularization":regularization,
                      "iterations": iterations, "ndcg":ndcg_result, "precision" : precision_result})

print("NDCG 기준 최적 파라미터 - ALS")
print(result.sort_values(by = "ndcg", ascending = False).head(1))
print("Precision 기준 최적 파라미터 - ALS")
print(result.sort_values(by = "precision", ascending = False).head(1))

위 코드를 실행하면 ndcg를 기준으로 최적인 파라미터와 precision을 기준으로 최적인 파라미터를 확인하실 수 있습니다.

 

Code

from implicit.evaluation import *

# train test split
train, test = train_test_split(user_play_movies, train_percentage = 0.8, random_state = 42)

# 모델 학습
bpr = BayesianPersonalizedRanking(factors = 20, regularization=0.001,
                                  learning_rate = 0.05, iterations=20, random_state = 42)
bpr.fit(train)

# 성능 평가
metrics = ranking_metrics_at_k(bpr, train, test, K=10, show_progress=False)
print("BPR model score")
print("precision :", metrics['precision'])
print("map :", metrics['map'])
print("ndcg :", metrics['ndcg'])
print("auc :", metrics['auc'])

성능 평가 코드는 위와 같습니다.

movielens 데이터를 활용해서 als와 bpr 모델을 각각 학습시키고, 성능을 비교한 결과는 아래와 같습니다.

모든 평가 지표에서 BPR보다 ALS가 더 좋은 성능을 보이고 있습니다.

BPR이 ALS 이후에 나온 모델인데도 이런 성능이 나타나는 것은 데이터의 특성과 모델의 목적때문이 아닐까 생각됩니다.

학습에 사용된 movielens 는 explicit feedback이고, BPR은 implicit feedback에 최적화된 모델이기 때문입니다.

 

전체 코드는 아래 링크에서 확인하실 수 있습니다. 전체 코드에는 로컬 파일을 사용하는 방법이 포함되어 있습니다.

 

implicit evaluation.ipynb

Colaboratory notebook

colab.research.google.com