集合知プログラミング

3章 その16 hpricotでHTMLパース

p.49より、HTMLの解析。 pythonではBeautiful Soupを使ってHTMLを解析しているが、RubyなのでHpricotを使う。hpricotは既に3章序盤でHTMLタグ除去にも使ったが、今回はタグの中身を取り出しに深入りしていく。 3章 その2 - 橋本詳解 pylori*style wiki - HTM…

3章 おまけ2 日本語blogの階層的クラスタリング修正、できたクラスタを見てみる

return list.uniqだった所を修正 http://www.bitbucket.org/shokai/collective-intelligence-study/src/tip/03/generatefeedvector-jp.rb def getWordsByKind(node, kind) list = Array.new while node do f = node.feature.split(/,/) if /#{kind}/ =~ f[0]…

3章 おまけ 日本語blogの階層的クラスタリング

日本語データを扱うなら、テキストファイルじゃなくてちゃんとRDBに保存した方が良いですね。区切り文字とかが面倒をかけてきて、今回はクロールしてきたデータの一部を手動で修正してしまった。 できた。→大きいサイズ http://www.flickr.com/photos/shokai…

3章 その15 K平均法でblogをクラスタリング

データ群をK個のクラスタに分けるために、「いちばんしっくり来るK個の重心」を再帰で見つけるK平均法を使う。 このページのインデントわかりづらくてイライラした。 このアルゴリズムは階層的クラスタリングより全然速い。 p.47~48より clusters.rbにkclust…

配列の初期化と参照

p.47でK平均法をやっていて、2次元配列(配列の配列)が必要になった。 ループで空の配列を作っているが bestmatches = [[] for i in range(4)] Rubyだと、Array.newの引数で要素数と初期値を指定できる >> arr = Array.new(3, 10) # 要素数3で初期値10の配…

3章 その13 blogクラスタのビジュアライズ

p.42~44より、blogクラスタの図を描く。 Python Imaging Libraryの代わりに、RMagick http://d.hatena.ne.jp/shokai/20081112/1226502119 を使う。使い方も関数名もほぼ同じなので簡単。あと配列内の一番大きい要素を返すArray.max関数を使った。 http://www…

3章 その12 irbのloadとrequire

