3강 컨텐츠 기반 모델
Intoduction
컨텐츠 기반 모델은 상관관계를 통해 유사성을 발견하고 추천을 하는 방법에서 조금 벗어나 컨텐츠 사이의 유사도를 기반으로 추천을 해주는 모델입니다. 예를 들어 아이언맨 영화를 재밌게 본 사람에게 이와 비슷한 영화인 어벤져스나 마블시리즈 영화를 추천해 주는 방식이죠. 이러한 방식은 새로운 아이템이나 평가가 적은 아이템에 적용하기 좋습니다.
Word2Vec
word2vec모델은 기존에 자연어 처리를 위해 만들어진 모델입니다. 앞 뒤 단어를 통해 단어를 저차원의 벡터로 임베딩하는 방식이죠. 여기서 단어를 아이템으로 바꾸게 되면 인접한 아이템들을 통해 아이템을 벡터화할 수 있습니다. 구글play에서는 이와 같은 내용을 Item2vec이라는 모델로 소개하였습니다.
CBOW
Word2Vec모델 중 하나인 CBOW모델은 주변 단어들을 통해 중심 단어를 예측하는 모델입니다. 주변 단어들의 개수를 window size라고 부르고 window를 계속 옮겨 가며 학습을 진행합니다.
위의 그림에서 w(t)가 중심 단어이고 나머지 w(t-2) ~ w(t+2)까지가 주변 단어입니다. 각각의 주변단어에 대해서 같은 작업을 반복해 주고 평균을 내기 때문에 하나의 주변 단어를 기준으로 모델에 대해 알아보겠습니다.
위의 그림은 하나의 주변 단어에 대한 모델의 세부적인 구조입니다. 총 세개의 layer가 있고 2개의 가중치 벡터가 존재합니다. Input layer에는 one-hot 인코딩 방식으로 만들어진 단어 벡터가 들어옵니다. x는 v차원의 벡터이고 첫번째 가중치 벡터와의 연산을 통해 N차원의 벡터로 변환됩니다. N차원의 벡터는 다시 가중치와의 연산을 통해 v차원의 벡터로 변하게 됩니다.
위의 확률을 최대화 하는 것이 이 모델의 목적입니다.
hidden layer에 속하는 벡터들을 위와 같이 표현할 수 있습니다.
output layer에 속하는 벡터들은 hidden layer벡터에 W’가중치를 곱한 형태입니다.
softmax함수를 이용해 정규화를 해줍니다.
마지막으로 크로스 엔트로피를 사용하여 loss값을 구합니다.
크로스 엔트로피를 사용해서 구한 loss값과 역전파 방법을 통해 파라미터를 수정하며 오차를 줄여나갑니다. optimization 방법으로는 SGD를 사용합니다.
Word2vec 추천시스템 구현
#필요한 라이브러리 불러오기
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
import gensim
Python
복사
#경로설정하기
path_meta = "./drive/MyDrive/machine_learning/movies_metadata.csv"
path_ratings = "./drive/MyDrive/machine_learning/ratings.csv"
Python
복사
#판다스를 이용해 데이터 불러오기, 데이터 정렬
movie = pd.read_csv(path_ratings)
movie = movie.sort_values(by='timestamp', ascending=True).reset_index(drop=True)
Python
복사
#데이터 전처리, column이름을 바꾸고 데이터 병합
meta = pd.read_csv(path_meta)
meta = meta.rename(columns={'id':'movieId'})
movie['movieId'] = movie['movieId'].astype(str)
meta['movieId'] = meta['movieId'].astype(str)
movie = pd.merge(movie, meta[['movieId', 'original_title']], how='left', on='movieId'
Python
복사
movie = movie[movie['original_title'].notnull()].reset_index(drop=True)
Python
복사
#userId를 기준으로 묶어주기
agg = movie.groupby(['userId'])['original_title'].agg({'unique'})
agg.head()
Python
복사
#각각의 user가 본 영화끼리 묶어서 저장하기
sentence = []
for user_sentence in agg['unique'].values:
sentence.append(list(map(str, user_sentence)))
Python
복사
#word2vec 모델 학습
from gensim.models import Word2Vec
embedding_model = Word2Vec(sentence, size=20, window = 5,
min_count=1, workers=4, iter=200, sg=1)
Python
복사
#결과확인
embedding_model.wv.most_similar(positive=['The Phantom of the Opera'], topn=10)
Python
복사