surprise 라이브러리를 이용한 협업필터링(Collaborative Filtering) 파이썬 치트코드

협업필터링은 생각보다 구현하기가 쉬운데도 불구하고 너무나도 훌륭한 라이브러리 또한 많이 존재합니다. 게다가, user-based, item-based 모두 유사도만 구하면 간단한 편이지만 희소행렬에서 임베딩을 적용해서 딥러닝을 하는 등의 시도를 해볼수 있기 때문에 발전가능성은 무궁무진 한듯 합니다.

cf

협업필터링(Collaborative Filtering) surprise라이브러리로 구현하기

협업필터링은 일반적인 memory(user, item) based 그리고 머신러닝을 이용해서 예측을 하는 model based의 필터링, 그리고 거기에 더해 희소행렬을 아예 임베딩등을 통해 차원을 변경해 여러 레이어로 구성된 딥러닝 필터링까지도 가능하다. 여기서는, surprise라이브러리로 구현이 가능함을 보인다.

In [17]:
import os

# 맥os의 경우 시도때도없이 다운되서 아래와 같이 넣어준다.
os.environ['KMP_DUPLICATE_LIB_OK']='True'

https://grouplens.org/datasets/movielens/ 에서 다운로드 가능하다.

In [18]:
import pandas as pd

ratings = pd.read_csv('ratings.csv') 
In [19]:
ratings.head()
Out[19]:
userId movieId rating timestamp
0 1 1 4.0 964982703
1 1 3 4.0 964981247
2 1 6 4.0 964982224
3 1 47 5.0 964983815
4 1 50 5.0 964982931
In [20]:
from surprise import Reader, Dataset

Scale만 지정해주고, 필요한 userId, movieId, rating에 대한 컬럼만 설정해주면 전부다.

In [22]:
reader = Reader(rating_scale=(0.5, 5.0))
data = Dataset.load_from_df(ratings[['userId', 'movieId', 'rating']], reader)

k-fold를 5로 나누고, 제일 높게 나온 알고리즘을 확인해보자. 현재로썬 KNNBasic 이 제일 높다. 사용할수 있는 로직이 많으니 하나하나 이용해본다.

In [24]:
# Split data into 5 folds

data.split(n_folds=5)

from surprise import SVD, evaluate
from surprise import NMF
from surprise import KNNBasic

# svd
algo = SVD()
evaluate(algo, data, measures=['RMSE'])

# nmf
algo = NMF()
evaluate(algo, data, measures=['RMSE'])

algo = KNNBasic()
evaluate(algo, data, measures=['RMSE'])
/Users/kohry/anaconda3/lib/python3.7/site-packages/surprise/evaluate.py:66: UserWarning: The evaluate() method is deprecated. Please use model_selection.cross_validate() instead.
  'model_selection.cross_validate() instead.', UserWarning)
/Users/kohry/anaconda3/lib/python3.7/site-packages/surprise/dataset.py:193: UserWarning: Using data.split() or using load_from_folds() without using a CV iterator is now deprecated. 
  UserWarning)
Evaluating RMSE of algorithm SVD.

------------
Fold 1
RMSE: 0.8669
------------
Fold 2
RMSE: 0.8728
------------
Fold 3
RMSE: 0.8688
------------
Fold 4
RMSE: 0.8811
------------
Fold 5
RMSE: 0.8764
------------
------------
Mean RMSE: 0.8732
------------
------------
Evaluating RMSE of algorithm NMF.

------------
Fold 1
RMSE: 0.9153
------------
Fold 2
RMSE: 0.9241
------------
Fold 3
RMSE: 0.9180
------------
Fold 4
RMSE: 0.9280
------------
Fold 5
RMSE: 0.9283
------------
------------
Mean RMSE: 0.9227
------------
------------
Evaluating RMSE of algorithm KNNBasic.

------------
Fold 1
Computing the msd similarity matrix...
Done computing similarity matrix.
RMSE: 0.9429
------------
Fold 2
Computing the msd similarity matrix...
Done computing similarity matrix.
RMSE: 0.9485
------------
Fold 3
Computing the msd similarity matrix...
Done computing similarity matrix.
RMSE: 0.9475
------------
Fold 4
Computing the msd similarity matrix...
Done computing similarity matrix.
RMSE: 0.9524
------------
Fold 5
Computing the msd similarity matrix...
Done computing similarity matrix.
RMSE: 0.9499
------------
------------
Mean RMSE: 0.9483
------------
------------
Out[24]:
CaseInsensitiveDefaultDict(list,
                           {'rmse': [0.942911713411438,
                             0.9485301804275947,
                             0.947508109130864,
                             0.952380019464324,
                             0.9499200019514455]})

fastai를 이용한 라이브러리 이용도 가능하다. 생각보다 정확도가 높지는 않으나, 추후 딥러닝을 통해 정확도 개선을 이뤄볼수도 있다.

In [26]:
from fastai.collab import * 
In [28]:
data = CollabDataBunch.from_df(ratings)
In [29]:
learn = collab_learner(data, n_factors=50, y_range=[0, 5.5])
learn.fit_one_cycle(5, 5e-3)
epoch train_loss valid_loss time
0 0.802808 0.805747 00:08
1 0.665075 0.733431 00:11
2 0.451940 0.738080 00:11
3 0.265611 0.747300 00:10
4 0.153321 0.751794 00:10

답글 남기기