cs 추천시스템 Collaborative Filtering(CF) Python 기반 [1]
본문 바로가기
  • 매일 한걸음씩
  • 매일 한걸음씩
개발/Recommender System

추천시스템 Collaborative Filtering(CF) Python 기반 [1]

by 시몬쯔 2020. 4. 27.
728x90
반응형

 

Collaborative Filtering이란 무엇인가?

 



 

위의 그림에서도 알 수 있듯이 특정 사용자 A에게 컨텐츠(영화, 뉴스기사 등)를 추천하고자 할 때 취향이 비슷한 사용자의 취향에 기반해 추천을 하는 것이다. 즉 이제까지 비슷한 컨텐츠를 재생하거나 읽은 사용자라면 비슷한 취향이겠거니 하고 컨텐츠를 추천해주는 것이다.

 

The Dataset

이 알고리즘을 실험해보기 위해서는 item의 집합과 item에 반응하는 users의 집합이 필요하다. 여기서 explicit reaction(평점이나 별점)Implicit reaction(기사에 머무르는 시간, 장바구니 담기 등)으로 반응이 나눠진다.

 

 

위의 Rating Matrix를 예시로 보자. 5명의 사용자의 5개의 아이템에 대한 평가 행렬이다.

각 row는 각 사용자의 평점을 의미하고 각 column은 각 item의 평점을 의미한다.

이 행렬은 간단한 예시이기 때문에 대부분의 행렬 값이 채워져 있지만 실제로는 매우 Sparse한 행렬일 것이다.(즉 행렬이 많이 비워져 있을 것이다.)

 

이 포스팅에서는 MovieLens 100k dataset을 이용하여 코드 구현을 해볼 것이다.

 

Steps Involved in Collaborative Filtering

  1. 유사한 사용자나 아이템을 찾는다.
  2. 사용자가 아직 평가하지 않은 아이템의 평가를 예측한다.

 

 

이를 위해서는 우리는 이 질문들에 대해 고민해봐야한다.

 

  • 사용자나 아이템들의 유사도를 어떻게 측정할 것인가?
  • 유사한 취향을 가진 두 사용자가 있다고 할 때, 한 사용자의 평가에 기반하여 다른 사용자의 평가를 어떻게 결정하나?
  • 우리가 예측한 평가의 정확성을 어떻게 측정하나?

첫번째와 두번째 질문에는 여러 답변이 있을 수 있다. 예를 들어, 유사도에는 dot product, cosine similarity등 여러 방법이 있기 때문이다.

Collaborative Filtering에서 명심할 것은 유사도는 사용자의 나이, 영화의 장르와 같은 요소들로 계산되는 것이 아니다. 유사도는 사용자의 아이템에 대한 평가에 의해 계산된다. 예를 들면, 두 사용자가 10개의 영화에 같은 평가를 내릴 때  둘의 나이차가 크더라도 유사한 취향을 가졌다고 간주한다.

 

세번째 질문은 여러 error calculation 기술들을 사용하여 측정한다. 예를 들면 Root Mean Square Error(RMSE) : Test dataset에 대해 예측한 값과 실제 값을 비교하는 평가, MSE의 root를 취해 구한다. / Mean Absolute Error(MAE) : error의 절대값의 평균을 통해 구한 값 이 있다.

 

Memory Based

Collaborative Filtering에는 여러 방식의 알고리즘이 있는데 첫번째는 메모리 기반의 알고리즘이다.

통계적 방법들을 이용하여 예측하는 방식이다.

 

사용자 U가 아이템 I에 대해 한 평가 R을 찾는 방법은 : 1. 아이템 I에 대해 평가를 한 사용자 U와 비슷한 사용자들을 찾고, 2. 이 사용자들을 기반으로 평가 R을 계산하는 것이다.

 

이 두개의 과정을 자세히 알아보자.

 

1. 기존 평가를 기반으로 어떻게 비슷한 사용자들을 찾나?

 

유사도에 대한 개념을 이해하기 위해 예시를 들어보자.

 

사용자 A,B,C,D가 두 개의 영화에 대해 평가한 데이터가 있다. 

그래프로 시각화해보자면,

이 점으로 표현된 4명의 사용자들의 유사도를 측정한다고 할 때, 

가장 쉽게 생각할 수 있는 방법으로는 유클리디안 distance가 있다.

 

scipy library로부터 간단하게 계산가능하다.

B,C는 눈으로 보기에도 가까워보이고 euclidean distance값으로도 작은 값이니 유사한 사용자라고 할 수 있겠다.

그럼 C는 A,D중에 어느 사용자와 가까울까?

위의 Euclidean distance를 보면 C-A는 2.5고 C-D는 2.2360xx이다. 그럼 D와 더 유사할까?

 

하지만 다시 그림을 보자.

D는 두 영화를 동등하게 좋아하는 대신에 A,C는 두번째 영화를 첫번째 영화의 두배만큼 좋아한다.

이렇게 유클리디안 distance로는 못알아차리는 패턴을 뭘로 알아차릴 수 있을까?

 

각도는 어떨까?

원점과 각각 점들을 연결해보니 각도상으로 C는 사용자 A와 더 유사성을 보이는 것을 알 수 있다.

각도를 계산하기위해서는 cosine 값을 생각할 수 있다. cosine값이 커질수록 각도는 작아진다. 즉 더 유사해진다.

 

아까와 같이 scipy를 이용하여 cosine값을 구해보자.

사용자 A와 B는 다른 평가를 주었지만 cosine상으로는 같은 평가를 내렸다.

