본문 바로가기
추천시스템

컨텐츠 기반 추천(Content Based Filtering)

by 장찐 2022. 1. 10.

📚Content Based Filtering 개념 

✅ 기본 개념 

TONDJI, L. N. (2018). Web recommender system for job seeking and recruiting.  Partial Fulfillment of a Masters II at AIMS .

 IBCF는 특정 컨텐츠에 대해서 다른 유저들이 남긴 평점을 기반으로 유사도를 계산해서 추천을 진행하지만, 내용 기반 추천은 해당 컨텐츠의 내용 자체의 유사도로 추천하는 방식이다. 일반적인 단계는 다음과 같다. 

 

1. 아이템 간의 유사도를 계산한다. 

2. 추천 대상이 되는 사용자가 선호하는 아이템을 선정

3. 2번 단계에서 선정된 아이템과 가장 유사도가 높은 N개의 아이템을 찾는다. 

4. 찾은 N개의 아이템을 사용자에게 추천한다. 

 

위 과정에서 몇 가지 유의해야 할 부분들이 있다. 1.에서 아이템 간의 유사도를 사용하는 지표는 여러가지가 존재한다. 텍스트 데이터의 경우 TF-IDF와 같은 방법을 사용할 수 있다.

또한 2.에서 사용자가 좋게 평가한 아이템을 몇 개를 선정할 것인지도 고려해야 한다. 여러 개의 아이템을 선택할 경우 최종 추천 단계에서 사용자에게 어떤 상품을 걸러서 보여줄 지 고민해야 한다. 

 

컨텐츠 기반 추천의 장단점은 다음과 같다. 

장점
-컨텐츠가 중요한 도메인에서는 정확도가 높다 

-실질적으로 사용자들의 평점을 얻기가 쉽지 않은데, 내용 기반 추천은 평점이 없는 경우에도 추천이 가능하다 
 
단점 
-컨텐츠의 특성 만으로 추천하는 것이기 때문에 사용자에 대한 정보가 포함되지 않는다. 
 즉, 개별 고객의 특성이나 취향이 반영되지 않는다. 
→ 사용자들의 특성이 중요한 도메인에서는 CF가 더 정확함 

-상품의 특성만을 이용해서 과거에 긍정 평가를 한 상품과 비슷한 상품을 추천하기 때문에
특정 상품군이나 카테고리에 치우친 추천이 반복될 확률이 높다. 

 


📚 실습 (1) : 영화 줄거리 기반 추천시스템 

영화의 Tagline, Description을 사용하여 유사한 plot description을 가진 영화를 추천

 

영화에 대한 메타데이터를 포함하고 있는 데이터를 불러온다. 

 

 

#데이터 불러오기 
import pandas as pd
movies = pd.read_csv(r'C:\Users\Yeong\Desktop\추천시스템 강의\W6\movies_metadata.csv', encoding='latin-1', low_memory=False)
movies = movies[['id', 'title', 'overview']]
movies = movies.drop_duplicates()

#결측치 제거 
movies = movies.dropna()
movies['overview'] = movies['overview'].fillna('')

movielens 데이터셋에서 메타 데이터를 포함하고 있는 데이터를 불러온다.

 

 

# TfIdfVectorizer 가져오기
from sklearn.feature_extraction.text import TfidfVectorizer

# 불용어 설정 
tfidf = TfidfVectorizer(stop_words='english')

#tfidf 매트릭스 계산 
tfidf_matrix = tfidf.fit_transform(movies['overview'])

줄거리 변수를 사용해서 각 영화별 TF-IDF를 계산한다. 사이킷런에 포함된 패키지를 사용하고 영어 불용어를 제거한다. 

 

# 코사인 유사도 계산
from sklearn.metrics.pairwise import cosine_similarity
cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)

#판다스 시리즈로 변경
cosine_sim = pd.DataFrame(cosine_sim, index=movies.index, columns=movies.index)

# index가 영화 이름이고, 데이터로 해당 영화의 id가 들어간 형태로 변경 
indices = pd.Series(movies.index, index=movies['title'])

TF-IDF의 코사인 유사도를 계산하고 판다스 시리즈 형태로 변경한다. 넘파이 array 상태로는 최종 추천 결과를 보여줄 때 직관적이지 않기 때문. 그리고 indices 객체에 인덱스가 영화 이름, 데이터 값이 영화 id 가 들어간 형태로 저장한다. 

 

 

# 영화추천 함수 
def content_recommender(title, n_of_recomm):
    # title에서 영화 index 받아오기
    idx = indices[title]
    
    # 주어진 영화와 다른 영화의 similarity를 가져온다
    sim_scores = cosine_sim[idx]
    
    # similarity 기준으로 정렬하고 n_of_recomm만큼 가져오기
    sim_scores = sim_scores.sort_values(ascending=False)[1:n_of_recomm+1]
    
    # 영화 title 반환
    return movies.loc[sim_scores.index]['title']

영화 제목과 추천할 영화 수를 입력하는 함수를 지정한다. 차례대로 n_of_recomm 개의 영화를 추천할 때, 유사도가 가장 높게 나타나는 자기 자신은 제외하고 인덱싱 한다. 

 

print(content_recommender('The Dark Knight Rises', 20))

다크나이트 라이즈와 유사한 영화를 추천받은 결과를 보면, 주로 배트맨 관련 시리즈인 것을 알 수 있다. 

 

 

 


 

📚 Reference 

•  "Python을 이용한 개인화 추천시스템", 임일, 청람

 

댓글