빠르게 살펴보기 :: Python을 이용한 추천 시스템 - mindscale
Skip to content

빠르게 살펴보기

예제 데이터 불러오기

from surprise import Dataset

예제로 내장된 무비렌즈(MovieLens) 데이터를 불러온다. 최초로 불러올 때 데이터를 다운로드 받을 것인지 물어보는데, 이때 Y를 입력한다.

data = Dataset.load_builtin('ml-100k')

데이터의 형태는 아래와 같다. 순서대로 사용자ID, 상품ID, 평점, 그리고 시간을 나타낸다.

data.raw_ratings[:10]
[('196', '242', 3.0, '881250949'),
 ('186', '302', 3.0, '891717742'),
 ('22', '377', 1.0, '878887116'),
 ('244', '51', 2.0, '880606923'),
 ('166', '346', 1.0, '886397596'),
 ('298', '474', 4.0, '884182806'),
 ('115', '265', 2.0, '881171488'),
 ('253', '465', 5.0, '891628467'),
 ('305', '451', 3.0, '886324817'),
 ('6', '86', 3.0, '883603013')]

파일에서 데이터 불러오기

데이터를 파일에서 불러올 수도 있다. 데이터 다운로드

from surprise import Reader
import pandas as pd

판다스를 이용해서 데이터를 연다.

df = pd.read_csv('ml-100k.zip')
df.head()
user_id item_id rating timestamp
0 196 242 3.0 881250949
1 186 302 3.0 891717742
2 22 377 1.0 878887116
3 244 51 2.0 880606923
4 166 346 1.0 886397596

평점의 범위를 지정한다. 이 데이터는 1~5점 범위이다.

reader = Reader(rating_scale=(1, 5))

데이터에서 필요한 컬럼을 추출한다. 컬럼 순서는 사용자ID, 상품ID, 평점 순이어야 한다.

col = ['user_id', 'item_id', 'rating']
df = df[col]

데이터를 surpriseDataset 형식으로 변환한다.

data = Dataset.load_from_df(df, reader)

데이터 분할

데이터를 학습용과 훈련용으로 분할한다.

from surprise.model_selection import train_test_split
trainset, testset = train_test_split(data, test_size=.2, random_state=42)

학습

surprise는 다양한 알고리즘을 지원한다. SVD를 사용해서 데이터를 학습한다.

from surprise import SVD

algo = SVD()
algo.fit(trainset)
<surprise.prediction_algorithms.matrix_factorization.SVD at 0x20350112748>

테스트

학습된 알고리즘을 통해 예측을 한다.

pred = algo.test(testset)

uid는 사용자ID, iid는 상품ID, r_ui는 실제 평점, est는 예측된 평점을 나타낸다.

pred[0]
Prediction(uid=907, iid=143, r_ui=5.0, est=5, details={'was_impossible': False})

실제 평점과 예측된 평점의 차이를 RMSE로 측정한다. RMSE는 오차(E)를 제곱(S)해서 평균(M)낸 값의 제곱근(R)이다. RMSE가 작을 수록 예측이 잘 된 것이다.

from surprise import accuracy
accuracy.rmse(pred)
RMSE: 0.9361
0.9361445421978951

평점 예측

사용자의 평점을 예측해본다. 사용자ID 196번, 상품ID 302번의 평점을 예측해본다. ID는 문자열로 변환해서 입력해야 한다.

uid = str(196)
iid = str(302)

pred = algo.predict(uid, iid)

예측된 평점은 다음과 같다.

pred.est
3.5318875