user based CF, item based CF

2022. 3. 22. 22:35AI/Deep learning

    목차
반응형

CF types

user based CF: 사용자를 기준으로 비슷한 취향의 이웃을 선정하는 방식
item based CF:

둘의 차이는 유사도를 계산하는 기준이 사용자인지 아이템인지에 따름
 

user-based CF

  • 사용자의 rating 정보가 많다면 정확한 추천이 가능
  • 그러나 터무니없는 추천을 하는 경우가 있음

item-based CF

  • 사용자별로 계산을 안해서 빠름
  • 터무니 없는 추천을 할 가능성이 낮음

데이터 크기가 적고 사용자에 대한 충분한 정보가 있다면 UBCF 사용
데이터가 크고 사용자에 대한 충분한 정보가 없는 경우 IBCF 사용

rating 정보가 풍부하다면 UBCF가 다소 정확함
IBCF는 계산이 빠르기에 아마존같이 대규모 데이터를 다뤄야 하는 상업용 사이트에서는 IBCF기반의 알고리즘을 사용했음
 

item-based CF 구현

data load 및 정제

 

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics.pairwise import cosine_similarity


u_cols = ['user_id', 'age', 'sex', 'occupation', 'zip_code']
users = pd.read_csv('u.user', sep='|', names=u_cols, encoding='latin-1')
i_cols = ['movie_id', 'title', 'release date', 'video release date', 'IMDB URL', 'unknown', 
          'Action', 'Adventure', 'Animation', 'Children\'s', 'Comedy', 'Crime', 'Documentary', 
          'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 
          'Thriller', 'War', 'Western']
movies = pd.read_csv('u.item', sep='|', names=i_cols, encoding='latin-1')
r_cols = ['user_id', 'movie_id', 'rating', 'timestamp']
ratings = pd.read_csv('u.data', sep='\t', names=r_cols, encoding='latin-1')

ratings = ratings.drop('timestamp', axis=1)
movies = movies[['movie_id', 'title']]

 

학습 데이터 split

 

x = ratings.copy()
y = ratings['user_id']
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, stratify=y)

 

method 정의


def RMSE(y_true, y_pred):
    return np.sqrt(np.mean((np.array(y_true) - np.array(y_pred))**2))


def score(model):
    id_pairs = zip(x_test['user_id'], x_test['movie_id'])
    y_pred = np.array([model(user, movie) for (user, movie) in id_pairs])
    y_true = np.array(x_test['rating'])
    return RMSE(y_true, y_pred)

 

rating matrix 생성

이번에는 rating_matrix를 transpose하여 colunm이 movie가 아닌 user가 되도록 함
row가 movie가 디어 movie의 유사도를 구하게 됨

 

rating_matrix = x_train.pivot(index='user_id', columns='movie_id', values='rating')

rating_matrix_t = np.transpose(rating_matrix)
matrix_dummy = rating_matrix_t.copy().fillna(0)
item_similarity = cosine_similarity(matrix_dummy, matrix_dummy)
item_similarity = pd.DataFrame(item_similarity, index=rating_matrix_t.index, columns=rating_matrix_t.index)

 

item_similarity

 

 

IBCF 정의

사용자가 평가하지 않은 영화들을 제거
사용자가 평가하지 않은 영화의 유사도 제거
-> user가 평가하지 않은 영화의 유사도는 버림

sim_scores = sim_scores.drop(non_rating_idx)

 

def CF_IBCF(user_id, movie_id):
    if movie_id not in item_similarity:      # 현재 영화가 train set에 있는지 확인
        return 3.0

    sim_scores = item_similarity[movie_id]
    user_rating = rating_matrix_t[user_id]

    non_rating_idx = user_rating[user_rating.isnull()].index
    user_rating = user_rating.dropna()
    sim_scores = sim_scores.drop(non_rating_idx)

    mean_rating = np.dot(sim_scores, user_rating) / sim_scores.sum()
    return mean_rating

 

score(CF_IBCF)
    1.011883734199702
반응형

'AI > Deep learning' 카테고리의 다른 글

Keras로 MF 구현  (0) 2022.05.15
역전파 (Back-propagation)  (0) 2022.03.06
Activation function(활성 함수)  (0) 2022.03.06
RNN(Recurrent Neural Network)  (0) 2022.03.06
seq2seq  (0) 2022.03.06