3章では、hcluster関数(http://d.hatena.ne.jp/shokai/20081112/1226473410)の処理がMacbookだと3分ぐらいかかるので、何度もやりたくない。 でもhcluster関数で作った階層的クラスタをビジュアライズする処理は何度も試行錯誤したいので、irbのloadし直しを…

3章 その14 単語のクラスタリング

p.44より clusters.rbに行列反転を追加 # 行列の入れ替え def rotatematrix(data) newdata = Array.new for i in 0...data[0].length newrow = Array.new for j in 0...data.length newrow.push(data[j][i]) end newdata.push(newrow) end return newdata en…

3章 その10 階層的クラスタの出力

名前付き引数をインクリメントだと勘違いしてた。 printclust(clust.left, labels=labels, n=n+1) のn=n+1はpythonでは名前付き引数なので、別にインクリメントしているわけじゃなかった。 cluster.rbにprintclust関数を追加 http://www.bitbucket.org/shoka…

3章 その9 階層的クラスタを作成

単語出現回数のリストを要素(vec)に持つ2分木ノードbiclusterをつなぎあわせて、p.36で解説されている内容が近いblog同士の階層的クラスタを作る。距離の計算は関数ポインタになっていたので、Object#method関数を使って http://www.ruby-lang.org/ja/man/ht…

3章 その8 hashのkeyに配列を使う

p.39のhcluster関数の distances = {} if(clust[i].id,clust[j].id) not in distances: distances[(clust[i].id,clust[j].id)] = distance(clust[i].vec,clust[j].vec) がいまいちわからなかったんだけど、よく見たらリストをキーにとるディクショナリ(ハッ…

3章 その11 RMagickで図を描く

p.42から、Python Imaging Library(PIL)で階層的クラスタをデンドログラムにしてビジュアライズしているので、Rubyでも何とかして絵を描きたい。Processingとか使えれば楽なんだけど。今回のグラフに必要なのはテキストの配置とラインを引く事だけなので、Im…

3章 その6 クラスタの木構造

Biclusterとして、階層的クラスタのための2分木のクラスを作る 一応アクセサも用意しておいた http://www.bitbucket.org/shokai/collective-intelligence-study/src/82884830d372/03/bicluster.rb class Bicluster def initialize(vec, left=nil, right=nil,…

3章 その5 ピアソン相関距離の計算

2章で実装した http://d.hatena.ne.jp/shokai/20081004/1223126485 とは別に作る。 p.38より ピアソン相関距離を計算する関数をclusters.rbに追加http://www.bitbucket.org/shokai/collective-intelligence-study/src/82884830d372/03/clusters.rb # ピアソ…

3章 その4 単語頻出表の読み込み

pythonのstring.stripは指定文字を削除する関数で、引数無しだと文字列前後の空白を除去する。rubyにも引数なしのstripがあって、同じ働きをする p.37より、cluster.rbを作成して前回generatefeedvector.rbで作成した単語頻出表(myblogdata.txt)から単語名な…

3章 その7 pythonのrange、rubyの..と...

前の章から出てきたrange関数はrubyでは..か...で使えるが、それぞれちょっと違う。 これややこしいな。どう覚えればいいんだろirbで試す >> for i in 0..5; puts i; end 0 1 2 3 4 5 => 0..5 >> for i in 0...5; puts i; end 0 1 2 3 4 => 0...5 pythonだと…

3章 その3 feedlist.txtから単語出現表を作る

http://kiwitobes.com/clusters/feedlist.txt のfeedリストを巡回して、blogから全単語を取り出し、 http://kiwitobes.com/clusters/blogdata.txt と同じフォーマットで単語-出現数リストを作る。 pythonでは大丈夫みたいだけどfeedlist行末の改行がrubyのop…

3章 その2

p33より feedから記事本文を読んで単語の出現回数をチェックする。 htmlから本文を取り出すのに、hpricotを使ってみた。 gem install hpricot まずは、1つのfeedから単語と出現回数を数える getwordcounts(url) を作る。 http://www.bitbucket.org/shokai/co…

3章 その1 simple-rssでRSS/Atomフィードを読む

3章はクラスタリング。 35ページまでかけて複数の英文blogのRSSフィードから単語を切り出し、 http://kiwitobes.com/clusters/blogdata.txt のような単語と出現回数のリストを作っている。このblogdata.txtを使ってしまっても良いのだけど、せっかくだからru…

2章 その10

これまで、あるユーザに似たユーザリストを計算してから、似たユーザの持つリンクや映画をレコメンドしてきた。これをユーザベースの協調フィルタリング呼ぶらしい。 それに対して、あるアイテムがあり、それに似ているかどうか重み付けされたスコアを持つア…

2章 その9

続き。 1ユーザあたり15件では足りないので、最近の100件を取得できるようにfillItem関数を修正 http://www.bitbucket.org/shokai/collective-intelligence-study/changeset/89c724b7af46/ # すべてのユーザによって投稿されたリンクを取得 def fillItems(us…

2章 その8

続き。これで23ページ、deliciousのレコメンデーションまでできた http://www.bitbucket.org/shokai/collective-intelligence-study/src/0082469f4612/delicious.rb delicious.rbにget_userposts関数を追加 # 指定ユーザのpostをできるだけ全部取ってくる de…

2章まで終わった

作業内容はbitbucketにアップした http://www.bitbucket.org/shokai/collective-intelligence-study/ この本面白いなー。 情報数学とか習ってないけど数式が出てこなくてコードが具体的だからなんとかついて行ける。ここまで15時間ぐらいかかった。 Rubyにも…

2章 その13

p.29より、今度はアイテムベースの協調フィルタリングで推薦をする irbで >> itemsim = c.calculateSimilarItems(prefs,50) 100/1664 200/1664 300/1664 1664件読み込むのに3分ぐらいかかる 87番のユーザに推薦 >> pp c.getRecommendedItems(prefs, itemsim,…

2章 その12

p.27より、 ミネソタ大のGroupLens Projectによって作られた映画の評価データセットを使う。MovieLens(http://www.grouplens.org/node/73) mkdir data mkdir data/movielens cd data/movielens wget http://www.grouplens.org/system/files/ml-data_0.zip un…

2章 その11

その10で、ある映画に似ている映画とその類似度を取れるようになった。 自分がこれまで評価した映画に付けたスコアと、まだ見ていない映画との類似度を使って、まだ見ていない映画に何点をつけるかを予測する。 p.26~27より recommendations.rb にgetRecomme…

2章 その4

今回は関数ポインタが出てくるので、rubyのObject#method関数を使った http://www.ruby-lang.org/ja/man/html/Method.html 全ての人の中から趣向の近い人を求める。全員との相関を計算して、相関係数の高い人から順に並べる。 これまで相関計算方法を2つやっ…

2章 その3

p.13より その2のユークリッド距離を用いた方法では、人それぞれ高い点数を付ける人や低い人など色々いて、その差が相関に影響を与えてしまう。 傾向の差を埋める為にピアソン相関係数を使う。recommendations.rb に sim_pearson関数を追加 class Critics # …

2章 その2

p.11より、2人の全ての映画評価から類似性を計算する(pythonのsum関数は、配列を渡すと要素が数値だったら全て足して結果を返すらしい) recommendation.rbにsim_distance関数を追加 class Critics # Person1とperson2の距離を基にした類似性スコアを返す d…

2章 その1

これをRubyにする 元データを作っておく p.8より recommendations.rb class Critics def users return @users end def initialize @users = { 'Lisa Rose' => { 'Lady in the Water' => 2.5, 'Snake on a Plane' => 3.5, 'Just My Luck' => 3.0, 'Superman R…