제2장에서는 밀접하게 관련된 것을 찾아내는 방법을 논의했으므로, 예를 들어 영화에 대한 취향을 공유하는 사람을 찾을 수 있었다. 이 장에서는 이러한 아이디어를 확장하고 데이터 클러스터링, 즉 모두 밀접하게 관련된 사물, 사람 또는 아이디어의 그룹을 발견하고 시각화하는 방법을 소개한다. 이 장에서는 다양한 소스에서 데이터를 준비하는 방법, 두 개의 서로 다른 클러스터링 알고리즘, 더 많은 거리 메트릭, 생성된 그룹을 보기 위한 간단한 그래픽 시각화 코드, 그리고 마지막으로 매우 복잡한 데이터 세트를 2차원으로 투사하는 방법을 배우게 될 것이다.


클러스터링은 데이터 집약적인 애플리케이션에서 자주 사용된다. 고객 구매를 추적하는 소매업체는 이 정보를 사용하여 일반 인구통계 정보와 더불어 유사한 구매 패턴을 가진 고객 그룹을 자동으로 감지할 수 있다. 비슷한 연령과 수입을 가진 사람들은 매우 다른 스타일의 옷을 가지고 있을지 모르지만, 군집을 사용함으로써 "패션 아일랜드"를 발견하고 소매나 마케팅 전략을 개발하는데 사용할 수 있다. 클러스터링은 또한 유사한 행동을 보이는 유전자 집단을 찾기 위해 컴퓨터 생물학에 많이 사용되는데, 이것은 그들이 같은 방식으로 치료에 반응하거나 같은 생물학적 경로의 일부임을 나타낼 수 있다.


이 책은 집단지성에 관한 것이기 때문에, 이 장의 예들은 많은 사람들이 다른 정보를 기부하는 출처에서 나온 것이다. 첫 번째 예에서는 블로그, 그들이 토론하는 주제, 그리고 블로그를 텍스트에 따라 그룹화할 수 있고 단어들이 그들의 사용법에 따라 그룹화될 수 있다는 것을 보여주기 위한 그들의 특정한 단어 사용법을 살펴볼 것이다. 두 번째 예는 사람들이 자신이 소유하고 싶은 것과 소유하고 싶은 것을 나열하는 커뮤니티 사이트를 볼 것이며, 우리는 이 정보를 사용하여 사람들의 욕망이 어떻게 군집으로 분류될 수 있는지를 보여줄 것이다.


감독 학습 대 감독되지 않은 학습

예시 입력과 출력을 사용하여 예측 방법을 학습하는 기법을 감독 학습 방법이라고 한다. 우리는 이 책에서 신경망, 의사결정 나무, 지원 벡터 기계, 베이시안 필터링을 포함한 많은 감독된 학습 방법을 탐구할 것이다. 이러한 방법을 사용하는 애플리케이션은 입력 및 예상 출력을 검사하여 "학습"한다. 이러한 방법 중 하나를 사용하여 정보를 추출하고자 할 때, 우리는 일련의 입력값을 입력하여 응용 프로그램이 지금까지 학습한 것에 근거하여 출력을 생성하기를 기대한다.


클러스터링은 감독되지 않는 학습의 한 예다. 신경망이나 의사결정 나무와는 달리, 감독되지 않는 학습 알고리즘은 정답의 예를 가지고 훈련되지 않는다. 그들의 목적은 한 조각의 데이터도 해답이 되지 않는 데이터 집합 내에서 구조를 찾는 것이다. 앞서 제시된 패션 사례에서, 이 군집들은 소매상들에게 개인이 무엇을 살 가능성이 있는지 말하지 않으며, 새로운 사람이 어떤 패션 섬에 적합한지에 대한 예측도 하지 않는다. 알고리즘을 클러스터링하는 목적은 데이터를 가져다가 그 안에 존재하는 개별적인 그룹을 찾는 것이다. 그 밖에 감독되지 않은 학습의 예로는 10장에서 논의될 비음수 행렬 인자화 및 자가조직화 맵이 있다.


워드 벡터

클러스터링을 위해 데이터를 준비하는 일반적인 방법은 항목을 비교하는 데 사용할 수 있는 공통의 숫자 속성 집합을 결정하는 것이다. 이는 평론가들의 순위를 일반적인 영화 세트와 비교했을 때와 책갈피의 유무를 del.icio.us 사용자들의 경우 1 또는 0으로 번역했을 때 제2장에서 보여진 것과 매우 유사하다.


피전홀딩 더 블로거

이 장에서는 몇 가지 예제 데이터셋을 살펴보기로 한다. 첫 번째 데이터 집합에서 클러스터링될 항목은 상위 블로그의 120개 집합이며, 클러스터링될 데이터는 각 블로그의 피드에 특정 단어 집합이 나타나는 횟수이다.


워드 빈도에 기반한 블로그를 클러스터링함으로써 유사한 주제에 대해 자주 쓰거나 비슷한 스타일로 글을 쓰는 블로그 그룹이 있는지 판단할 수 있을 것이다. 그러한 결과는 현재 온라인 상태인 엄청난 수의 블로그를 검색하고, 분류하고, 발견하는데 매우 유용할 수 있다.


이 데이터 세트를 생성하려면 블로그 집합에서 피드를 다운로드하고, 항목에서 텍스트를 추출하고, 워드 빈도 표를 작성하십시오. 데이터 집합을 생성하는 단계를 건너뛰고 싶다면  clusters 클러스터/블로그 데이터에서 데이터 집합을 다운로드하자.


피드 내 단어 수

