Python

Content-based 추천 시스템 구현 (1)

ju_young 2024. 8. 14. 14:37
728x90

휴리스틱 알고리즘으로 추천 시스템을 구현하는 방법으로 Content-basedCollaborative Filtering이 있다. 이 두 가지 방법 중 Content-based를 적용할 것이고, 이에 대해 먼저 간단히 살펴보겠다.

Content-based 추천

Content-based 추천 방법은 각 사용자가 구매/만족했던 상품과 유사한 것을 추천하는 방법이다. 동작 순서는 다음과 같다.

  1. 상품 프로필 수집
  2. 사용자 프로필 구성
  3. 사용자 프로필과 다른 상품들의 상품 프로필 매칭
  4. 사용자에게 상품 추천

이제 하나씩 순서대로 어떤 것을 하는지 간단하게 알아보겠다.

1. 상품 프로필 수집

상품 프로필이란, 상품의 특성을 나열한 벡터이다. 이를 Feature라고도 부른다.

 

예를 들어, 영화의 프로필의 특성을 나열한 벡터라고 한다면 다음과 같이 표현할 수 있다. 이러한 벡터를 one-hot encoding 이라고 한다.

NOTE
one-hot encoding: 전체 집합의 크기를 벡터의 차원으로 정의하고 표현하고 싶은 값에 1의 값을 부여하고, 다른 값은 0의 값을 부여한다.

2. 사용자 프로필 구성

사용자 프로필도 벡터로 표현되며, 선호하거나 구매한 상품의 프로필을 사용하여 가중 평균한 값이다.

 

위의 상품 프로필과 마찬가지로 영화 프로필을 사용한 사용자 프로필을 다음과 같이 표현할 수 있다.

예를 들어, 로맨스 영화 1편과 액션 영화 1편을 관람했다면 [1, 0, 0, 0, ...] + [0, 0, 1, 0, ...] = [1, 0, 1, 0, ...]이 되고, 이에 대해 평균을 구해주면 [0.5, 0, 0.5, 0, ...]이 된다.

3. 사용자 프로필과 다른 상품들의 상품 프로필 매칭

위 과정을 통해 구성된 사용자 프로필과 상품 프로필은 아래처럼 코사인 유사도를 계산하여 매칭한다. 도출된 값이 클수록 유사하다고 판단할 수 있고, 낮을 수록 유사하지 않다고 판단할 수 있다.

4. 사용자에게 상품 추천

위에서 코사인 유사도를 계산하여 얻은 값을 통해 가장 유사도가 높은 상품들을 선택할 수 있게 된다. 그리고 추천하고 싶은 상품 개수를 지정하여 상위에서 지정한 개수만큼 골라 사용자에게 추천할 수 있다.


Content-based 추천 구현

1. 상품 프로필

상품에 대한 카테고리가 11개가 존재하고, 이 카테고리를 바탕으로 상품의 프로필(벡터)를 정의한다면 다음과 같이 구현할 수 있다.

post_profile = np.array([0.] * 11)
post_profile[-1] += 1

10번째 카테고리에 속한 상품의 벡터라고 알 수 있다.

2. 사용자 프로필 구성

위와 마찬가지로 사용자의 프로필(벡터)를 정의한다면 다음과 같이 구현할 수 있다.

import numpy as np

# 사용자 프로필 -> 카테고리별 구매 횟수
user_profile = np.array([0] * 11)
user_profile[0] = 10
user_profile[1] = 3
user_profile[2] = 2

# count / sum
print(user_profile / user_profile.sum())

"""
출력:
[0.66666667 0.2 0.13333333 0. 0. 0. 0. 0. 0. 0. 0. ]
"""

1번 카테고리 상품을 10번, 2번 카테고리 상품을 3번, 3번 카테고리 상품을 2번 구매했고, 총 15회 구매했기 때문에 마지막에 평균을 구했다.

3. 사용자 프로필과 다른 상품들의 상품 프로필 매칭

우선 사용자 프로필과 상품 프로필과의 코사인 유사도를 구하는 함수를 구현해보면 다음과 같다.

from numpy import dot
from numpy.linalg import norm

def cos_sim(A, B):
    return dot(A, B)/(norm(A)*norm(B))

이 함수를 사용하여 코사인 유사도를 간단히 구할 수 있다.

cos_sim(user_profile, post_profile).item()

numpy를 사용하여 계산한 결과는 ndarray로 반환되기 때문에 item()을 호출하여 실제 유사도 값을 반환할 수 있다.

4. 사용자에게 상품 추천

위 과정을 통해 구한 코사인 유사도를 리스트 형식으로 저장하고 가장 높은 값을 가지는 인덱스를 추출하면 된다. 예를 들어 다음과 같이 구현할 수 있다.

# index와 함께 tuple 형식으로 저장
cosine_similarity = [(index, cosine_similarity_value) for index, cosine_similarity_value in enumerated(cosine_similarity_values)]
# 코사인 유사도 값을 기준으로 내림차 순 정렬
cosine_similarity.sort(key=lambda x: x[1], reverse=True)
# 유사도가 높은 상위 10개 추출
cosine_similarity[:10]
728x90

'Python' 카테고리의 다른 글

Content-based 추천 시스템 구현 (2)  (0) 2024.08.17
[PEP8] Comments  (0) 2022.02.26
[PEP8] When to use trailing commas  (0) 2022.02.25
[PEP8] Whitespace in Expressions and Statements  (0) 2022.02.07
[PEP8] String Quotes  (0) 2022.02.07