Collective Intelligence - Making Recommendations

Chapter 2 : Making Recommendations

다른사람들이 좋아하는 취향을 분석해서 내 취향에 맞게 자동적으로
추천되는 시스템을 만들것입니다. 물론 Python을 이용해서 만들겠습니다.

추천사이트라는 것은 쉽게 도서 구매 사이트에 가서 책을 검색해보면 이책을 구매한 사람이
구매한 다른 책들 목록이 나오는 것과 비슷한 기능을 합니다. 
즉 내가 사려는 책의 취향에 맞게 다른 책들을 추천하는 것입니다.

여기서는 Collaborative Filtering 기법을 사용할 것입니다.
Collaborative Filtering 기법은 협력적 필터링 이라고도 합니다.
이제 사용하려는 것과 같은 고객의 관심을 분석한후 비슷한 취향의 사람들에게 상품을 추천하도록 할때
주로 사용됩니다.

이것을 하기 위해서는 기존의 고객들이 어느정도 예측가능한 고객들과 비슷한 패턴을 가진 고객에게만
추천할 수 있을것이며, 추천을 위해서는 기존의 고객들에 대한 정보를 수치화 할 필요가 있습니다.

그렇다면 왜 Collaborative 즉 협력적 방법을 사용하는 것일까요?
다른 많은 방법이 있겠지만, 제 생각에는 한사람만의 고객을 분석해서 다른 사람에게 그 자료를 바탕으로
추천하는 것보다는 여러사람, 가급적이면 많은 사람들의 취향을 분석해서 새로운 사람에게 추천하는것이
조금이라도 더 정확하기때문이라고 생각합니다. 

그럼 이제 추천을 할 수 있는 시스템을 만들어봐야겠습니다.

우선 위에서도 설명했듯이 새로운 고객에게 기존의 고객정보를 기반으로 취향에 맞게 추천을 하기 위해서는
기존 정보에 대한 데이터와 그것을 데이터화하는 기준이 필요할 것입니다.
기존정보에 대한 데이터는 Python의 Dictionary 구조로 만들겠습니다.
그리고 데이터화하는 기준, 즉 기존의 사람들이 나와 얼마나 비슷한지에 대한 것을 측정하는 기준으로는
두가지의 방법을 설명하겠습니다.

일단, 파이썬으로 만드는 사전(Dictionary)식 구조를 말하자면
critics={'Word':'mean','word2':'mean2'} 
형식으로 되어있습니다. critics라는 변수에 저장을 하는데 그 구조는 사전과 비슷하게
word - mean 
word2 - mean2 
라고 입력하는것과 같습니다. 구분은 : (콜론)으로 합니다.

실행화면을 보는것과 같이 사전처럼 word를 물으면 그뜻인 mean을 출력해줍니다.

그럼 이제 데이터를 저장해보면

critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 
 'The Night Listener': 3.0},
'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 
 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 
 'You, Me and Dupree': 3.5}, 
'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,
 'Superman Returns': 3.5, 'The Night Listener': 4.0},
'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,
 'The Night Listener': 4.5, 'Superman Returns': 4.0, 
 'You, Me and Dupree': 2.5},
'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 
 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,
 'You, Me and Dupree': 2.0}, 
'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},
'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}

이렇게 입력합니다. 사전 구조가 중복 되어서도 똑같이 적용됨을 알수있을것입니다.
그럼 파이썬에서 입력한후 값을 확인해보겠습니다.

그림에서 보는것과 같이 Toby에 대한 정보를 얻기위해서  
  >>> critics['Toby'] 라고 입력을 했더니 Toby에 대한 정보가 제대로 들어가있음을 볼수있습니다.

그럼 이제 데이터를 얻었으니 사람들 사이에 얼마나 비슷한 관계가 있는지를 찾아보겠습니다.
그것을 찾기위해서는 앞서 말했듯이 사람들 사이의 관계를 측정해야 하는데 우리는 두가지 방법을 사용합니다.

Euclidean Distance 방법
Pearsion Correlation 방법 입니다.

유클리드 방법을 말하자면
사람들이 측정한 영화에 대한 평면을 만든후 사람들이 그것에 대하여 측정한 점을 찍고 그 점들간의 거리를
두점간의 거리 구하는 공식과 비슷하게 측정하는 것입니다.

그림처럼 Snakes와 Dupre라는 영화에 대하여 사람들이 준 점수에 따라 점을 찍습니다.

두점사이 거리 구하는 공식이라고 하면 다들 잘 알고있을 것입니다.
P=(p1,p2)와 Q=(q1,q2) 라고 주어졌다면.
  sqrt(pow(p1-q1,2)+pow(p2-q2,2))  (sqrt는 루트를, pow는 제곱을 나타냅니다.)
이렇게 해서 구한 거래의 값이 클수록 비슷하다고 생각하겠지만 한계가 없다면
그것을 측정하기가 조금 힘이 들것입니다. 따라서 우리는 이 공식을 약간 변형을 해서
구해진 값의 범위를 0 부터 1까지로 오도록 합니다.
즉 아까구한값을 Ed 라고 한다면 1/(1+ed)를 하면 될것입니다. 1+ed를 하는 이유는 분모가 0이면 무한대로
원하지 않는 값이 나오니까 가장작은 ed값이 0이 나올때에도 구해지는 값은 1이 되도록 하기 위해서입니다.


파이썬으로 실행한 결과입니다. 변형전에는 3.1이라는 값이 나와서 이값이 큰값인지 작은 값인지를
정확히 알수 없었지만 변형된 공식으로 사용하니 0.24가 나와서 0에 가까운 값이라는 것을 쉽게 알수 있습니다.

그럼 이제 유클리드 거리를 측정하는 파이썬 함수를 구현하면

def sim_distance(prefs,person1,person2):
    si={}
    for item in prefs[person1]:
          if item in prefs[person2]:
               si[item]=1
    if len(si)==0: return 0
    sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2)
                          for item in prefs[person1] if item in prefs[person2]])
    return 1/(1+sum_of_squares)

        
코드에는 앞서 설명한 것들이 그대로 반영되어 있습니다.
파이썬에서는 다른 언와 달리  { } 함수 영역을 구분하지 않고 들여쓰기를 하기때문에 들여쓰기가 중요합니다.

위의 그림을 보면 알 수있듯이 들여쓰기는 굉장히 중요하다.
또한 값이 0.143으로 나온것으로 보니 그렇게 비슷한 취향을 아닌가 보다.
(측정하는 값은 Lisa와 Gene가 공통으로 점수를 매긴 영화들만 해당된다.)

그럼 이것으로 유클리드 측정법을 사용한 거리 측정은 마치겠습니다.
피어슨(Pearson) 방법으로의 측정은 다음에..

'프로그래밍' 카테고리의 다른 글

WinDbg 출력 결과를 파일로 보내자  (0) 2010.01.07
IME를 강제로 활성, 비활성 시키기  (0) 2009.12.24
C# - Property  (0) 2009.12.24
Python - Beautiful Soup  (2) 2009.12.24
SCJP 5.0 관련 자료 모음  (0) 2009.12.24