거의 모든 블로그는 온라인으로 또는 RSS 피드를 통해 읽을 수 있다. RSS 피드는 블로그와 모든 항목에 대한 정보를 포함하는 간단한 XML 문서다. 각 블로그에 대한 워드 수를 생성하는 첫 번째 단계는 이러한 피드를 분석하는 것이다. 다행히도, 이것을 할 수 있는 훌륭한 모듈이 있는데, 당신은 http://www.feedparser.org에서 다운로드할 수 있다.


import feedparser

import re

# Returns title and dictionary of word counts for an RSS feed

def getwordcounts(url):

 # Parse the feed

 d=feedparser.parse(url)

 wc={}

 # Loop over all the entries

 for e in d.entries:

 if 'summary' in e: summary=e.summary

 else: summary=e.description

 # Extract a list of words

 words=getwords(e.title+' '+summary)

 for word in words:

 wc.setdefault(word,0)

 wc[word]+=1

 return d.feed.title,wc


이 모듈은 RSS 또는 Atom 피드로부터 제목, 링크 및 항목을 쉽게 얻을 수 있도록 해준다. 다음 단계는 피드에서 모든 단어를 추출하는 기능을 만드는 것이다. generatefeedvector.py이라는 새 파일을 생성하고 다음 코드를 삽입하자.


def getwords(html):

 # Remove all the HTML tags

 txt=re.compile(r'<[^>]+>').sub('',html)

 # Split words by all non-alpha characters

 words=re.compile(r'[^A-Z^a-z]+').split(txt)

 # Convert to lowercase

 return [word.lower( ) for word in words if word!='']


RSS 및 Atom 피드는 항상 제목과 항목 목록을 가지고 있다. 각 항목에는 일반적으로 항목의 실제 텍스트가 포함된 요약 또는 설명 태그가 있다. getwordcounts 함수는 이 요약을 getwords에 전달하며, 이 요약은 모든 HTML을 삭제하고 알파벳이 아닌 문자로 단어를 분할하여 목록으로 반환한다. 


이제 작업하려면 피드 목록이 필요할 것이다. 원하는 경우 블로그 집합에 대한 피드 URL 목록을 직접 생성하거나 100개의 RSS URL로 미리 작성된 목록을 사용할 수 있다. 이 목록은 가장 많이 참조되는 모든 블로그에 대한 피드를 가져다가, 해당 블로그의 전체 텍스트를 포함하지 않거나 대부분 이미지인 블로그를 제거함으로써 만들어졌다. 목록은 http://kiwitobes.com/clusters/feedlist.txt에서 다운로드할 수 있다.


이것은 각 줄에 URL이 있는 일반 텍스트 파일이다. 만약 여러분이 여러분 자신의 블로그나 몇몇 특정한 좋아하는 블로그를 가지고 있다면, 여러분은 그 블로그들이 가장 인기 있는 블로그와 어떻게 비교되는지 보고 싶다면, 여러분은 그것들을 이 파일에 추가할 수 있다.


피드를 루핑하고 데이터 세트를 생성하기 위한 코드는 generatefeedvector.py(즉, 함수가 아님)의 주 코드가 될 것이다. 코드의 첫 부분은 피드리스트의 모든 라인에 걸쳐 있다.각 단어가 (apcount)에 나타난 블로그의 수뿐만 아니라 각 블로그에 대한 단어 수를 확장하고 생성한다. generatefeedVector 끝에 이 코드를 추가하자.


apcount={}

wordcounts={}

for feedurl in file('feedlist.txt'):

 title,wc=getwordcounts(feedurl)

 wordcounts[title]=wc

 for word,count in wc.items( ):

 apcount.setdefault(word,0)

 if count>1:

 apcount[word]+=1


다음 단계는 각 블로그의 개수에 실제로 사용될 단어 목록을 생성하는 것이다. "더"와 같은 단어는 거의 모든 단어에서 등장할 것이고, "플림 플램"과 같은 단어들은 한 단어에서만 나타날 수 있기 때문에, 여러분은 최대와 최소 백분율 내에 있는 단어들만 선택하여 포함된 전체 단어 수를 줄일 수 있다. 이 경우, 하한선으로는 10%, 상한선으로는 50%로 시작할 수 있지만, 흔한 단어나 이상한 단어가 너무 많이 나타난다면 이 숫자들을 실험해 볼 가치가 있다.


wordlist=[]

for w,bc in apcount.items( ):

 frac=float(bc)/len(feedlist)

 if frac>0.1 and frac<0.5: wordlist.append(w)


마지막 단계는 단어 목록과 블로그 목록을 사용하여 각 블로그에 대한 모든 단어 수의 큰 매트릭스를 포함하는 텍스트 파일을 만드는 것이다.


out=file('blogdata.txt','w')

out.write('Blog')

for word in wordlist: out.write('\t%s' % word)

out.write('\n')

for blog,wc in wordcounts.items( ):

 out.write(blog)

 for word in wordlist:

 if word in wc: out.write('\t%d' % wc[word])

 else: out.write('\t0')

 out.write('\n')


워드 카운트 파일을 생성하려면 명령줄에서 generatefeedvector.py을 실행하자.


c:\code\blogcluster>python generatefeedvector.py


이러한 모든 피드를 다운로드하는 데는 몇 분이 걸릴 수 있지만, 이것은 결국 블로그 데이터라는 출력 파일을 생성하게 될 것이다.txt. 이 파일을 열어 단어 열과 블로그 행이 있는 탭 구분 테이블이 있는지 확인하십시오. 이 파일 형식은 이 장의 기능에 의해 사용되므로 나중에 다른 데이터 세트를 생성하거나 제대로 포맷된 스프레드시트를 이러한 클러스터링 알고리즘을 사용할 탭 구분 텍스트 파일로 저장할 수 있다.

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