또는 $$ \hat{r}_{ui} = \frac{ \sum\limits_{j \in N^k_u(i)} \text{sim}(i, j) \cdot r_{uj}} {\sum\limits_{j \in N^k_u(j)} \text{sim}(i, j)} $$
추측평점의 총합을 구한 후,
추측평점 총합계/유사도 합계를 통해 예상평점을 뽑아낼 수 있다.
ratings_expand = {
'마동석': {
'택시운전사': 3.5,
'남한산성': 1.5,
'킹스맨:골든서클': 3.0,
'범죄도시': 3.5,
'아이 캔 스피크': 2.5,
'꾼': 3.0,
},
'이정재': {
'택시운전사': 5.0,
'남한산성': 4.5,
'킹스맨:골든서클': 0.5,
'범죄도시': 1.5,
'아이 캔 스피크': 4.5,
'꾼': 5.0,
},
'윤계상': {
'택시운전사': 3.0,
'남한산성': 2.5,
'킹스맨:골든서클': 1.5,
'범죄도시': 3.0,
'꾼': 3.0,
'아이 캔 스피크': 3.5,
},
'설경구': {
'택시운전사': 2.5,
'남한산성': 3.0,
'범죄도시': 4.5,
'꾼': 4.0,
},
'최홍만': {
'남한산성': 4.5,
'킹스맨:골든서클': 3.0,
'꾼': 4.5,
'범죄도시': 3.0,
'아이 캔 스피크': 2.5,
},
'홍수환': {
'택시운전사': 3.0,
'남한산성': 4.0,
'킹스맨:골든서클': 1.0,
'범죄도시': 3.0,
'꾼': 3.5,
'아이 캔 스피크': 2.0,
},
'나원탁': {
'택시운전사': 3.0,
'남한산성': 4.0,
'꾼': 3.0,
'범죄도시': 5.0,
'아이 캔 스피크': 3.5,
},
'소이현': {
'남한산성': 4.5,
'아이 캔 스피크': 1.0,
'범죄도시': 4.0
}
}
def getRecommendation (data, person, k=3, sim_function=sim_pearson):
result = top_match(data, person, k)
score = 0 # 평점 합을 위한 변수
li = list() # 리턴을 위한 리스트
score_dic = dict() # 유사도 총합을 위한 dic
sim_dic = dict() # 평점 총합을 위한 dic
for sim, name in result: # 튜플이므로 한번에
print(sim, name)
if sim < 0 : continue #유사도가 양수인 사람만
for movie in data[name]:
if movie not in data[person]: #name이 평가를 내리지 않은 영화
score += sim * data[name][movie] # 그사람의 영화평점 * 유사도
score_dic.setdefault(movie, 0) # 기본값 설정
score_dic[movie] += score # 합계 구함
# 조건에 맞는 사람의 유사도의 누적합을 구한다
sim_dic.setdefault(movie, 0)
sim_dic[movie] += sim
score = 0 #영화가 바뀌었으니 초기화한다
for key in score_dic:
score_dic[key] = score_dic[key] / sim_dic[key] # 평점 총합/ 유사도 총합
li.append((score_dic[key],key)) # list((tuple))의 리턴을 위해서.
li.sort() #오름차순
li.reverse() #내림차순
return li
getRecommendation(ratings_expand, '소이현')
getRecommendation(ratings_expand, '최홍만', k=2, sim_function=sim_cosine)
또는 $$ \hat{r}_{ui} = \mu_i + \frac{ \sum\limits_{j \in N^k_u(i)} \text{sim}(i, j) \cdot (r_{uj} - \mu_j)} {\sum\limits_{j \in N^k_u(i)} \text{sim}(i, j)} $$
for name in ratings_expand:
sum = 0
count = 0
for movies in ratings_expand[name]:
sum += ratings_expand[name][movies]
count += 1
ratings_expand[name]['avg'] = sum / count
ratings_expand
def getRecommendation (data, person, k=3, sim_function=sim_pearson):
result = top_match(data, person, k)
score = 0 # 평점 합을 위한 변수
li = list() # 리턴을 위한 리스트
score_dic = dict() # 유사도 총합을 위한 dic
sim_dic = dict() # 평점 총합을 위한 dic
for sim, name in result: # 튜플이므로 한번에
print(sim, name)
if sim < 0 : continue #유사도가 양수인 사람만
for movie in data[name]:
if movie not in data[person]: #name이 평가를 내리지 않은 영화
score += sim * (data[name][movie] - data[name]['avg']) # 그사람의 영화평점 * 유사도
score_dic.setdefault(movie, 0) # 기본값 설정
score_dic[movie] += score # 합계 구함
# 조건에 맞는 사람의 유사도의 누적합을 구한다
sim_dic.setdefault(movie, 0)
sim_dic[movie] += sim
score = 0 #영화가 바뀌었으니 초기화한다
for key in score_dic:
score_dic[key] = data[person]['avg'] + (score_dic[key] / sim_dic[key]) # 평점 총합/ 유사도 총합
li.append((score_dic[key],key)) # list((tuple))의 리턴을 위해서.
li.sort() #오름차순
li.reverse() #내림차순
return li
getRecommendation(ratings_expand, '소이현')
getRecommendation(ratings_expand, '최홍만', k=2, sim_function=sim_cosine)