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
rating = pd.read_csv("../data/movie_rating.csv")
rating.head() # critic(user) title(item) rating
rating['critic'].value_counts()
rating['title'].value_counts()
# 관람 vs 미관람
tab = pd.crosstab(rating['critic'], rating['title'])
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' 영화를 추천한다.
'Python 과 머신러닝 > III. 머신러닝 모델' 카테고리의 다른 글
[Python 머신러닝] 10장. 텍스트 마이닝 - (1) 크롤링 (Crawling) (0) | 2019.10.31 |
---|---|
[Python 머신러닝] 10장. 텍스트 마이닝 (Text Mining) 개요 & 패키지 준비 (0) | 2019.10.31 |
[Python 머신러닝] 8장. 군집분석 (Cluster Analysis) (0) | 2019.10.29 |
[Python 머신러닝] 7장. 앙상블 (Ensemble) - (3) XGBoost (0) | 2019.10.28 |
[Python 머신러닝] 7장. 앙상블 (Ensemble) - (2) RandomForest (0) | 2019.10.25 |
댓글