본문 바로가기
Python 과 머신러닝/III. 머신러닝 모델

[Python 머신러닝] 9장. 추천시스템 (Recommendation System)

by JoyfulS 2019. 10. 30.

 

 

1. 추천시스템이란?

- 추천 시스템 (Recommender/Recommendation System)

- 정보 필터링(IF) 기술의 일종으로, 특정 사용자가 관심을 가질만한 정보를 추천하는 시스템

- 정보 : 영화, 음악, 책, 뉴스, 이미지, 웹 페이지 등

 

>추천 시스템 사례

- 넷플릭스 : 고객의 영화 평가를 바탕으로 특정 고객에게 영화 추천 서비스 -> 고객 이탈률 4% 이하

- 아마존 : 협업필터링 알고리즘 기반 추천 시스템 적용

   (제품 웹페이지 방문기록, 쇼핑장바구니, 구매 상품 선호 등 다양한 정보 -> Item 기반 추천시스템)

 

2. 추천 알고리즘

① 협업 필터링 (Collaborative Filtering : CF)

    - 구매/소비 패턴이 비슷한 사용자를 한 집단으로 보고 그 집단에 속한 소비자들의 취향을 추천하는 방식

    - UBCF (User Based CF) : 패턴이 비슷한 사용자를 기반으로 상품(Item) 추천

    - IBCF (Item Based CF) : 상품(Item)을 기반으로 연관성이 있는 상품(Item) 추천

② 내용기반 필터링 (Content-Based Filtering : CB)

    - 뉴스, 책 등 텍스트의 내용을 분석해서 추천하는 방식

    - 소비자가 소비하는 제품 중 텍스트 정보가 많은 제품을 대상으로 함

    - 텍스트 중에서 형태소(명사, 동사 등)를 분석하여 핵심 키워드를 분석하는 기술이 핵심

③ 지식기반 필터링 (Knowledge-Based Filtering : KB)

    - 특정 분야에 대한 전문가의 도움을 받아서 그 분야에 대한 전체적인 지식구조를 만들고 이를 활용하는 방식

 

 

> 협업 필터링의 유사도(Similarity) 계산 방법

- 상관계수 (Correlation coefficient) 유사도 : 피어슨 상관계수 이용

- 코사인 (Cosine) 유사도 : 두 벡터 사이의 각도

- Jaccard 유사도 : 이진화 자료(binary data) 대상 유사도 계산

- 유클리드 거리 계산법 : 거리 기반 유사도 계산

 

> SVD

- 특이값 분해 (SVD : Singular Value Decomposition)

- 차원 축소 (dimension reduction) 기법 사용

- 모든 m x n 행렬에 대해 적용 가능

- m x n 행렬 A를 다음과 같이 분해

    • U : m x m 크기의 정방행렬 

    • ∑ : m x n 크기의 대각행렬 (주 대각성분이 A의 특이값) 

        * 대각행렬 : 주대각선을 제외한 모든 원소가 0인 정사각형 행렬

    • VT : n x n 크기의 정방행

 

> SVD 기반 추천시스템

- 사용자의 특징과 아이템의 특징 그리고 이 두 가지를 대표하는 대각행렬 추출

- 대각 행렬의 특이값으로 차원을 축소 (데이터의 양 줄이기)

- 아직 평가하지 않은 데이터에 대해서 평균값을 이용해 결측치를 채운 뒤 SVD를 이용해 점수 예측

- 추천 시스템에서는 이 예측된 점수가 높은 아이템을 추천

 


< 실습한 내용 >

[ 주제 ]

: 특정 사용자(Toby)에게 유사도 평점을 통해 추천하기

[ 시나리오 ]

: Toby는 3편의 영화를 관람하고, 3편의 영화는 미관람한 상태이다. 보지 않은 3편의 영화 중 Toby의 취향에 가장 적합한 영화를 추천해아 한다.

[ 알고리즘 ]

: Toby의 영화평점과 다른 사람의 영화평점 간의 유사도를 계산하여 활용한다.

1. Toby와의 유사도 계산 (피어슨 상관계수)

2. 유사도 평점 계산 = Toby가 미관람한 영화평점 * Toby와의 유사도

3. Toby에게 영화 추천 = 유사도 평점 합계 / Toby와의 유사도 합계

 

실습 전 준비사항

- 아나콘다 프롬프트에서 'Surprise' 패키지 설치하기 ( "pip install scikit-surprise" 입력)

- 만약 설치가 안되고 실패할 경우, 'conda install -c conda-forge scikit-surpirse' 입력

    > Proceed ([y]/n)? 질문이 뜨면 'y' 입력

 


"""
SVD 기반 추천시스템
 - Toby에게 영화 추천하기
"""

import pandas as pd # raw dataset
from surprise import SVD, accuracy # SVD model, 평가
from surprise import Reader, Dataset # SVD model의 dataset

# 1. raw dataset

movie_rating.csv
0.00MB

rating = pd.read_csv("../data/movie_rating.csv")
rating.head()   #   critic(user)   title(item)   rating

rating.head() 출력결과

 

rating['critic'].value_counts()
rating['title'].value_counts()

# 관람 vs 미관람
tab = pd.crosstab(rating['critic'], rating['title'])
tab

tab 출력결과


# movie rating
# 두 개의 집단변수를 가지고 나머지 rating을 그룹화
rating_g = rating.groupby(['critic', 'title'])
rating_g.sum()
tab = rating_g.sum().unstack() # 행렬구조로 변환
tab

# Toby가 미관람한 영화 : 'Just My', 'Lady', 'The Night'


# 2. rating 데이터셋 생성
reader = Reader(rating_scale= (1, 5)) # 평점 범위
data = Dataset.load_from_df(df=rating, reader=reader)
# rating이라는 데이터프레임은 reader(1~5)의 평점 범위를 가진다.
data


# 3. train/test set
train = data.build_full_trainset() # 훈련셋
test = train.build_testset() # 검정셋


# 4. model 생성
help(SVD)

model = SVD(n_factors=100, n_epochs=20, random_state=123)
model.fit(train) # model 생성


# 5. Toby 사용자 영화추천
user_id = 'Toby' # 추천대상자
item_ids = ['The Night', 'Just My', 'Lady'] # 추천 대상 영화
actual_rating = 0 # 실제 평점

 

for item_id in item_ids :
    print(model.predict(user_id, item_id, actual_rating))
    
'''
user: Toby       item: The Night  r_ui = 0.00   est = 3.30   {'was_impossible': False}
user: Toby       item: Just My    r_ui = 0.00   est = 2.88   {'was_impossible': False}
user: Toby       item: Lady       r_ui = 0.00   est = 3.27   {'was_impossible': False}
'''
# 예측한 평점이 가장 높은 'The Night' 영화를 추천한다.

 

댓글