추천시스템 이론 - 협업필터링(CF)의 KNN 모델 정리

David's Data Science·2022년 3월 11일
1

기본적인 추천 시스템 종류 컨텐츠 기반추천(CB), 협업 필터링(CF)

컨텐츠 기반 추천시스템(Content Based)
협업 필터링(CF, Collaborative Filtering)

  • 메모리 기반, 이웃 기반 (Memory Based, Neighbor Based)

    • 유저 기반 (User Based)
    • 아이템 기반 (Item Based)
  • 모델 기반 (Machine Learning)

    • 잠재요인 기반(Latent factor Based)
      • SVD(Singular Vector Decomposition)
      • MF(Matrix Factorization)
      • AutoEncoder(Latent Feature)
      • SVM(Support Vector Machine) - 한마디로 선형 결정 경계를 찾는 모델
    • 기타 분류/회귀 기반
    • 딥러닝 기반(Deep Learning Based)
      • NCF(Neural Collaborative Filtering)
        • DCN(Deep Cross Network)
        • Wide & Deep
      • DeepFM(Deep Fatorization Machine)

Memory Based

Matrix를 이용하는 추천시스템 중 사용자의 평점 혹은 사용여부를 바탕으로 구매 패턴을 파악해 그 메모리를 바탕으로 추천을 진행하는 방법이다.
기본적으로 사용자 또는 아이템의 유사성을 바탕으로 평점이 없는 부분에 대해 모델을 통해 예측을 하는 방식이며, 이는 사용자 관점에서 진행하는 사용자 기반, 아이템 관점에서 진행하는 아이템 기반 협업필터링으로 나눌 수 있다.

  • 사용자 기반(User-Based): 사용자와 비슷한 구매 패턴을 가진 다른 사용자의 평점을 바탕으로 추천
    피어슨 또는 코사인 유사도를 이용해 사용자들 간의 유사도를 구하여 진행한다.
  • 아이템 기반(Item-Based): 사용자들의 아이템 별 평점을 바탕으로 바탕으로 아이템의 유사도를 파악해 비슷한 아이템을 추천, 방식은 사용자 기반과 같다.

KNN(K-Nearest Neighbor)

K명의 최근접 이웃에 기반해서 찾는 방법으로, 널리 쓰이는 방법이다. 사용자가 준 평점으로 유사한 사람의 아이템을 찾거나, 유사한 아이템을 찾아 추천을 한다. 편향을 제거(전반적으로 평점을 후하게 주거나 적게 주는 경우를 방지)해주기 위해 비교군의 평점을 더해주거나 빼주어 동일하게 해준다.

  • 추천 리스트에 새로운 사용자 또는 아이템이 오더라도 안정정으로 진행이 가능하다.
  • 방법이 간단하고 직관적이어서 접근이 용이하다.
  • 유저 기반의 방법 및 속도, 메모리가 많이 든다.
  • 희소성으로 인한 제약이 발생한다. (유사한 이웃이 사용한 경험이 없으면 추천 불가능하다)

KNN을 이용해서 추천진행 해보기

영화 데이터가 아닌 실제 매트릭스를 생성해서 만들어보도록 한다.
아래는 KNN을 공부했던 TeamEDA 김현우님의 포스팅을 바탕으로 코드를 구현해봤다.

아이템1아이템2아이템3아이템4아이템5아이템6
사용자1767454
사용자267?434
사용자3?3311?
사용자4122334
사용자51?1233
import numpy as np

# 위 매트릭스에서 ? 부분은 0으로 치환하여 매트릭스 생성
matrix = np.array([[7,6,7,4,5,4],
                   [6,7,0,4,3,4],
                   [0,3,3,1,1,0],
                   [1,2,2,3,3,4],
                   [1,0,1,2,3,3]])

코사인 유사도 함수작성

여기서 코사인 유사도를 이용해 특정 사용자3과 가장 유사한 사용자를 찾아낼 것이다.

cosθ=ABABcos\theta = \frac{A * B}{||A||*||B||}

def cosine_simillarity(v1, v2):
  """
  두 벡터 v1, v2에 대한 코사인 유사도를 구하는 함수
  위 매트릭스에서 사용자 기반 추천을 한다고 할때, 사용자1을 v1, 사용자2를 v2로 놓는다면,
  v1 = [7,6,7,4,5]
  v2 = [6,7,?,4,3]
  으로 두고 함수를 적용하게 된다.

  return: similarity of the two vectors
  """
  A = np.sqrt(np.sum(np.square(v1)))
  B = np.sqrt(np.sum(np.square(v2)))
  return np.dot(v1,v2) / (A*B)

유사도 계산해보기 (코사인)

사용자3에 대한 다른 사용자들의 유사도를 각각 구해본다.

sim_lst = []  # 빈 리스트 생성
best_score = 0

for idx, vec in enumerate(matrix):  # 매트릭스의 각 사용자 별 벡터를 뽑아 vec에 넣기
  similarity = cosine_simillarity( vec, matrix[2]) # matrix[2] == 사용자3의 벡터
  sim_lst.append((idx,similarity))  
  if idx != 2 and best_score < similarity:  # 현재 계산한 유사도가 기존 최고 유사도보다 높다면 바꿔준다. 
    best_score = similarity
    best_user = idx +1   
print(sim_lst, f"\n사용자3과 가장 비슷한 유저: 사용자{best_user} \n유사도:{best_score}")
[output]

[(0, 0.8113480845393759), (1, 0.5969620057957091), (2, 0.9999999999999998), (3, 0.7745966692414833), (4, 0.46188021535170054)] 
사용자3과 가장 비슷한 유저: 사용자1 
유사도:0.8113480845393759

가장 비슷한 유저를 바탕으로 ?의 점수 예측해보기

현재 사용자3과 가장 비슷한 유저는 사용자1(코사인 유사도 0.81)이다.
해당 사용자1의 평균 평점을 '편향'으로 두고, 사용자1의 아이템1의 평점에서 평균점수를 뺀 점수를 이용.
수정된 점수 x 코사인 유사도를 통해 ?의 점수를 예측한다.

수식으로 나타내면 아래와 같다.

사용자3평점+(사용자1평점사용자1평균평점)사용자1과유사도사용자1과유사도사용자3 평점 + \frac {(사용자1평점-사용자1평균평점)*사용자1과유사도}{사용자1과유사도}

best_user_idx = best_user-1 # 가장 비슷한 유저의 매트릭스 내 인덱스
best_mean_score = np.mean(matrix[best_user_idx])  # 가장 비슷한 유저의 평균 평점
for vec in range(len(matrix[2])):
  if matrix[2][vec] == 0:   # 해당 사용자3의 ? 부분에 위와같은 연산을 진행한다.
    matrix[2][vec] = np.mean(matrix[2]) + (((matrix[best_user_idx][vec]-best_mean_score)*best_score)/best_score)

최종 매트릭스 확인해보기

사용자3의 경우, 평균적으로 평점을 낮게 주는 경향이 있다.
그렇기에 편향을 모두 고려하여 이전 단계까지의 연산을 진행했다.

matrix
[output]

array([[7, 6, 7, 4, 5, 4],
       [6, 7, 0, 4, 3, 4],
       [2, 3, 3, 1, 1, 0],
       [1, 2, 2, 3, 3, 4],
       [1, 0, 1, 2, 3, 3]])

그 결과로, 아이템1에 대해선 평균(1.6667)보다 높은 점수인 2를 예측했고, 아이템6 에대해선 최하점인 0으로 적용이 되었다.
해당 유저에겐 평균 아이템1의 점수가 평균 이상의 높은 점수에 해당 하므로 아이템1을 추천해줄 수 있게 된다.

profile
데이터 사이언티스트가 되고싶은 David입니다.

0개의 댓글