본문 바로가기

추천 시스템 | Recommender System

추천 시스템 05. Item-based Collaborative Filtering 아이템 기반 협업 필터링

안녕하세요, 수달이입니다 😊. 지난번 포스팅에서 다룬 유저 기반 협업 필터링의 단점을 기억하시나요?

 

바로 확장성(scalability)이 부족하다는 점이었죠. 거대 웹사이트들에게는 수백만의 유저를 대상으로 유저 간의 유사성을 연산하는 것이 다소 부담스러울 수 있습니다. 그래서 미국의 이커머스 기업인 아마존은 이러한 한계를 극복하고자 유저 기반 협업 필터링을 대체할 새로운 방법, 아이템 기반 협업 필터링 Item-based Collaborative Filtering을 개발했는데요. 이번 포스팅에서는 이 알고리즘에 대해 얘기해보겠습니다.

그거 산 사람들은 이것도 사던데?

 

출처: 쿠팡 웹사이트 캡쳐

 

인터넷 쇼핑 자주 하시나요? 코로나가 시작된 이후 저는 식재료를 포함하여 거의 모든 것을 택배로 받아보고 있는데요. 필요한 것만 딱 구매하는 현명한 소비를 하려고 했는데, 위의 그림과 같은 유혹에 넘어갈 뻔한 적이 한두 번이 아닙니다. 햇반만 사려고 했는데.. 김이랑 고추참치를 햇반이랑 같이 산 사람들이 많다고 하니.. 왠지 같이 먹으면 너무 맛있을 것 같단 말이죠. 그렇게 장바구니 금액은 계속 늘어납니다.

 

"그거 산 사람들은 이것도 사던데?"라는 군중심리를 건드리는 멘트. 이것이 바로 아이템 기반 협업 필터링의 핵심입니다. 다시 말해, "내가 사려는 상품과 같이 자주 팔리는 상품"을 찾는 것이 목적이죠. 예를 들면, 편의점에서 맥주 코너 바로 옆에 오징어나 견과류를 배치하는 느낌이랄까요.

 

이쯤이면 아마 지난 포스팅에서 배운 유저 기반 협업 필터링과 정확히 뭐가 다른 건지 헷갈리는 분들이 있을 것 같습니다. 유저 기반 협업 필터링은 나와 취향이 비슷한 사람들의 장바구니를 분석합니다. 여러 아이템에 걸쳐 나와 비슷한 구매패턴을 보이는 사람들이 필요하죠. 하지만 아이템 기반 협업 필터링에서는 "전반적인 취향/소비패턴"을 고려하진 않습니다. 그저 내가 사려고 하는 아이템 A를 이미 구매한 사람이라면 분석대상에 들어가죠.

 

아래의 유저-아이템 매트릭스를 보시면 그 차이를 더 쉽게 느끼실 수 있습니다. 유저 기반 협업 필터링에서는 유저를 n 개의 아이템으로 구성된 벡터로 표현하고 유저 벡터 간의 유사성을 측정했습니다. (즉, 매트릭스 행 간의 유사성을 계산). 반면, 아이템 기반 협업 필터링은 아이템을 n 명의 유저로 구성된 벡터로 표현하고 아이템 간의 유사성을 계산합니다. (즉, 매트릭스 열 간의 유사성을 계산).

 

 

코사인 유사도를 활용하여 추천 상품 찾기

STEP 1. 비슷한 아이템 찾기

아이템 간의 유사성을 계산한다라... 뭔가 우리가 지금껏 배웠던 벡터의 유사성을 구하는 테크닉들을 그대로 사용할 수 있지 않을까요?

 

그렇습니다. 컨텐츠 기반 필터링에서 배웠던 벡터의 내적(inner product), 그리고 유저 기반 협업 필터링에서 배웠던 피어슨 상관계수(Pearson Correlation) 모두 아이템 벡터 간의 유사성을 구하는데 쓰일 수 있습니다. 하지만 오늘은 또 다른, 새로운 방법을 배워보도록 하겠습니다. 바로, 코사인 유사도 cosine similarity입니다.

 

