-
[Recommendation] Collaborative Filtering : MSD, Cosine, Pearson 유사도ML/Recommendation 2020. 3. 6. 18:16
이전 포스팅에서 구현에 사용했던 유클리디안 유사도 이외의 다른 유사도(Similarity)들을 알아보자.
1. 평균제곱차이 유사도 (Mean Squared Difference Similarity)
- User-based Collaborative Filter
- Iuv는 사용자 u와 사용자 v 모두에 의해 평가된 상품의 집합
- |Iuv|는 사용자 u와 사용자 v 모두에 의해 평가된 상품의 수
- 동일한 item에 대해 점수를 매긴 user 사이의 유사도- Item-based Collaborative Filter
- Uij는 상품 i와 상품 j 모두를 평가한 사용자의 집합이고 |Uij|는 상품 i와 상품 j 모두를 평가한 사용자의 수
- 동일한 user에 대해 점수가 매겨진 item 사이의 유사도- Mean Squared Difference Similarity
- Mean Squared Difference(msd)의 역수 -> msd가 클 수록 Similarity 값은 작아짐
- MSD가 0이 되는 경우를 대응하기 위해 분모에 1을 무조건 더함- Python 구현
def sim_msd(data, name1, name2): diff = 0 count = 0 for title in data[name1]: if title in data[name2]: # print('commonly watched movie ->', title) diff += pow(data[name1][title] - data[name2][title], 2) count += 1 sim_msd = 1/( 1 + (diff/count) ) print('** msd similariy = ', sim_msd) return sim_msd
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}, 'cookie':{'Anne_with_an_E':2,'Strange_Things':1} }
sim_msd(ratings, 'doky', 'cookie')
Out: ** msd similariy = 0.13333333333333333
2. 코사인 유사도 (Cosine Similarity)
- 코사인 유사도 값의 범위 : -1 ~ 1
- 내적 공식 이용하여 도출
- 사용자 u와 사용자 v간의 Cosine Similarity
- 두 사용자가 모두 평가한 상품의 평점을 사용해서 계산
- 분모는 내적값을 구하는 것과 같음
- 분자는 벡터의 크기를 구하는 것과 같음- 상품 i와 상품 j간의 Cosine Similarity
- 두 상품의 평점을 사용해서 계산
- 분모는 내적값을 구하는 것과 같음
- 분자는 벡터의 크기를 구하는 것과 같음- Python 구현
import math def sim_cosine(data, name1, name2): vsize_name1 = 0 vsize_name2 = 0 product_sum = 0 for title in data[name1]: if title in data[name2]: vsize_name1 += pow(data[name1][title], 2) vsize_name2 += pow(data[name2][title], 2) product_sum += data[name1][title]*data[name2][title] sim_cosine = product_sum/(math.sqrt(vsize_name1)*math.sqrt(vsize_name2)) print("** cosine similarity : ",sim_cosine) return sim_cosine
sim_cosine(ratings, 'doky', 'cookie')
Out: ** cosine similarity : 0.9970544855015815
3. 피어슨 유사도 (Pearson Similarity)
- 피어슨 유사도 값의 범위 -1 ~ 1
- 특정인물의 점수기준이 극단적으로 너무 낮거나 높을 경우 유사도에 영향을 크게 주기 때문에, 이를 막기 위해 상관계수 사용
- 사용자 u와 사용자 v간의 Pearson Similarity
- μu는 사용자 u의 평균 평점
- 상품 i와 상품 j간의 Pearson Similarity
- μi는 상품 i의 평균 평점
- Python 구현
def sim_pearson(data, name1, name2): sum_name1 = 0 sum_name2 = 0 count = 0 for title in data[name1]: if title in data[name2]: sum_name1 += data[name1][title] sum_name2 += data[name2][title] count += 1 avg_name1 = sum_name1/count avg_name2 = sum_name2/count vsize_name1 = vsize_name2 = product_sum = 0 for title in data[name1]: if title in data[name2]: vsize_name1 += pow(data[name1][title]-avg_name1, 2) vsize_name2 += pow(data[name2][title]-avg_name2, 2) product_sum += (data[name1][title]-avg_name1)*(data[name2][title]-avg_name2) sim_pearson = product_sum / (math.sqrt(vsize_name1)*math.sqrt(vsize_name2)) print('** Pearson similarity', sim_pearson) return sim_pearson
sim_pearson(ratings, 'doky', 'cookie')
Out: ** Pearson similarity 0.9999999999999998
4. 유사도 상위 N 출력
- Python 구현
def top_match(data, name, n=3, sim_function=sim_pearson): top_list = [] for user in data: if user != name: top_list.append((sim_function(data, name, user), user)) # ({유사도}, {사람}) top_list.sort(reverse=True) topN_list = top_list[:n] for idx, user in enumerate(topN_list): print(idx+1, '등 : ', user) return topN_list
print('[msd]') top_match(ratings, 'doky', 3, sim_msd) print('-'*50) print('[cosine]') top_match(ratings, 'doky', 3, sim_cosine) print('-'*50) print('[pearson]') top_match(ratings, 'doky', 3, sim_pearson)
Out:
[msd]
** msd similariy = 0.37499999999999994
** msd similariy = 0.09090909090909091
** msd similariy = 0.15
** msd similariy = 0.13333333333333333
1 등 : (0.37499999999999994, 'steve')
2 등 : (0.15, 'bobby')
3 등 : (0.13333333333333333, 'cookie')
--------------------------------------------------
[cosine]
** cosine similarity : 0.9412416106700233
** cosine similarity : 0.6430394361098802
** cosine similarity : 0.7795844649455863
** cosine similarity : 0.9970544855015815
1 등 : (0.9970544855015815, 'cookie')
2 등 : (0.9412416106700233, 'steve')
3 등 : (0.7795844649455863, 'bobby')
--------------------------------------------------
[pearson]
** Pearson similarity 0.6933752452815364
** Pearson similarity -0.9819805060619655
** Pearson similarity -0.2773500981126146
** Pearson similarity 0.9999999999999998
1 등 : (0.9999999999999998, 'cookie')
2 등 : (0.6933752452815364, 'steve')
3 등 : (-0.2773500981126146, 'bobby')이런 식으로 유사도가 높은 top N명을 찾을 수 있다!
reference : https://www.fun-coding.org/recommend_basic2.html
'ML > Recommendation' 카테고리의 다른 글
[Recommendation] 유사도와 KNN을 활용한 예측값 계산 및 추천 목록 생성 (0) 2020.03.06 [Recommendation] 추천 알고리즘 Python 구현 : Collaborative Filtering w/ 유클리디안 유사도 (0) 2020.03.06