개발/머신러닝

파이썬 머신러닝 - Item based collaborative filtering recommend system (pivot, corr 이용)

웅'jk 2023. 1. 3. 12:59

추천 시스템을 만드는 방법 중에서 Item 기반으로한 추천 방법을 만들어보겠습니다.

 

1. 제작에 필요한 라이브러리를 import 

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

from google.colab import drive
drive.mount('/content/drive')

 - 구글 코랩으로 만들기 때문에 드라이브 연동부분은 패스 하셔도 상관없습니다. 

 

2. 데이터를 읽어옵니다. (csv)

movie_titles_df = pd.read_csv('Movie_Id_Titles.csv')

movies_rating_df = pd.read_csv('u.data', sep='\t' , names = [ 'user_id', 'item_id', 'rating', 'timestamp'] )

 - u.data 는 컬럼명이 없이 있는 파일이기에 컬럼명을 지정해 읽어옵니다. 

 

3. 데이터를 파악합니다.

좌) movie_titles_df 우) movies_rating_df

4. 필요없는 컬럼은 삭제하고 두개의 데이터 프레임을 하나로 만듭니다.

movies_rating_df=movies_rating_df.drop('timestamp' , axis = 1)

movies_rating_df = pd.merge(movie_titles_df , movies_rating_df , on = 'item_id' , how = 'left')

 

5. pivot 을 이용해 콜라보레이티브 필터링을 만듭니다.

df = movies_rating_df.pivot_table(index = 'user_id' , columns = 'title', values = 'rating')

corr_movie = df.corr(min_periods=80)

 - 여기서 min_periods 속성은 데이터의 최소수 를 의미합니다. 따라서 지금과 같은 경우에는 각 컬럼별로 80개 이상의 데이터가 있으면 사용한다는 뜻입니다.

 

6.  내 별점 정보 데이터를 가져옵니다

myRatings = pd.read_csv('My_Ratings.csv')

 

7. 내 별점과 영화의 상관계수를 통해 가중치를 만들어 그 가중치로 정렬합니다.

similar_movies_list = pd.DataFrame()

for i in range(myRatings['Movie Name'].shape[0]) :
  movie_title = myRatings['Movie Name'][i]
  recom_movies=corr_movie[movie_title].dropna().sort_values(ascending = False).to_frame()
  recom_movies.columns=['correlation']
  recom_movies['correlation'] * myRatings['Ratings'][i]
  recom_movies['weight']= recom_movies['correlation'] * myRatings['Ratings'][0]
  similar_movies_list = similar_movies_list.append(recom_movies)
  
similar_movies_list=similar_movies_list.sort_values('weight',ascending = False)

8. 만들어진 데이터에서 필요없는 데이터를 처리합니다.

# 내가본 영화 제외
drop_index_list=myRatings['Movie Name'].to_list()

for name in drop_index_list : 
  if name in similar_movies_list.index :
    similar_movies_list.drop(name , axis = 0 , inplace = True)
    
# 중복된 영화는 가중치가 높은 것만 보여준다.
similar_movies_list.reset_index()['title'].value_counts()
similar_movies_list.groupby('title')['weight'].max().sort_values(ascending = False)