[Recommendation system]Basic Recommendation System 구현 I
ML 기반 추천 엔진: 컨텐츠 기반 추천 엔진 개발
넷플릭스 프라이즈 개요
- 2006년부터 3년간 운영된 기념비적인 추천 엔진 경진 대회
- 넷플릭스의 내부에서 쓰던 추천 시스템 품질을 10% 개선하는 팀에게 $1M 수여 약속, RMSE(Root Mean Square Error)가 평가 기준으로 사용됨
- 이를 기폭제로 캐글과 같은 머신러닝 경진대회 플랫폼이 등장!
넷플릭스 프라이즈 우승팀과 알고리즘
- 이 대회를 통해 협업 필터링이 한단계 발전!
- SVD를 활용한 SVD++는 이후 굉장히 많은 분야에서 활용됨
- 앙상블 방식의 모델들이 가장 좋은 성능을 보임
- 너무 긴 실행시간 때문에 실제 프로덕션에서는 사용 불가
- 너무 긴 실행시간 때문에 실제 프로덕션에서는 사용 불가
앙상블(Ensemble)과 랜덤 포레스트(Random Forest)
- 다수의 분류기를 사용해서 예측하는 방식(여러 모델의 조합)
- 성능은 좋지만 훈련과 예측 시간이 오래 걸린다는 단점
추천 엔진의 발전 역사
- 2001년 아마존이 아이템 기반 협업 필터링 논문 발표
- 2006-2009년 넷플릭스 프라이즈
- SVD를 이용한 사용자의 아이템 평점 예측 알고리즘 탄생
- 앙상블 알고리즘이 보편화됨
- 딥러닝의 일종이라 할 수 있는 RBM(Restricted Boltzman Machine)
- 2010년 딥러닝이 컨텐츠 기반 음악 추천에 사용되기 시작
- 2016년 딥러닝을 기반으로 한 추천이 활기를 띄기 시작
- 오토인코더 기반으로 복잡한 행렬 계산을 단순화 하는 방식
- 아이템 관련 사용자 정보를 시간순으로 인코드하는 RNN 사용 방식
- 아마존에서 DSSNTE라는 알고리즘 오픈소스화했다가 SageMaker라는 제품으로 통합
- 개발 부담을 최소화한 다양한 서비스들이 나오게 됨(클라우드 서비스들)
인기도 기반 추천 엔진 개발
- Cold Start 이슈가 존재하지 않음. 특정 카테고리에 대해서 인기의 정의에 따라 추천 시스템을 구축하면 되기 때문.
- 인기도의 기준
- 평점 / 매출 / 최다 판매
- 사용자 정보에 따라 확장 가능
- 서울 지역 인기 아이템 추천
- 개인화되어 있지는 않음(어느정도는 가능)
- 같은 20대 사람들에게 인기있는 ~~ -> 개인화 x
- 아이템의 분류 체계 정보 존재 여부에 따라 쉽게 확장 가능
- 특정 카테고리에서의 인기 아이템 추천
- 인기도를 다른 기준으로 바꿔 다양한 추천 유닛 생성 가능
- top 100 -> newest 등으로 기준을 바꿔 유닛을 생성할 수 있다.
- top 100 -> newest 등으로 기준을 바꿔 유닛을 생성할 수 있다.
기타 Cold Start 이슈가 없는 추천 유닛
- 현재 사용자들이 구매한 아이템
- 현재 사용자들이 보고 있는 아이템(영화, 강좌 등)
유사도 측정: 코사인 유사도와 피어슨 유사도 설명
다양한 유사도 측정 알고리즘
- 벡터들간의 유사도를 판단하는 방법
- 코사인 유사도란?
- N차원 공간에 있는 두 개의 벡터간의 각도(원점에서)를 보고 유사도를 판단하는 기준
- 대표적인 것은 코사인 유사도와 피어슨 유사도
- 평점처럼 방향 뿐만 아니라 벡터 크기의 정규화가 중요하면 피어슨 유사도를 사용
- 피어슨 유사도는 코사인 유사도의 개선 버전
- 평점처럼 방향 뿐만 아니라 벡터 크기의 정규화가 중요하면 피어슨 유사도를 사용
- 피어슨 유사도란?
- 먼저 벡터 A와 B의 값들을 보정
- 각 벡터내 셀들의 평균값을 구한 뒤 평균값을 각 셀에서 빼줌
- 예를 들어 A = {3, 4, 5} -> 각각 평균값 4를 빼서 보정 -> A = {-1, 0, 1}
- 그 이후 계산은 코사인 유사도와 동일. 중앙 코사인 유사도 or 보정된 코사인 유사도라 부르기도 함.
- 먼저 벡터 A와 B의 값들을 보정
- 피어슨 유사도의 장점
- 모든 벡터가 원점을 중심으로 이동되고 벡터간의 비교가 더 쉬워짐
- 평점이란 관점에서는 까다로운 사용자와 아닌 사용자를 정규화하는 효과를 가져옴
- 평점이란 관점에서는 까다로운 사용자와 아닌 사용자를 정규화하는 효과를 가져옴
- 모든 벡터가 원점을 중심으로 이동되고 벡터간의 비교가 더 쉬워짐
TF-IDF 소개
텍스트를 행렬(벡터)로 표현하는 방법
- 텍스트 문서를 행렬로 표현하는 방법은 여러가지
- 기본적으로 일단 단어를 행렬의 차원으로 표현해야함
- Bag of Words 방식은 문서들에 나타나는 단어수가 N개이면 N차원으로 문서 표현
- 딥러닝의 워드임베딩 사용시 차원수도 축소되고 공간상에서 비슷한 단어들끼리 가깝게 위치
- 원핫 인코딩 + Bag of Words(카운트)
- 단어의 수를 카운트해서 표현
- 원핫 인코딩 + Bag of Words(TF-IDF)
- 단어의 값을 TF-IDF 알고리즘으로 계산된 값으로 표현
- 단순한 카운트가 아니라 문서 전체적으로 단어가 중요한지 의미적으로 더 접근
원핫 인코딩 + Bag of Words(카운트)
- 먼저 stopword 제외 (the, is, in, we, can, see)
- 그 뒤 단어수 계산 -> 유니크하게 나온 단어가 총 5개 (sky, blue, sun, bright, shining)
- 단어별로 차원을 배정: sky(1), blue(2), sun(3), bright(4), shining(5)
- 예를들어 문서 doc1에서 sky, blue가 한번씩 나왔다면 [1, 1, 0, 0, 0]이 된다.
CountVectorizer 소개
- 앞서 Bag of Words 카운팅 방식을 구현한 모듈
- 이렇게 벡터로 표현이 되면 문서들간의 유사도 측저이 가능
- CountVectorizer(analyzer=’word’, stop_words=’english’)
- 들어오는 텍스트를 word단위로 끊는다(공백이 항상 단어 단위를 의미하지 않는 한국어, 중국어의 경우 좋지 않음)
- stop_words=’english’하면 영어에서 의미없는 것들, is, the등등을 스탑워드로 자동으로 만들어줌.
TF-IDF 소개
- 앞서 카운트 방식은 자주 나오는 단어가 높은 가중치를 갖게 됨
- TF-IDF의 기본적인 아이디어
- 한 문서에서 중요한 단어를 카운트가 아닌 문서군 전체를 보고 판단하자
- 어떤 단어가 한 문서에서 자주 나오면 중요하지만 이 단어가 다른 문서들에서는 자주 나오지 않는다면 더 중요
- 단어 t의 문서 d에서의 점수: TF-IDF = TF(t, d) * IDF(t)
- TF(t, d): 단어 t가 문서 d에서 몇번 나왔나?
- DF(t): 단어 t가 전체 문서군에서 몇번 나왔나?
- IDF(t): 위의 DF(t)의 역비율
- 단어 t가 전체 문서들중(총 N개) 몇개의 문서에서 나왔는지의 비율을 역으로 계산한 것이 IDF -> 다른 문서에서는 안나올수록 더 중요한 단어
- ln(N/DF): N은 총 문서수를 나타내고 DF는 단어가 나온 문서를 말한다.
원핫 인코딩 + Bag of Words(TF-IDF)
- 카운트 기반 Bag of Words랑 동일한데 카운트 대신에 TF-IDF 점수를 사용
- TF-IDF = TF(t, d) * IDF(t)
- TF(t, d): 단어 t가 문서 d에서 카운트
- IDF(t): 역문서 비율. 단어 t가 전체 N개의 문서들 중 몇개의 문서에서 나타났는지의 비율을 역으로 한 값
- ln(N/DF)
- N은 총 문서수
- DF는 단어가 나온 문서의 수
- ln(N/DF)
TfidfVectorizer소개
- TfidfVectorizer(analyzer=’word’, stop_words=’english’, norm=’l2’)
- analyzer, stop_words는 CountVectorizer와 동일.
- L2 normalization: 벡터를 단위 벡터로 만든다. 길이가 1인 벡터로 만드는 것.
- 사이킷런의 TF-IDF 공식은 조금 다름
- IDF = ln(N+1)/(DF+1)+1
- 왜 다를까? ln 1은 0, 0으로 나누면 에러.
TF-IDF 문제점
- 정확하게 동일한 단어가 나와야 유사도 계산이 이뤄짐
- 동의어 처리가 안됨
- 단어의 수가 늘어나고 아이템의 수가 늘어나면 계산이 오래걸림
- 결국은 워드 임베딩을 사용하는 것이 더 좋음
- 아니면 LSA(Latent Semantic Analysis)와 같은 차원 축소 방식 사용
- 아니면 LSA(Latent Semantic Analysis)와 같은 차원 축소 방식 사용
CountVectorizer/TFIdfVectorizer/코사인 유사도 실습
- 앞서 설명한 개념들을 실제 코드로 실습
- 이를 바탕으로 뒤에서 컨텐츠 기반 추천 엔진 개발
- https://colab.research.google.com/drive/1WRd0uhPSwLVuQk998teEaziCHesMNawD?usp=sharing
TF-IDF를 이용한 컨텐츠 기반 추천과 실습
- 영화 추천을 위해 TMDB 데이터 재사용
- 컨텐츠 기반 추천 엔진 개발
- TfIdfVectorizer와 cosine_similarity를 사용
- https://colab.research.google.com/drive/1xbFjBvzgiDpPwBwKiaMw0ByWos12EAiD?usp=sharing