-
[Recommendation] 추천 알고리즘 Python 구현 : Collaborative Filtering w/ 유클리디안 유사도ML/Recommendation 2020. 3. 6. 13:14
넷플릭스를 한창 보는 중인데, 도대체 넷플릭스는 어떤 방식으로 나한테 추천을 해주는 건지가 궁금해졌다.
추천 알고리즘을 좀 알아봐야겠다!
먼저 제일 기초적인 [1. 사용자 간의 유사도를 구하는 방식 + 2. 그 유사도로 추천하는 기본 방식]을 알아보고,
넷플릭스는 그걸 어떻게 사용하는지 알아보자.
Popularity, High Rated Based
가장 단순한 방법 → 평점이 높은 것을 추천
모두에게 같은 item 추천하게 됨.
ratings = { 'doky':{'Anne_with_an_E':5,'Strange_Things':3,'The_Escape':3}, 'steve':{'Anne_with_an_E':5,'Strange_Things':1,'The_Escape':4}, 'jamie':{'Anne_with_an_E':0,'Strange_Things':4,'The_Escape':5}, 'bobby':{'Anne_with_an_E':2,'Strange_Things':1,'The_Escape':5} }
recmd_movielist = dict() # (A) for name in ratings: for title in ratings[name]: score = ratings[name][title] if title not in recmd_movielist: recmd_movielist[title] = score else: recmd_movielist[title] += score #
# (B) for recmd_movietitle in recmd_movielist: recmd_movielist[recmd_movietitle] /= 4 #
# (C) from operator import itemgetter recmd_movielist = sorted(recmd_movielist.items(), reverse=True, key=itemgetter(1)) # recmd_movielist
Out: [('The_Escape', 4.25), ('Anne_with_an_E', 3.0), ('Strange_Things', 2.25)]
네 사람이 같은 영화에 준 평점들을 각각 더한 다음 (A)
4로 나눠서 각 영화가 받은 평점의 평균을 낸다 (B)
그 평균으로 내림차순 정렬해서 추천 리스트를 만든다 (C)Collaborative Filtering
- 사용자가 입력한 선호도(평점)를 사용하여 사용자-항목 선호도(평점) 행렬 계산
- 그 행렬을 사용하여 사용자들 간의 유사도를 계산
- 사용자들 간의 유사도를 바탕으로 모든 항목에 대해 예측 값을 계산하고, 높은 예측 값을 갖는 상위 N개의 추천 목록을 생성
ratings = { 'doky':{'Anne_with_an_E':5,'Strange_Things':3,'The_Escape':3}, 'steve':{'Anne_with_an_E':5,'Strange_Things':1,'The_Escape':4}, 'jamie':{'Strange_Things':4,'The_Escape':5}, 'bobby':{'Anne_with_an_E':2,'Strange_Things':1,'The_Escape':5} }
import math def sim_w_dist(i, j): return math.sqrt(pow(i,2) + pow(j,2))
유클리디안 거리 유사도 측정
max_sim_w_dist = sim_w_dist(5, 5) min_sim_w_dist = sim_w_dist(0, 0) print(min_sim_w_dist, ',', max_sim_w_dist)
sim_w_dist로 구한 sim의
최대값=루트50, 최소값=0for name in ratings: if name != 'jamie': v1 = ratings['jamie']['Strange_Things'] - ratings[name]['Strange_Things'] v2 = ratings['jamie']['The_Escape'] - ratings[name]['The_Escape'] sim = sim_w_dist(v1, v2) norm_sim = (sim-min_sim_w_dist)/(max_sim_w_dist-min_sim_w_dist) print('similarity with', name, ':', sim, '->', norm_sim)
Out: similarity with doky : 2.23606797749979 -> 0.31622776601683794
similarity with steve : 3.1622776601683795 -> 0.4472135954999579
similarity with bobby : 3.0 -> 0.4242640687119285jamie가 평가한 Strange_Things, The_Escape를 모두 평가한 사용자와의 유사도 구하기
● sim_w_dist 함수 사용
● sim을 0과 1 사이로 정규화한 norm_sim 계산 => 1에 가까운 값일수록 유사도 높음다음 포스팅(#2)에서는 오늘 구현한 유클리디안 유사도 말고 다른 유사도들을 알아보겠다.
'ML > Recommendation' 카테고리의 다른 글
[Recommendation] 유사도와 KNN을 활용한 예측값 계산 및 추천 목록 생성 (0) 2020.03.06 [Recommendation] Collaborative Filtering : MSD, Cosine, Pearson 유사도 (0) 2020.03.06