집단지성의 투어를 시작하기 위해, 나는 당신에게 다른 사람들에게 추천을 하기 위해 사람들의 그룹의 선호를 사용하는 방법을 보여줄 것이다. 온라인 쇼핑을 위한 제품 추천을 하거나, 흥미로운 웹사이트를 제안하거나, 사람들이 음악과 영화를 찾을 수 있도록 돕는 등 이런 종류의 정보에 대한 많은 어플리케이션이 있다. 이 장에서는 취향을 공유하는 사람을 찾고 다른 사람이 좋아하는 것을 바탕으로 자동 추천을 할 수 있는 시스템을 구축하는 방법을 보여준다.


여러분은 아마 아마존 같은 온라인 쇼핑 사이트를 이용할 때 전에 추천 엔진을 만난 적이 있을 것이다. 아마존은 모든 쇼핑객들의 구매 습관을 추적하고, 당신이 사이트에 접속할 때, 당신이 좋아할 만한 제품을 제안하기 위해 이 정보를 이용한다. 아마존은 심지어 여러분이 좋아하는 영화를 제안할 수도 있다. 비록 여러분이 그 영화로부터 책을 산 적이 있을 지라도 말이다. 일부 온라인 콘서트 티켓 대리점들은 여러분이 전에 본 쇼의 역사를 보고 여러분에게 관심을 가질지도 모르는 다가오는 쇼를 알려 줄 것이다.  reddit.com과 같은 사이트는 당신이 다른 웹사이트로의 링크에 투표한 다음 당신이 흥미롭게 여길 수 있는 다른 링크들을 제안하기 위해 당신의 표를 사용할 수 있게 해준다.


이러한 예에서 선호도를 여러 가지 방법으로 수집할 수 있음을 알 수 있다. 때때로 데이터는 사람들이 구입한 품목이며, 이러한 항목에 대한 의견은 찬성/부표 또는 1부터 5까지의 등급으로 표시될 수 있다. 이 챕터에서는 이러한 사례들이 모두 동일한 알고리즘 집합으로 작동하도록 다양한 표현 방법을 살펴보고, 영화 평론가 점수나 사회적 책갈피로 작업 사례를 만들 겁니다.


협업 필터링

당신은 제품, 영화 또는 오락 웹사이트에 대한 추천을 얻는 저기술적인 방법이 당신의 친구들에게 물어보는 것이라는 것을 알고 있다. 여러분은 또한 여러분의 친구들 중 몇몇은 다른 사람들보다 더 "맛"이 좋다는 것을 알고 있는데, 그것은 그들이 보통 여러분과 같은 것을 좋아하는지 관찰함으로써 여러분이 시간이 지나면서 배운 것이다. 점점 더 많은 선택권이 8 | 제 2 장: 추천서를 사용할 수 있게 되면서, 작은 그룹의 사람들에게 물어봄으로써 당신이 원하는 것을 결정하는 것은 덜 실용적이 된다. 왜냐하면 그들은 모든 선택사항에 대해 알지 못하기 때문이다. 이것이 바로 협력 필터링이라고 불리는 일련의 기술들이 개발된 이유다.


협업 필터링 알고리즘은 대개 많은 사람들을 검색하고 당신의 취향과 비슷한 작은 집합을 찾음으로써 작동한다. 그것은 그들이 좋아하는 다른 것들을 보고 그것들을 결합하여 제안의 순위 목록을 만든다. 어떤 사람들이 비슷한지 결정하고 목록을 만들기 위해 그들의 선택을 결합하는 몇 가지 다른 방법이 있다; 이 장에서는 이들 중 몇 가지를 다룰 것이다.


협업 필터링이라는 용어는 1992년 제록스 PARC에서 데이비드 골드버그가 "협력 필터링을 사용하여 정보 태피스트리를 엮어낸다"는 논문에서 처음 사용되었다. 그는 사람들이 문서를 흥미롭거나 재미없다고 주석을 달 수 있도록 해주는 태페스트리라는 시스템을 설계했고 이 정보를 다른 사람들을 위한 문서를 필터링하는데 사용했다.


현재 영화, 음악, 책, 데이트, 쇼핑, 다른 웹사이트, 팟캐스트, 기사, 그리고 농담에 대한 일종의 협력적 필터링 알고리즘을 사용하는 수백 개의 웹사이트들이 있다.


기본 설정 수집

당신에게 필요한 첫 번째 것은 다른 사람들과 그들의 선호도를 나타내는 방법이다. 파이톤에서 이것을 하는 매우 간단한 방법은 중첩된 사전을 사용하는 것이다. 이 섹션의 예를 살펴보려면 권장 사항.py라는 파일을 생성하고 다음 코드를 삽입하여 데이터 세트를 생성하자.


이 장에서는 Python과 대화식으로 작업할 예정이므로 recommendations.py을 Python 대화형 통역사가 찾을 수 있는 곳에 저장하십시오. 이것은 python/Lib 디렉토리에 있을 수 있지만, 가장 쉬운 방법은 파일을 저장한 디렉토리에서 Python 통역을 시작하는 것이다.