사용자A와 같은 사람을 Tough raters라 부르는데 영화 평론가와 같은 사람이다. 항상 평균보다 낮은 점수를 준다. 

사용자B와 같은 사람은 Average raters라 부른다.

 

각 개인의 선호도를 추정하기 위해 그들의 bias를 제거하여 모든 사용자들을 같은 레벨 상으로 둬야한다.

보통 전체 값에서 평균값을 빼는 방법이 있다.

위의 사용자 A를 예시로 들어보면 두 영화에 대해 [1,2]로 평가했는데 1과 2의 평균인 1.5를 빼서

[-0.5,0.5]로 만들 수 있다.

사용자 B는 마찬가지로 [-1,1]로 둘 수 있다.

이 방식을 통해 우리는 각 사용자들의 평가의 평균을 0으로 만들 수 있다. 

이러한 조정을 통해 코사인 값을 구한 걸 centered cosine이라 한다. 이 방법은 많은 missing values가 있을 때 이 값들을 common value로 넣기 위해 쓴다. (centered cosine은 Pearson correlation coefficient라고도 불린다.)

Pearson correlation coefficient

물론 이렇게 common value로 값을 채우면 부정확성이 나타날 수 밖에 없다.

평균값으로 common value를 채우는게 일반적인데 조정하기 전 A의 평균은 1.5, B의 평균은 3이였으므로

각각 1.5와 3으로 값을 채우는 것은 사용자 A와 B를 더 유사하지 않은 사용자로 만든다.

그러나 위의 조정을 통해 값을 바꿔주면 두 사용자 모두 평균이 0이 되므로 평균이상의 item이나 평균이하의 item을 더 잘 측정할 수 있다. 

 

이와같이 Euclidean distance와 cosine 유사도는 우리가 유사한 사용자들을 찾는 방법 중 두 가지이다.

 

 

 

어떻게 평가들을 계산하나?

 

Remind : 메모리 기반의 collaborative filtering은 특정사용자와 유사한 사용자들을 찾아 그 사용자들의 평가를 기반으로 특정사용자의 평가를 계산한다고 했다.

이제 사용자 U가 item I에게 내릴 평가 R을 예측해보자.

 

간단하게는, 사용자 U와 유사한 5명 또는 10명의 평가들의 평균으로 예측할 수도 있다.

 

하지만 유사한 사용자들이더라도 사용자 U와의 유사도는 다를 것이다. 즉, 만약 10명의 유사한 사용자들을 골랐더라도 top 3명은 매우 유사하고 나머지는 별로 유사하지 않을 수도 있다.

이러한 경우에 우리는 weighted average가 필요하다.

 

여기서 weight의 역할을 하는 Similarity factor S는 distance의 역수여야 할 것이다. distance가 클수록 즉 유사도가 떨어질수록 weight를 작게 해야 하기 때문이다.

 

이렇게 메모리 기반의 CF 방법에 대해 살펴봤다. 

이러한 비슷한 사용자들을 찾는 방법 외에 비슷한 아이템을 찾아 평가를 예측하는 방법도 있다.

밑에서 다뤄보자.

 

사용자 기반(User-Based) vs 아이템 기반(Item Based) Collaborative Filtering

위에서 사용한 방법은 user-based or user-user collaborating filtering이라고 불린다.

만약 사용자들이 기존의 아이템들에게 평가한 평점을 기반으로

비슷한 아이템을 찾는데에 Rating 행렬을 사용하는 방법은 item-based or item-item collaborative filtering이라 한다.

 

  • 사용자 기반(User-Based) : 사용자 U에 대해 rating matrix를 기반으로 비슷한 사용자들의 집합을 이용해 아직 사용자 U가 평가하지 않은 아이템 I에 대한 평가를 예측한다. 위에서 설명한바와 같이 item I를 이미 평가한 U와 유사한 사용자들 중에 N명을 고르고 이 N명의 평가들을 이용해 예측한다.

사용자 기반 CF

 

  • 아이템 기반(Item-Based)아이템 I에 대해 기존 평가들을 기반으로 유사한 아이템들의 집합을 고르고 아직 I에 대해 평가하지 않은 사용자 U의 평가는 사용자 U가 이미 평가한 아이템들 중 I와 유사한 N개의 아이템들을 골라 이 N개의 아이템에 대한 U의 평가를 기반으로 I에 대한 사용자 U의 평가를 예측한다.

 

아이템 기반 CF

아이템 기반의 CF는 아마존에 의해 개발됐는데 아마존에서는 아이템보다 사용자들이 더 많을때 아이템기반 필터링이 더 빠르고 안정적이라고 한다. 왜냐면 한 아이템의 평균 평점은 한 사용자의 다른 아이템들에 대한 평균 평점들보다 빨리 변하지 않기 때문이다. 즉 한 아이템은 수많은 사용자들에 의해 평점이 내려지는데 그 평점은 그리 변동이 심하지 않다. 그러나 한 사용자가 여러 아이템에 대해 내린 평점은 들쑥날쑥하기 때문에 평균이 계속해서 변할 가능성이 크다.

 

또, rating matrix가 sparse할 때 즉 빈 값이 많을 때 더 잘 작동한다.

 

그럼에도 불구하고 아이템 기반의 방법은 영화 데이터셋에는 잘 작동하지 않는다. 예를 들어 넷플릭스...

왜일까? 이러한 데이터셋에서는 Matrix Factorization 또는 hybrid recommenders 기술이 더 잘 작동한다.

 

이에 대해서는 다음 포스팅에서 다룰 예정이다.

 

 

참고자료:

https://realpython.com/build-recommendation-engine-collaborative-filtering/

728x90
반응형

댓글