코사인 유사도는 이름에서 알 수 있듯, 두 벡터 간의 코사인 값을 측정합니다. 코사인 그래프를 기억하신다면, 각도가 0일 때 코사인은 1의 값을 갖고, 각도가 180도일 때 -1의 값을 갖습니다. 다시 말해, 두 벡터 간의 각도가 0이라면, 두 벡터는 사실 동일한 벡터이므로 유사성은 1이 되고, 두 벡터 간의 각도가 180도라면, 두 벡터는 정반대의 방향을 가리키고 있으므로 유사도가 -1이 됩니다.

 

 

조금 더 깊이 들어가자면, 사실 코사인 유사도와 내적은 한 끗 차이입니다. 두 벡터의 내적 값을 각 벡터의 길이로 나누면 바로 코사인 유사도를 얻을 수 있기 때문이죠. 이러한 나눗셈 덕분에, 내적은 벡터의 절대적 길이에 영향을 받는 반면, 코사인 유사도는 벡터의 길이가 어떻든 전혀 상관이 없습니다.

 

아래의 그림으로 예를 들자면, (a)와 (b)는 두 벡터 사이의 각도가 동일하지만 (b) 벡터들이 (a) 벡터들에 비해 더 길기 때문에 더 큰 내적 값을 갖습니다. 즉, 각도가 동일함에도 불구하고 (b)의 벡터쌍이 서로 더 유사하다는 결과가 나오죠. 하지만 각 벡터의 절대적 길이로 나눗셈을 해준 코사인 유사도는 동일한 값을 갖습니다. 즉, 코사인 유사도를 기준으로 하면, 두 벡터의 유사성은 동일합니다. '그럼 코사인 유사도가 우월한 방법 아닌가?'라고 생각하실 수 있지만, 절대적인 답은 없습니다. 상황에 따라, 벡터의 절대적 길이를 고려하고 싶다면 내적을, 그렇지 않다면 코사인 유사도를 사용하면 됩니다.

 

 

그럼 다음 스텝으로 넘어가기 전에 예제를 가지고 코사인 유사도를 직접 계산해보도록 하겠습니다.

 

 

아이템 A & 아이템 B: 두 아이템을 동시에 구매한 유저는 유저 1과 유저 2이므로 이들의 평점을 이용해서 벡터를 구성합니다. 즉,

$$ A = [3,5],\quad B = [3,4] $$

$$ Sim(A, B) = \frac{(3*3 + 5*4)}{\sqrt{9+25} + \sqrt{9+16}} = 2.70$$

 

아이템 A & 아이템 C: 두 아이템을 동시에 구매한 유저는 유저 1과 유저 3이므로 이들의 평점을 이용해서 벡터를 구성합니다. 즉,

$$ A = [3,4],\quad C = [5,1] $$

$$ Sim(A, C) = \frac{(3*5 + 4*1)}{\sqrt{9+16} + \sqrt{25+1}} = 1.88$$

 

이로써 아이템 A와 가장 비슷한 아이템은 더 높은 코사인 유사도를 보인 아이템 B인 것을 알 수 있습니다. 같은 방법으로 아이템 B와 아이템 C 사이의 코사인 유사도도 구할 수 있겠죠? 이건 여러분에게 맡기도록 하겠습니다. :)

 

STEP 2: 아이템 별 평점 예측하기

이제 아이템 간 유사성을 측정하는 방법을 알았으니, 이 도구를 활용하여 아이템 별 예상 평점을 구해볼까요? 우선 다음과 같이 평점 데이터가 있다고 가정하겠습니다.

 

 

우리가 궁금한 것은 수달이가 아이템 C에 몇 점을 줄 것인가입니다. 첫 번째로 할 일은 수달이가 이미 평점을 준 아이템들을 찾아내는 것입니다. 위의 테이블을 기준으로 하면 아이템 A, B, D가 되겠네요. 그럼 STEP 1에서 배운 코사인 유사도를 활용하여 아이템 C와 각 아이템 간의 유사도를 계산합니다. 그리고 이 유사도를 가중치로 사용하여 가중평균을 내면 아이템 C에 대한 예상 평점이 나옵니다.

 

