本棚演算

本棚.orgのデータに様々な演算を適用すると 有用な結果を得られることがある。 協調フィルタリング的に 特定カテゴリの本を集めたりできる。

解説 本棚演算例 演算プログラミング 演算ライブラリ ダウンロード

解説

本棚.orgでは、 ユーザが自由に作成した本棚ごとに複数の本が登録されている。 「増井の本棚」に 「Blue Note Cover Art」 「逆風野郎」 などの本が登録されており、 「svslabの本棚」に 「逆風野郎」 「スモールワールドネットワーク」 などの本が登録されているとき、 全本棚データを表1のような本棚行列で表現することができる。

表1: 本棚行列
 
増井の本棚
1
1
1
1
0
1
svslabの本棚
0
1
0
0
0
1
桐華の本棚
0
0
0
1
1
0

この表から以下のようなことがわかる。

この事実をもとに、以下のような推論を行なうことができる。 このような推論はあまりあてにならないかもしれないが、 本棚表の行や列データに対して様々な本棚演算を行なうことにより、 表を見ただけではすぐにわからない各種の情報を抽出することができる可能性がある。

本棚演算の例

「増井の本棚」行と「svslabの本棚」行を加算すると以下のような行列が得られる。

表2: 増井+svslab
 
増井+svslab
1
2
1
1
0
2

この演算の結果、「逆風野郎」や「スモールワールドネットワーク」は人気があることがわかる。

また、 「増井の本棚」行から「svslabの本棚」行を減算すると以下のような行列が得られる。

表3: 増井-svslab
 
増井-svslab
1
0
1
1
0
0

「増井の本棚」と「svslabの本棚」は似ているにもかかわらず 「アカギ」「掌の中の小鳥」は「svslabの本棚」に含まれていないため、 これらの本は「svslab」への推薦候補と考えることができる。

このような計算を本棚行列の行や列に対して行なうことにより、 様々な有用な情報を取得することができる。

本棚演算のプログラミング

本棚データを扱うRubyライブラリを使って様々な本棚演算を実行できる。

増井への推薦本を計算

「増井の本棚」に含まれる本の傾向を判断して推薦を行なう演算を考える。

「増井の本棚」に内容が近い本棚の中には、 私が興味を持ちそうな本が含まれている可能性が高いと思われるので、 まず「増井の本棚」に近い本棚のリストを計算してみる。