이 사전은 이 영화 비평가들(그리고 나는)이 주어진 영화를 얼마나 좋아하는지를 표현하는 방법으로 1부터 5까지의 순위를 사용한다. 선호도가 어떻게 표현되든, 그것들을 숫자 값에 매핑할 수 있는 방법이 필요하다. 만약 당신이 쇼핑 사이트를 건설하고 있다면, 당신은 누군가 과거에 물건을 샀다는 것을 나타내기 위해 1의 값을 사용하고, 그렇지 않았다는 것을 나타내기 위해 0의 값을 사용할 수 있다. 사람들이 뉴스 기사에 투표하는 사이트의 경우, 표 2-1과 같이 "Disliked", "Didn't Park", "liked"를 나타내는 데 ?1, 0, 1의 값을 사용할 수 있다.


사전 사용은 알고리즘을 실험하고 예시를 위해 편리하다. 사전을 검색하고 수정하는 것은 쉽다. Python 통역기를 시작하고 몇 가지 명령을 사용해 보자.


c:\code\collective\chapter2> python

Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32

Type "help", "copyright", "credits" or "license" for more information.

>>>

>> from recommendations import critics

>> critics['Lisa Rose']['Lady in the Water']

2.5

>> critics['Toby']['Snakes on a Plane']=4.5

>> critics['Toby']

{'Snakes on a Plane':4.5,'You, Me and Dupree':1.0}


사전에서 많은 수의 메모리 기본 설정을 저장할 수 있지만 매우 큰 데이터 세트의 경우 기본 설정을 데이터베이스에 저장하자.


유사한 사용자 찾기

사람들이 좋아하는 것들에 대한 자료를 수집한 후에, 여러분은 사람들이 그들의 취향을 얼마나 닮았는지 결정할 수 있는 방법이 필요하다. 각 사람을 다른 사람과 비교하고 유사점수를 계산하여 이것을 한다. 이를 위한 몇 가지 방법이 있으며, 이 섹션에서는 유사성 점수를 계산하기 위한 두 가지 시스템을 보여드리겠다. 유클리드 거리 및 피어슨 상관 관계.


유클리드 거리 점수

유사점수를 계산하는 아주 간단한 방법 중 하나는 사람들이 공통적으로 순위를 매긴 항목을 도표의 축으로 삼는 유클리드 거리 점수를 사용하는 것이다. 그런 다음 그림 2-1과 같이 사람들을 도표에 표시하여 그들이 얼마나 가까운지 볼 수 있다.


이 그림은 선호 공간에 도표로 표시된 사람들을 보여준다. 토비는 스네이크스 축 4.5와 듀프리 축 1.0에서 플롯되었다. 선호 공간에 두 사람이 가까이 있을수록 선호도는 비슷해진다. 도표가 2차원적이기 때문에 한 번에 두 개의 순위만 볼 수 있지만, 더 큰 순위 집합에 대해서는 원칙이 같다.


도표에서 토비와 라살레 사이의 거리를 계산하려면 각 축의 차이를 취하여 정사각형을 만들어 합한 다음 합계의 제곱근을 취한다. Python에서는 pow(n,2) 함수를 사용하여 숫자를 제곱하고 sqrt 함수로 제곱근을 얻을 수 있다.


>> from math import sqrt

>> sqrt(pow(5-4,2)+pow(4-1,2))

3.1622776601683795


이 공식은 거리를 계산하는데, 이것은 더 비슷한 사람들의 경우 더 작아질 것이다. 하지만 비슷한 사람에게 더 높은 가치를 주는 기능이 필요하다. 이 작업은 기능에 1을 추가하고(그래서 분할 대 0 오류를 얻지 않도록) 반전하여 수행할 수 있다.


>> 1/(1+sqrt(pow(5-4,2)+pow(4-1,2)))

0.2402530733520421


이 새로운 기능은 항상 0과 1 사이의 값을 반환하며, 여기서 1의 값은 두 사람이 동일한 선호도를 갖는다는 것을 의미한다. 모든 것을 종합하여 유사도를 계산하는 함수를 만들 수 있다. 권장 사항에 다음 코드를 추가하자.


from math import sqrt

# Returns a distance-based similarity score for person1 and person2

def sim_distance(prefs,person1,person2):

 # Get the list of shared_items

 si={}

 for item in prefs[person1]:

 if item in prefs[person2]:

 si[item]=1

 # if they have no ratings in common, return 0

 if len(si)==0: return 0

 # Add up the squares of all the differences

 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)


이 기능은 유사점수를 얻기 위해 두 개의 이름으로 호출할 수 있다. Python 통역기에서 다음을 실행하자.


>>> reload(recommendations)

>>> recommendations.sim_distance(recommendations.critics,

... 'Lisa Rose','Gene Seymour')

0.148148148148


이것은 당신에게 리사 로즈와 진 세이무어의 유사점수를 준다. 다른 이름들과 함께 여러분이 어느 정도 공통점이 있는 사람들을 찾을 수 있는지 알아보자.

  • 네이버 블로그 공유하기
  • 네이버 밴드에 공유하기
  • 트위터 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기