個人的な正誤表 3章

今回もreload(clusters)と書いてある部分は適宜自分の環境とあわせて適宜変えてください。

p.33〜p.35 コード

英語版では間違いが沢山あるが、日本語版では直っている。
ただ、そのままgeneratefeedvector.pyを実行すると

Traceback (most recent call last):
  File "generatefeedvector.py", line 51, in <module>
    out.write(blog)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xbb' in position 8: ordinal not in range(128)

って感じに出ちゃいます。
feedparserはUnicodeで返ってくるのでblogdata.txtに書き込むときにブログのタイトルがASCIIコードの範囲外のUnicode文字列の場合うまくいかないので、generatefeedvector.pyのp.35の最後の部分のfor部分を以下のように

for blog,wc in wordcounts.items():
    blog=blog.encode('ascii','ignore')
    out.write(blog)
    for word in wordlist:
        if word in wc: out.write('\t%d' % wc[word])
        else: out.write('\t0')
    out.write('\n')

してあげると、とりあえずエラーは吐かなくなる。
まぁ、あんまりもともとあまり大きな問題ではないので放置でもいいかもです。

p.38

こまかいけど、最後の段落の最後の方でcluster.pyと書いてあるけどclusters.pyね。

p.44

英語のerrataでは

draw.text((x+5,y-7),labels[clust.id],(0,0,0))

の部分を

draw.text((x+5,y+7),labels[clust.id],(0,0,0))

ってかいてあるけど、日本語の本のままで(上の方)。

p.48 実行部分

正しくは、

kclust=clusters.kcluster(data,k=10)
[blognames[r] for r in kcluster[0]]
[blognames[r] for r in kcluster[1]]
...
[blognames[r] for r in kcluster[9]]

としましょう。rownamesなんて一度も作っていないし、kもないからね。

p.49以降のZeboの部分

Zeboは英語の本の時から仕様がどうも変わったらしく、そのままやってもだめ。
日本語の本ではまったく直っていない。
ページの構造が変わっています。
なので、downloadzebodata.pyはURLの部分とマッチさせる文字列を変えないと全然データがとれない。
以下のようにするととりあえずとれます。

from BeautifulSoup import BeautifulSoup
import urllib2
import re
chare=re.compile(r'[!-\.&]')
itemowners={}

# Words to remove
dropwords=['a','new','some','more','my','own','the','many','other','another']

currentuser=0
for i in range(1,51):
  # URL for the want search page
  c=urllib2.urlopen(
  'http://member.zebo.com/Main?event_key=USERSEARCH&action=ns&keyword=car&tab=review&rPage=%d'
  % (i))
  soup=BeautifulSoup(c.read())
  for td in soup('td'):
    # Find table cells of bgverdanasmall class
    if ('class' in dict(td.attrs) and td['class']=='smallcontentgray'):
      items=[re.sub(chare,'',str(a.contents[0]).lower()).strip() for a in td('a')]
      for item in items:
        # Remove extra words
        txt=' '.join([t for t in item.split(' ') if t not in dropwords])
        if len(txt)<2: continue
        itemowners.setdefault(txt,{})
        itemowners[txt][currentuser]=1
      currentuser+=1
      
out=file('zebo.txt','w')
out.write('Item')
for user in range(0,currentuser): out.write('\tU%d' % user)
out.write('\n')
for item,owners in itemowners.items():
  if len(owners)>10:
    out.write(item)
    for user in range(0,currentuser):
      if user in owners: out.write('\t1')
      else: out.write('\t0')
    out.write('\n')

URLとsmallcontentgrayってのは実際のページの要素を見て適宜変えましょう。
とりあえずクラスタリングは出来るけど、もともと取るデータが変なものなので意味不明。
今のZeboはどの部分がアイテムのリストかが分からないなぁ・・・。

とりあえず、上のコードならエラーにはならないよ。でも、意味ないデータかな。うまいことアイテムを抽出出来ればいいけどなぁ。

p.58 エクササイズ3

実際の距離(ピタゴラスの定理)とありますが、今までの流れからするとユークリッドの書き間違えか?英語のerrataでも指摘されているので、一応載せておきます。

関連リンク

随時追加していきます.

書籍「集合知プログラミング」について パート1

http://d.hatena.ne.jp/naoe/20081130

書籍「集合知プログラミング」について パート2

http://d.hatena.ne.jp/naoe/20081207

書籍「集合知プログラミング」について パート3

http://d.hatena.ne.jp/naoe/20090201

書籍「集合知プログラミング」について パート4

http://d.hatena.ne.jp/naoe/20090222