$$ rating(C) = \frac{rating(A)\cdot sim(C,A) + rating(B) \cdot sim(C,B) + rating(D) \cdot sim(C, D)}{sim(C,A) + sim(C,B) + sim(C,D)}$$

 

이런 방식으로 우리는, 수달이가 아직 평점을 남기지 않은 모든 아이템에 대해 점수를 예측할 수 있습니다.

 

STEP 3: 예상 평점이 높은 아이템 추천하기

자, 이제 가장 쉬운 단계만 남았군요. STEP 2에서 구한, 수달이가 아직 접하지 못한 상품들의 예상 평점을 쭈욱 내림차순으로 정렬하여 가장 상위에 있는 아이템 몇 가지를 추천 상품으로 제시합니다.

 

장점과 단점

아마존이나 넷플릭스 같은 거대 웹사이트에서는 보통 가입 유저의 수가 보유한 상품/컨텐츠의 수보다 비교할 수 없을 정도로 많습니다. 그리고 상품/컨텐츠가 늘어나는 속도보다 신규 유저가 생기는 속도가 더욱 빠르죠. 즉, 유저 Pool은 크기도 크고 변화 속도도 빠른 반면 아이템 Pool은 상대적으로 크기도 작고 변화 속도도 안정적입니다.

 

아이템 기반 협업 필터링이 유저 기반 협업 필터링에 비해 확장성 및 효율적 연산 측면에서 유리한 이유가 바로 여기에 있죠. 위의 특성 때문에, 비슷한 유저를 찾으려면 (유저 기반 협업 필터링을 하려면) 유사도 연산을 한 번에 많이 그리고 매번 수행해야 하지만, 비슷한 아이템을 찾기 위한 (아이템 기반 협업 필터링을 위한) 유사도 연산은 오프라인으로 미리 수행해두고 필요시에 결과값만 불러오는 방식으로 더 빠르게 처리할 수 있습니다.

 

이처럼 아이템 기반 협업 필터링은 유저 기반 협업 필터링의 확장성 문제를 해결했지만, 콜드 스타트 cold-start 문제는 극복하지 못했습니다. 신상품은 구매를 하거나 평점을 남긴 고객이 아무도 없기 때문에 비슷한 아이템을 찾는 연산 과정에 포함될 가능성이 없습니다. 따라서 추천 결과에도 포함될 수가 없죠. 꼭 신상품이 아니더라도 구매/평점 데이터가 희소한 상품이라면 (예를 들어, 두 아이템을 모두 구매/평가를 한 고객이 없는 경우) 유사성 연산을 할 수 없고, 결과적으로 추천 리스트에 포함될 가능성이 희박합니다.

 

다음 포스팅: Netflix Prize Compeition을 평정한 행렬 분해 (Matrix Factorization) 추천 시스템

오늘 소개했던 아마존의 아이템 기반 협업 필터링은 사실 1998년도에 개발된 무려 20년이 넘은 시스템입니다. 그 이후 협업 필터링의 퍼포먼스를 향상시키기 위한 많은 노력이 있었는데요. 특히 2006년도에 처음 시행된 넷플릭스의 Prize Competition은 더 발전된 추천 시스템의 탄생을 이끌었습니다. 그중에서도 가장 주목을 많이 받았던 알고리즘은 행렬 분해 Matrix Factorization이었는데요. 이름만 들어도 조금 어렵게 느껴지는데.. 다음 포스팅에서 쉽고 자세하게 설명드리도록 하겠습니다.

 

그럼 그때까지 안녕히 계세요! Happy Machine Learning! ت

 

 

아이템 기반 협업 필터링 Item-based Collaborative Filtering
1/ 아이템을 n명의 유저로 구성된 벡터로 표현
2/ 코사인 유사도를 활용하여 다른 아이템과의 유사성 확인
3/ 유사한 아이템들의 평점을 가중 평균하여 (코사인 유사도를 가중치로 사용) 평점을 예측하고, 예측값이 높은 순으로 추천

* 아마존의 논문 원문을 읽고 싶은 분들은 여기를 클릭해주세요 👉 Amazon.com Recommendations