require 'enzan'
#  「増井の本棚」に近い本を持つ本棚のリストを取得
BookList.new('増井').similar.dump
この結果、以下のような本棚が「増井の本棚」に内容が近いことがわかる。
1 dai5d
1 sakai
1 matznaga
1 suchi
1 m-use
...
これらの本棚に共通に含まれている本のリストを取得してみる。
require 'enzan'
#  「増井の本棚」の本リストを取得
masuibooks = BookList.new('増井')
#  この本リストに近い本を持つ本棚のリストを取得
similarshelves = masuibooks.similar
# 内容が近い本棚を40個取得し、その上で2個以上登録されている本のリストを作成
similarshelves[0...40].booklist.sort.major(2).dump
結果はこのようになる。
17 4839912653 Code Reading―オープンソースから学ぶプログラミングテクニック
17 4844317210 Rubyソースコード完全解説 (青木 峰郎, まつもと ゆきひろ)
14 4314005564 利己的な遺伝子 (リチャード・ドーキンス, 日高 敏隆, 岸 由二, 羽田 節子, 垂水 雄二)
14 4797318325 Wiki Way―コラボレーションツールWiki (ボウ ルーフ, ウォード カニンガム,
14 4756136494 プログラミング作法 (ブライアン カーニハン, ロブ パイク)
14 489471163X 計算機プログラムの構造と解釈 (ジェラルド・ジェイ サスマン
13 4798102040 コモンズ (ローレンス・レッシグ, 山形 浩生)
...
確かに私が買いそうな本が並んでいるが、 自分の持ってる本が含まれているし、 計算機関連本が多すぎるので、それらの本は除きたいところである。 計算機関連本のリストを別に作成し、このリストから引算すればいいだろう。

「正統派ハッカーの本棚」というものがあり、 これに近い本棚には計算機関連の本が多数登録されていると思われるので、 上と同じような方法で計算機関連本のリストを作ってみることにする。

require 'enzan'
#  「正統派ハッカー本棚」の本リストを取得
hackbooks = BookList.new('正統派ハッカー')
#  この本リストに近い本を持つ本棚のリストを取得
sshelves = hackbooks.similar
# 計算機関連と思われる本のリストを作成
sshelves[0...100].booklist.sort.major(2).dump
これを計算すると、確かに計算機関連の本がリストされた。
46 4320026926 プログラミング言語C ANSI規格準拠 (B.W. カーニハン, D.M. リッチー)
42 4756136494 プログラミング作法 (ブライアン カーニハン, ロブ パイク)
36 4839912653 Code Reading―オープンソースから学ぶプログラミングテクニック
34 4844317210 Rubyソースコード完全解説 (青木 峰郎, まつもと ゆきひろ)
25 4894712369 珠玉のプログラミング―本質を見抜いたアルゴリズムとデータ構造
...
これをまとめると、以下のようなスクリプトで 増井への推薦本を計算することができる。
require 'enzan'
#  「増井の本棚」の本リストを取得
masuibooks = BookList.new('増井')
#  この本リストに近い本を持つ本棚のリストを取得
sshelves = masuibooks.similar
# 内容が近い本棚を40個取得し、その上で2個以上
# 登録されている本のリストを作成
sbooks = sshelves[0..40].booklist.sort.major(2)
#  「正統派ハッカー本棚」の本リストを取得
hackbooks = BookList.new('正統派ハッカー')
#  この本リストに近い本を持つ本棚のリストを取得
sshelves = hackbooks.similar
# 計算機関連と思われる本のリストを作成
compbooks = sshelves[0..100].booklist.sort.major(2)
# 「増井の本棚」にもともと含まれていた本や計算機関連の本を除いてリスト
sbooks.remove(masuibooks).remove(compbooks).dump
この結果、以下のような推薦本リストを得ることができる。 確かに私が欲しいと思うような本のリストになっている気がする。 「攻殻機動隊」は本当は持ってるんだけど。
10 406313248X 攻殻機動隊 (1) (士郎 正宗)
10 4140807431 新ネットワーク思考―世界のしくみを読み解く (アルバート・ラズロ・バラバシ, 青木 薫)
9 4756133126 ロボットにつけるクスリ―誤解だらけのコンピュータサイエンス (星野 力)
9 4167330083 ぼくはこんな本を読んできた―立花式読書論、読書術、書斎論 (立花 隆)
7 4063211444 げんしけん (1) (木尾 士目)
7 4061495755 動物化するポストモダン―オタクから見た日本社会 (東 浩紀)
7 410401303X 博士の愛した数式 (小川 洋子)
7 415011451X しあわせの理由 (グレッグ イーガン, Greg Egan, 山岸 真)
...

萌え本の収集

同じ手法を 「
萌え専科の本棚」 に適用してみる。
require 'enzan'
moebooks = BookList.new('萌え専科')
moebooks.similar[0..40].booklist.sort.remove(moebooks).dump
この結果、以下のような本のリストが得られる。 違うのも混じっているようだが、引算すればより精度をあげることができる。

類似本の収集

ひとつの本からスタートして類似本のリストを作ることもできる。 鯨統一郎の「邪馬台国はどこですか?」 を含む本棚リストを作成し、その本棚に近い本棚に含まれる本のリストを作ることによって 似た傾向の本のリストを作ることができる。
require 'enzan'
# 「邪馬台国はどこですか」を含む本棚リストを作成
yamataishelves = ShelfList.new('4488422012')
# 似た本棚に含まれる本のリストを印刷
yamataishelves.similar[0..10].sort.dump
結果は以下のようになる。
1 4043730012 あすなろの詩 (鯨 統一郎)
1 4043432011 覆面作家は二人いる (北村 薫)
1 404343202X 覆面作家の愛の歌 (北村 薫)
1 4122034140 謎物語―あるいは物語の謎 (北村 薫)
1 4061854348 どんなに上手に隠れても (岡嶋 二人)
1 4061822365 タイムスリップ森鴎外 (鯨 統一郎)
1 4334074308 九つの殺人メルヘン (鯨 統一郎)
1 4488416012 生ける屍の死 (山口 雅也)
...

本棚演算ライブラリ

本棚のリストをShelfListクラス、本のリストをBookListクラスで表現している。

ダウンロード

プログラムと全データは
enzan20070409.tgz にまとめてある。 データは本棚.orgの最新のデータを反映しているわけではないが 適宜更新する予定。


2005/10/29 Toshiyuki Masui @ pitecan.com