유사도와 KNN을 활용한 예측 값 계산 및 추천 목록 생성 기법
이해하기 쉽고, 장황하지 않은 자료를 기반으로 강의를 진행합니다.
잔재미코딩 소식 공유
좀더 제약없이, IT 컨텐츠를 공유하고자, 자체 온라인 강의 사이트와 유투브 채널을
오픈하였습니다
응원해주시면, 곧 좋은 컨텐츠를 만들어서 공유하겠습니다
응원해주시면, 곧 좋은 컨텐츠를 만들어서 공유하겠습니다
● 잔재미코딩 유투브 오픈
[구독해보기]
4. 유사도와 KNN을 활용한 예측 값 계산 및 추천 목록 생성 기법¶
- 사용자들 간의 유사도를 바탕으로 모든 항목에 대해 예측 값을 계산하고 높은 예측 값을 갖는 상위 N개의 추천 목록을 생성한다.
K Nearest Neighbors(KNN) 가중치 예측 기법¶
- 유사도가 구해지면 평점을 예측하고자 하는 사용자(또는 상품)와 유사도가 큰 k 개의 사용자(또는 상품) 벡터를 사용하여 가중 평균을 구해서 가중치를 예측
4.1. KNNBasic¶
- 평점들을 단순히 가중 평균한다. 다음 식에서 $N^k$는 $k$개의 가장 유사도가 큰 벡터의 집합이다.
또는 $$ \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)} $$
대상과 가장 유사도가 높은 k의 대상의 영화 평점과 유사도를 통해 추측평점((유사도 x (타인의)영화평점)을 구한다.
추측평점의 총합을 구한 후,
추측평점 총합계/유사도 합계를 통해 예상평점을 뽑아낼 수 있다.
본 자료와 같이 IT 기술을 잘 정리하여, 온라인 강의로 제공하고 있습니다
퀄러티가 다른 온라인 강의로 차근차근 익혀보세요
In [27]:
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
}
}
In [32]:
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
In [33]:
getRecommendation(ratings_expand, '소이현')
Out[33]:
* getRecommendation를 사용해서 최홍만 과 가장 유사한 사용자는?
* 단 유사도 함수를 sim_cosine, k는 2를 사용하시오
* 단 유사도 함수를 sim_cosine, k는 2를 사용하시오
In [50]:
getRecommendation(ratings_expand, '최홍만', k=2, sim_function=sim_cosine)
Out[50]:
본 자료와 같이 IT 기술을 잘 정리하여, 온라인 강의로 제공하고 있습니다
퀄러티가 다른 온라인 강의로 차근차근 익혀보세요
4.2. KNNWithMeans¶
- 평점들을 평균값 기준으로 가중 평균한다.
또는 $$ \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)} $$
In [34]:
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
In [35]:
ratings_expand
Out[35]:
In [41]:
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
In [42]:
getRecommendation(ratings_expand, '소이현')
Out[42]:
본 자료와 같이 IT 기술을 잘 정리하여, 온라인 강의로 제공하고 있습니다
퀄러티가 다른 온라인 강의로 차근차근 익혀보세요
* getRecommendation를 사용해서 최홍만 과 가장 유사한 사용자는?
* 단 유사도 함수를 sim_cosine, k는 2를 사용하시오
* 단 유사도 함수를 sim_cosine, k는 2를 사용하시오
In [43]:
getRecommendation(ratings_expand, '최홍만', k=2, sim_function=sim_cosine)
Out[43]: