추천 시스템 개요 및 이론, Baseline Code

I. 개요
- 대고객 대상으로 한 대부분의 플랫폼 서비스 업체들은 고객 개개인에게 맞춤형의 추천 서비스를 도입하고 있음
- 전자상거래 업체, 유투브, 애플 뮤직 등
- ML의 여러 알고리즘 중 비즈니스 관점에 부합하는 기법이 추천 시스템.
- 추천 시스템의 진정한 묘미는 사용자 본인도 모르는 취향 발견, 재구매로 연결하도록 설계
- 누가 필요할까?
- 모든 플랫폼 서비스
- 이유1: 플랫폼은 다수의 판매자와 소비자를 필요로 함, 문제는 카테고리와 메뉴구성이 복잡해지면 소비자의 제품 선택에 부작용
- 이유2: 만족도가 떨어지면 고객은 그 플랫폼을 떠날 가능성이 크며, 이는 플랫폼 서비스의 매출 하락과 직결
- 모든 플랫폼 서비스는 기본적으로 추천서비스를 장착하고 싶어함
- 영화 데이터를 기준으로 추천시스템을 단계별로 구현함을 목표로 함
II. 추천시스템의 유형 및 역사
- 추천시스템의 유형과 간단한 역사에 대해 배워보도록 한다.
(1) 유형
- 크게 세가지로 구분됨.
- Demographic Filtering
- 콘텐츠 기반 필터링 (Content Filtering)
- 협업 필터링 (Collaborative Filtering)
- 최근접 이웃(Nearest Neighbor)
- 잠재 요인(Latent Factor)
(2) 역사
- 초창기: 콘텐츠 기반 필터링 또는 최근접 이웃 기반 협업 필터링이 주로 사용됨.
- 중기: 넷플릭스 추천 시스템 경연 대회에서 행렬 분해 (Matrix Factorization) 기법을 이용한 잠재요인 협업 필터링 방식으로 우승한 뒤, 유명해짐.
- 최근: 개인화 특성을 강화하기 위해서 하이브리드 형식으로 콘텐츠 기반과 협업 기반을 적절히 결합해 사용하는 경우도 늘고 있음
III. Demographic Filtering
- 가장 기초적이면서
Simple한 추천시스템 방식 - 같은 영화를 인구통계학에 기반하여 각 사용자에게 추천
- 그런데, 영화추천 시, 주로 인기도가 높은 대중적인 영화 위주 (예를 들면 Top 250개)만 선별하여 각 사용자에게 전달. 대중적인 영화들은 영화를 보지 않는 다른 일반 관객들에게게 호감을 가질 가능성이 더 높을 것으로 추정
- 필요조건
- 영화 평점 점수
- 평점 점수 기반 영화 정렬
(1) 데이터 수집
- 데이터는
kaggle에서 가져왔다.
(2) 데이터 설명
- 여러 데이터들이 있는데, 관련 내용은 캐글 본문의 것을 그대로 사용한다.
- movies_metadata.csv: The main Movies Metadata file. Contains information on 45,000 movies featured in the Full MovieLens dataset. Features include posters, backdrops, budget, revenue, release dates, languages, production countries and companies.
- keywords.csv: Contains the movie plot keywords for our MovieLens movies. Available in the form of a stringified JSON Object.
- credits.csv: Consists of Cast and Crew Information for all our movies. Available in the form of a stringified JSON Object.
- links.csv: The file that contains the TMDB and IMDB IDs of all the movies featured in the Full MovieLens dataset.
- links_small.csv: Contains the TMDB and IMDB IDs of a small subset of 9,000 movies of the Full Dataset.
- ratings_small.csv: The subset of 100,000 ratings from 700 users on 9,000 movies.
(3) 구글 드라이브와 연동
- 구글 드라이브와 연동하여
pandas를 활용하여 데이터를 수집한다. - 구글 드라이브와 연동하는 방법에 대해서는 Colab + Drive + Github Workflow에서 확인한다.
from google.colab import drive # 패키지 불러오기
from os.path import join
ROOT = "/content/drive" # 드라이브 기본 경로
print(ROOT) # print content of ROOT (Optional)
drive.mount(ROOT) # 드라이브 기본 경로 Mount
MY_GOOGLE_DRIVE_PATH = 'My Drive/Colab Notebooks/your/path' # 프로젝트 경로
PROJECT_PATH = join(ROOT, MY_GOOGLE_DRIVE_PATH) # 프로젝트 경로
print(PROJECT_PATH)
/content/drive
Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=947318989803-6bn6qk8qdgf4n4g3pfee6491hc0brc4i.apps.googleusercontent.com&redirect_uri=urn%3aietf%3awg%3aoauth%3a2.0%3aoob&response_type=code&scope=email%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdocs.test%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive.photos.readonly%20https%3a%2f%2fwww.googleapis.com%2fauth%2fpeopleapi.readonly
Enter your authorization code:
··········
%cd "{PROJECT_PATH}"
!ls
data source
import pandas as pd
import pandas_profiling
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
import seaborn as sns
from IPython.core.display import display, HTML
from pandas_profiling import ProfileReport
/usr/local/lib/python3.6/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.
import pandas.util.testing as tm
import pandas as pd
metadata = pd.read_csv('data/movies_metadata.csv', low_memory=False)
metadata.head(3)
| adult | belongs_to_collection | budget | genres | homepage | id | imdb_id | original_language | original_title | overview | popularity | poster_path | production_companies | production_countries | release_date | revenue | runtime | spoken_languages | status | tagline | title | video | vote_average | vote_count | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | False | {'id': 10194, 'name': 'Toy Story Collection', ... | 30000000 | [{'id': 16, 'name': 'Animation'}, {'id': 35, '... | http://toystory.disney.com/toy-story | 862 | tt0114709 | en | Toy Story | Led by Woody, Andy's toys live happily in his ... | 21.946943 | /rhIRbceoE9lR4veEXuwCC2wARtG.jpg | [{'name': 'Pixar Animation Studios', 'id': 3}] | [{'iso_3166_1': 'US', 'name': 'United States o... | 1995-10-30 | 373554033.0 | 81.0 | [{'iso_639_1': 'en', 'name': 'English'}] | Released | NaN | Toy Story | False | 7.7 | 5415.0 |
| 1 | False | NaN | 65000000 | [{'id': 12, 'name': 'Adventure'}, {'id': 14, '... | NaN | 8844 | tt0113497 | en | Jumanji | When siblings Judy and Peter discover an encha... | 17.015539 | /vzmL6fP7aPKNKPRTFnZmiUfciyV.jpg | [{'name': 'TriStar Pictures', 'id': 559}, {'na... | [{'iso_3166_1': 'US', 'name': 'United States o... | 1995-12-15 | 262797249.0 | 104.0 | [{'iso_639_1': 'en', 'name': 'English'}, {'iso... | Released | Roll the dice and unleash the excitement! | Jumanji | False | 6.9 | 2413.0 |
| 2 | False | {'id': 119050, 'name': 'Grumpy Old Men Collect... | 0 | [{'id': 10749, 'name': 'Romance'}, {'id': 35, ... | NaN | 15602 | tt0113228 | en | Grumpier Old Men | A family wedding reignites the ancient feud be... | 11.7129 | /6ksm1sjKMFLbO7UY2i6G1ju9SML.jpg | [{'name': 'Warner Bros.', 'id': 6194}, {'name'... | [{'iso_3166_1': 'US', 'name': 'United States o... | 1995-12-22 | 0.0 | 101.0 | [{'iso_639_1': 'en', 'name': 'English'}] | Released | Still Yelling. Still Fighting. Still Ready for... | Grumpier Old Men | False | 6.5 | 92.0 |
(4) 평점 가중치 함수 구현
- 여기에서 주목해야 하는 것이 있는데,
vote_average와vote_count를 유심히 봐야한다. - 3명이 투표해서 얻은 평점 8.7의 영화 Vs. 100명이 투표해서 얻은 평점 8.0의 영화 중 어느 것이 더 좋다고 볼 수 있을까?
- 이러한 부분을 고려하여 가중치 공식을 만든다. (wr:Weighted Rating)
$$ wr = \left (\frac{\nu }{\nu+\mu } \times R \right ) + \left (\frac{\nu }{\nu+\mu } \times C \right ) $$







