欲速不達

일을 급히 하고자 서두르면 도리어 이루지 못한다.

Fantastic AI, Fantastic World

DS | Data Science/RecSys | Recommendation System

[RecSys] kNN Collaborative Filtering : scikit-surprise 라이브러리 / MovieLens Data

_껀이_ 2022. 10. 14. 19:05
728x90
반응형

 

!pip install scikit-surprise

scikit-surprise 패키지는 Collaborative Filtering 관련 머신러닝 라이브러리이다. kNN 뿐만 아니라 MF 등의 알고리즘도 제공하지만 여기서는 kNN 알고리즘만 사용했다.

 

 

- Reader, Dataset

from surprise import Reader, Dataset

reader = Reader(rating_scale=(0.5, 5.0))
data = Dataset.load_from_df(ratings_df[['userId', 'movieId', 'rating']], reader)
 

 

- train_test_split

from surprise.model_selection import train_test_split

# train / test 데이터 나누기
train_data, test_data = train_test_split(data, test_size=0.2, random_state=10)

 

 

1. kNN Collaborative Filtering

  • k-Nearest Neighborhood 

  • user-based kNN

  • item-based kNN

 

 

 

2. Similarity

 

Using prediction algorithms — Surprise 1 documentation

© Copyright 2015, Nicolas Hug Revision c1de6b0e.

surprise.readthedocs.io

  1. 주어진 user-item rating에 대해
  2. user MSD Similarity
  3. item MSD Similarity

 

1) Mean Squared Difference Similarity

  • 주어진 user-item rating에 대해 
  • user MSD Similarity 

  • tem MSD Similarity

 

2) Cosine Similarity

  • 주어진 두 벡터 X, Y에 대하여

  • 두 벡터의 방향이 얼마나 유사한지의 정도
    • 1에 가까울수록 : 같은 방향
    • -1에 가까울수록 : 정반대 방향

 

3) Pearson Similarity

  • 주어진 두 벡터 X, Y에 대하여

  • 각 벡터를 표본평균으로 정규화 후 -> Cosine Sililarity를 계산한 결과값
    • (X와 Y의 동시 변화량) / (X와 Y의 각각의 변화량)
    • 1에 가까울수록 : + 상관관계
    • 0 : 독립
    • -1에 가까울수록 : - 상관관계

 

 

 

3. Cosine Similarity를 활용한 기본 kNN CF

- user based kNN CF model 생성

from surprise import accuracy      # 성능평가 라이브러리

sim_options = {
                'name': 'cosine',
                'user_based': True
              }

knn_basic = KNNBasic(k=40, min_k=10, sim_options=sim_options)

 

- 학습 후 예측

knn_basic.fit(train_data)
predictions = knn_basic.test(test_data)

 

- 성능평가

  • RMSE : Root Mean Squared Error

  • MSE : Mean Absolute Error

 

rmse = accuracy.rmse(predictions)       # 소수점 네자리수까지만 출력됨
mae = accuracy.mae(predictions)		

print("RMSE:", rmse)                    # 소수점 많이 출력됨
print("MAE:", mae)
RMSE: 0.9957
MAE:  0.7773
RMSE: 0.9957417139621522
MAE: 0.7772603323591643

 

  • cross_validate() : 다중 평가 지표 -> 여러가지 mesures를 한번에 사용할 수 있음
from surprise.model_selection.validation import cross_validate

user_based_cv_result = cross_validate(knn_basic, data, measures=['RMSE', 'MAE'], cv=5, verbose=True)

 

 

4. Grid Search

  • 사용자가 정한 몇 개의 하이퍼파라미터의 가능한 경우의 수를 비교
  • 하이퍼파라미터의 조합에 따라 모델의 성능차이를 계산하여 가장 우수한 결과값을 보이는 모델을 선택

 

- Surprise에서 제공하는 기능

  • kNN model with Means
    • 평점을 예측할 때, user의 평균 평점을 고려하여 예측하는 모델

  • kNN model with Z-score normalization
    • 평점을 예측할 때, item의 평점을 Z-score를 고려하여 예측하는 모델

 

 

5. Top K Recommendation 평가

  • user 별로 Top K Recommendation 결과를 생성 -> Precision, Recall, NDCG를 활용하여 성능 평가
  • user가 영화를 선호한다는 기준은 rating > 4.0이다.

 

주의점

- MovieLens 데이터는 Top K Recommendation으로 추천모델의 성능을 측정하기엔 적합하지 않다.

- 보통 Rating Prediction으로 추천 모델의 성능을 평가하기 때문에, Precision, Recall, ndcg 등의 성능이 굉장히 낮게 측정된다.

 

 

1) Precision@K / Recall@K / AP@K / MAP@K

def get_precision(relevant, recommend):
    
    _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)

def get_average_precision(relevant, recommend):
    
    _precisions = []
    
    for i in range(len(recommend)):
        _recommend = recommend[:i+1]
        _precisions.append(get_precision(relevant, _recommend))
    
    return np.mean(_precisions)

def get_ndcg(relevant_item, recommend_item):
    
    k = len(recommend_item)
    discount = np.log2(np.arange(k) + 2)
    cg = []
    for item in recommend_item:
        if item in relevant_item:
            cg.append(1)
        else:
            cg.append(0)

    dcg = np.sum(np.divide(cg, discount))
    
    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, discount))
        
    return dcg / idcg

 

2) 연산 과정

  • Cosine Similarity 활용하여 user based kNN CF 모델에 대한 Precision, Recall, MAP, NDCG @ K를 구한다.
    • train data에 있는 user-item 쌍에 대해 예측 평점을 구하여 dataframe으로 만든다.
  • 개별 user에 대해 추천을 진행하고 각 지표를 구한 뒤에 이를 합친다.
    • 전체 item 중에 train data에 있는 item을 제외한 나머지가 추천대상
  • 합쳐진 지표들을 각각 평균내어 최종 지표를 산출한다.

위의 연산과정에서 k=10일 때, 결과는 다음과 같다.

precision@10:  0.07632508833922262
recall@10:  0.07534757561910023
map@10:  0.0763750070110494
ndcg@10:  0.09475133544479197

 

 

 

6. Result

  • Grid Search에서 수행한 Offline Test의 결과를 바탕으로 모델을 선택
  • 실제 Production에 적용할 때는 train/test를 나누지 않고 지금까지 쌓인 모든 데이터를 가지고 학습하여 모델 생성

 

과정

  1. Grid Search에서 가장 높은 성능을 낸 모델로 생성
  2. 전체 데이터를 활용하여 학습데이터 생성 -> 학습
  3. 추천 결과 출력 : user에서 K개의 item 추천
    • 전체 영화중에서 해당 user가 이미 rating을 가진 경우를 제외
    • 예상 평점을 기준으로 상위 K개의 item을 추천

 

- 결과 예시

	movieId	predRating
3119	4564	5.0
5649	78620	5.0
5644	94959	5.0
5641	94953	5.0
5240	76301	5.0
3996	6345	5.0
5243	92694	5.0
558	714	5.0
4679	8254	5.0
4003	6368	5.0

 

 

 

 

 

출처 및 참고 자료 : 네이버커넥트 부스트캠프 AI_Tech 강의 자료, 실습 자료

728x90
반응형

'DS | Data Science > RecSys | Recommendation System' 카테고리의 다른 글

[RecSys] 한 눈에 보기 정리 - 2  (0) 2022.10.26
[RecSys] 한 눈에 보기 정리 - 1  (0) 2022.10.20
[RecSys] Basic - 3  (0) 2022.10.14
[RecSys] Basic - 2  (0) 2022.10.11
[RecSys] Basic - 1  (0) 2022.10.10