python 및 머신러닝/집단지성 프로그래밍
[Programming Collective Intelligence] - 집단지성 프로그래밍 3장 군집발견
java개발자
2015. 8. 24. 16:01
# -*- coding: utf-8 -*- from myutil import consolePrintWithLineNumber as c ''' Created on 2015. 8. 24. @author: Administrator ''' # 3장 군집발견 # 56p # 3-2 단어 벡터 (자료수집) ''' http://kiwitobes.com/clusters/blogdata.txt 링크는 깨졌다-_-; http://kiwitobes.com/clusters/feedlist.txt 링크도 깨졌다. > 저자의 원본소스파일 안에서 찾을 수 있음 ''' import feedparser import re # rss url을 분석해서 단어별 출현횟수를 딕셔너리로 출력한다. def getwordcounts(url): d = feedparser.parse(url) wc = {} for e in d.entries: if 'summary' in e: summary = e.summary else: summary = e.description words = getwords(e.title + ' ' + summary) for word in words: wc.setdefault(word, 0) # wc에 word가 없는 경우만 0으로 하는 것 같다. wc[word] += 1 return d.feed.title, wc # def getwords(html): txt = re.compile(r'<[^>]+>').sub('', html) # HTML tags 삭제 # words = re.compile(r'[^A-Z^a-z]+').split(txt) # 알파벳 이외의 문자(공백, 특수문자 등등)로 자르기. 헉!! 한글은...??? words = re.compile(r'[^A-Z^a-z^ㄱ-ㅎ^ㅏ-ㅣ^가-힣]+').split(txt) # 한글도 단어에 포함할 수 있도록 하기!!! return [word.lower() for word in words if word != ''] # c(getwordcounts('http://radar.oreilly.com/index.rdf')) # 성공!! # c(getwordcounts('http://electro85.blog.me/220072783373')) # 일반적인 네이버 블로그는 실행하면 에러난다. > rss의 형식에 맞지 않나보다 ''' 네이버 블로그는 /rss 를 붙이면 rss 로 조회가능 - 그런데 글 전체 내용이 나오지는 않는다.summary로... http://electro85.blog.me/rss http://electro85.blog.me/rss/1 http://electro85.blog.me/rss/atom ''' # c(getwordcounts('http://electro85.blog.me/rss')) # c(getwordcounts('http://blog.rss.naver.com/camping2172.xml')) # 책의 소스와 조금 다르다. def practice0(filename): apcount = {} wordcounts = {} feedlist = [line for line in open(filename, 'r', encoding='UTF-8')] testcount = 0; for feedurl in feedlist: # 테스트로 몇개만 해보자 if testcount > 5: break; testcount += 1 try: title, wc = getwordcounts(feedurl) wordcounts[title] = wc for word, count in wc.items(): apcount.setdefault(word, 0) if count > 0: # count 가 0인 경우는 없다. 항상 성립. (혹시나 스파스가 아닌 경우를 고려한 것인가??-코딩더매트릭스3장86p - 아이템이 없는 경우 0으로 출력한 것을 sparsity를 유지하지 않는 다고 말한다.) apcount[word] += 1 c('Succeeded to parse feed %s' % feedurl) except: c('Failed to parse feed %s' % feedurl) # 단어 빈도에 따라 제외 작업 wordlist = [] for w, bc in apcount.items(): # frac = float(bc) / len(feedlist) frac = float(bc) / testcount # test한 개수만 사용하기 때문에 if frac > 0.1 and frac < 0.5: wordlist.append(w) # else: # c(w + ' is not included. for ' + str(frac) + ' bc: ' + str(bc)) #단어 빈도 확인하기 위해 # 결과를 파일로 저장 # 처음 작동하면, 문서캐릭터셋이 MS949로 생성되어서 한글이 깨진다. -_-;; 직접 캐릭터셋을 바꿔주고 다시 하면 그 다음부터는 UTf-8이 유지된다. 이클립스에서 만들어서 그런가? 그러네.. 이클립스 프로젝트 캐릭터셋을 바꿔주면, 정상 동작 out = open('blogdata1.txt', 'w', encoding='UTF-8') # 상단 첫줄 출력(단어 목록) out.write('Blog') for word in wordlist: out.write('\t%s' % word) out.write('\n') # 두번째 줄부터 왼쪽에 블로그명, 오른쪽에 각 단어별 출현횟수 for blog, wc in wordcounts.items(): c(blog) out.write(blog) for word in wordlist: if word in wc: out.write('\t%d' % wc[word]) else: out.write('\t0') out.write('\n') practice0('feedlist.txt') ''' 현재 블로그의 단어 빈도까지 포함해서 평균을 내는 것은 정확도가 떨어진다. 특정 단어의 출현이 다수 발생하는 이유가 the, she가 아니라 정말 그 블로그의 주제어 일 수 있기 때문에 단어 빈도에 따라 특정 단어를 제외하는 로직은 다음과 같이 정의 할 수 있다. 현재 블로그를 제외한 99개의 블로그에서 단어 리스트를 추출해서 다수 출현하는 단어 빈도를 조사. 현재 블로그의 단어빈도와 비교해서 제외 출처 : 머신러닝 인 액션 '''
77 > Succeeded to parse feed http://feeds.feedburner.com/37signals/beMH 77 > Succeeded to parse feed http://feeds.feedburner.com/blogspot/bRuz 79 > Failed to parse feed http://battellemedia.com/index.xml 77 > Succeeded to parse feed http://blog.guykawasaki.com/index.rdf 77 > Succeeded to parse feed http://blog.outer-court.com/rss.xml 77 > Succeeded to parse feed http://feeds.searchenginewatch.com/sewblog 101 > Eschaton 101 > Search Engine Watch 101 > Signal v. Noise 101 > Guy Kawasaki 101 > Google Blogoscoped