지난 시간에는 추천 시스템의 정의, 종류 등을 살펴보았습니다.
이번 포스팅은 추천 시스템 종류 중 콘텐츠 기반 추천 시스템(content-based, CB)에 대해서 얘기를 나눠볼려고 합니다.
Content-based filtering
content-based filtering이라고도 불리는 CB는 사용자의 구매 이력을 통해 이와 비슷한 카테고리의 제품을 추천하는 방법을 의미합니다.
CB의 특징은 다음과 같습니다.
- 독립적 정보 활용
- 추천 대상 사용자의 과거 구매이력이나 profile 정보만 이용하기 때문에 CF처럼 다른 사용자의 정보가 부족할 경우에도 유용하게 쓰일수 있습니다.
- 위의 특징은 다시 말해 사용자의 정보가 부족하다면 성능이 낮아지거나 존재하지 않는다면 구현이 불가능하다는 뜻과 같습니다
- First rater
- First rater: 평가가 되지 않은 상품들은 추천 리스트에 포함될 수 없는 문제
- CB는 아이템에 대한 평가 점수가 존재하지 않더라도 유사도가 높은 카테고리의 아이템들이 추천되기 때문에 First rater 문제가 발생하지 않습니다.
- Over fitting
- 앞의 특징에서 비롯된 단점으로, 다른 카테고리의 제품들이 추천되기 어렵기 때문에 비슷한 상품들만 추천된다는 문제점을 지니고 있습니다.
Python code
CB를 python으로 간단하게 구현하기 위해 데이터를 불러오겠습니다.
※ 사용한 데이터는 캐글에서 다운받으실 수 있습니다.
movies = pd.read_csv('/content/drive/MyDrive/archive/tmdb_5000_movies.csv')
movies_df = movies[['id','title', 'genres', 'vote_average', 'vote_count',
'popularity', 'keywords', 'overview']]
movies_df = movies_df.drop_duplicates(['title'])
print(movies_df.shape)
movies_df.head()
위의 데이터를 확인했을 때 CB의 개념을 구현할 수 있는 방법을 생각해보면 다음과 같은 과정이 나올수 있습니다.
- genres 변수를 통해 영화 간 유사도를 도출한다.
- 사용자가 시청한 영화중 유사도가 높은 영화 순으로 추천
이러한 기준으로 코딩 하는 법을 알아보겠습니다.
먼저, genre 데이터에 대해 좀 더 살펴 보겠습니다.
pd.set_option('max_colwidth', 200)
print(type(movies_df["genres"].iloc[0]))
movies_df[["genres"]]
위의 사진과 같이 딕셔너리 형태로 데이터가 형성되어 있습니다. 또한 type은 문자열로 되어 있어 이를 list로 변환해주는 작업이 필요합니다.
from ast import literal_eval
movies_df['genres'] = movies_df['genres'].apply(literal_eval)
pd.set_option('max_colwidth', 200)
print(type(movies_df["genres"].iloc[0]))
movies_df[["genres"]]
list로 잘 변환된것을 알 수 있습니다.
이제 유사도를 구하는 과정입니다. 이번 실습에서는 코사인 유사도를 사용했는데 다른 유사도와 비교해서 성능이 좋은 metric으로 사용하시면 됩니다.
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
movies_df['genres'] = movies_df['genres'].apply(lambda x : [ y['name'] for y in x])
count_vect = CountVectorizer(min_df=0, ngram_range=(1,2))
genre_mat = count_vect.fit_transform(movies_df['genres_literal'])
genre_sim = cosine_similarity(genre_mat, genre_mat)
print(genre_sim.shape)
print(genre_sim[:2])
다음으로는 특정 영화를 본 사용자에게 비슷한 영화를 추천하는 함수를 위의 유사도를 통해서 간단하게 구현해보도록 하겠습니다.
def recommend_list(df, title, sim,top_n=10):
title_index = df[df['title'] == title].index
df["sim"] = sim[:, index]
df = df.drop(index, axis = 0).sort_values("sim", ascending = False).iloc[:top_n, :][["title", "genres", "keywords", "overview"]]
return df
위의 알고리즘은 단순합니다.
- 제공된 영화 제목의 위치를 가져온다.
- 해당 영화의 유사도 정보를 원래의 데이터 프레임에 추가(index하기 위함입니다.)
- 지정된 영화 index 부분의 유사도를 제외하고 내림차순으로 정렬
- 상위 10개의 영화 리스트를 도출
함수를 지정하고 예시로 Point Blank라는 영화를 넣어보았을때의 결과는 아래의 사진과 같습니다.
recommend_list(movies_df, "Point Blank", genre_sim)
이번 시간에는 콘텐츠 기반 추천 시스템(Content-based recommender system, CB)의 개념과 파이썬 구현 코드에 대해 알아보았습니다. 위의 코드는 정말 간단하게 나타낸 코드이고 좀 더 섬세하게 표현하기 위해서는 다양한 개념들이 필요합니다. 하지만 위의 코드의 틀에서 크게 바뀌지 않으니 의미 있는 내용들을 추가하며 공부해 나가면 좋을것 같습니다.
포스팅 내용 중 다른 생각이 있는 분 혹은 수정해야할 부분이 있으시면 댓글을 통해 그 의견을 나눠보면 너무 좋을 것 같습니다.
'reommender system' 카테고리의 다른 글
[추천 시스템#3] 협업 필터링(Collaborative filtering) 개요 (0) | 2023.05.08 |
---|---|
[추천 시스템#1] 추천 시스템이란? (0) | 2023.04.25 |