Upload
yoji-shidara
View
9.953
Download
1
Embed Size (px)
Citation preview
buzztterの裏側とその周辺技術
しだらようじ(dara)
2007-11-06勉強会@自律系
今 煙の中で溶け合いながら探しつづける 愛のことば
スピッツ「愛のことば」
自己紹介
しだらようじ / 設樂洋爾 / darahttp://d.hatena.ne.jp/darashi/http://twitter.com/darashiスープカレー好き108皿@2006年,37皿@2007年11月5日現在Ruby札幌運営チーム
My Projects
http://soupcurry.infohttp://jpmobile-rails.orghttp://radiant-hikifilter.googlecode.comhttp://buzztter.com
ばずったー作ったー☆
buzztterとは
基本的なアイディア
普段より多く言及されているコトバを抽出する
どうやって?
直近60分間のキーワード w の言及者数: TFtgt
発言者数: DFtgt
60分前~2日前のキーワード w の言及者数: TFref
発言者数: DFref
score(w) = TFtgt / DFtgt - TFref / DFref
キーワード w の評価値:
なぜこの式か
発言者数比を用いてキーワードがtwitterverseに占める割合を評価するまずは愚直に各項を簡単なSQLのクエリで計算できる意外とうまく動いた
技術的な面から。
buzztterの裏側
扱うべきデータ量2007年11月3日 buzztter調べ125,626 updates/日5234.4 updates/時87.24 updates/分データの大きさ (JSON response)約12kB/20 updates約71.88MB/日約25.62GB/年
ちなみに
>> t = Time.parse("2007-11-3")=> Sat Nov 03 00:00:00 +0900 2007
>> Status.count(:conditions=>["created_at BETWEEN ? AND ?", t, t.tomorrow])=> 125626
Rails (ActiveRecord + ActiveSupport)の素敵な例
システム構成twitter
DB
fetcher
analyzer
web UIhot botnotify bot
dRB
twitter API
importerlanguage guesser
user
入力系twitter
DB
fetcher
analyzer
web UIhot botnotify bot
dRB
twitter API
importerlanguage guesser
user
public_timelineの厄介ごと
ある程度のリアルタイム性が要求される:最新の20更新しか入手できない。取りこぼしたら終わり。各国語が混在している。
分散クローラ w/dRB, Rindatwitter
fetcher fetcher fetcher
DB
importer
1時間分をfetcherのメモリに保持
importerが永続化
dRB
クローラのログTue Nov 06 15:17:40 +0900 2007 - received 8 / 20, 5793 tuplesTue Nov 06 15:17:45 +0900 2007 - received 10 / 20, 5794 tuplesTue Nov 06 15:17:51 +0900 2007 - received 10 / 20, 5798 tuplesTue Nov 06 15:17:55 +0900 2007 - received 4 / 20, 5797 tuplesTue Nov 06 15:18:00 +0900 2007 - received 5 / 20, 5797 tuplesTue Nov 06 15:18:05 +0900 2007 - received 11 / 20, 5797 tuplesTue Nov 06 15:18:12 +0900 2007 - received 8 / 20, 5802 tuplesTue Nov 06 15:18:16 +0900 2007 - received 9 / 20, 5807 tuplesTue Nov 06 15:18:21 +0900 2007 - received 8 / 20, 5809 tuplesTue Nov 06 15:18:25 +0900 2007 - received 12 / 20, 5810 tuplesTue Nov 06 15:18:30 +0900 2007 - received 10 / 20, 5812 tuplesTue Nov 06 15:18:35 +0900 2007 - received 13 / 20, 5817 tuplesTue Nov 06 15:18:40 +0900 2007 - received 3 / 20, 5811 tuplesTue Nov 06 15:18:45 +0900 2007 - received 5 / 20, 5811 tuplesTue Nov 06 15:18:50 +0900 2007 - received 15 / 20, 5820 tuplesTue Nov 06 15:18:55 +0900 2007 - received 14 / 20, 5826 tuplesTue Nov 06 15:19:01 +0900 2007 - received 3 / 20, 5823 tuplesTue Nov 06 15:19:08 +0900 2007 - received 8 / 20, 5814 tuplesTue Nov 06 15:19:12 +0900 2007 - received 8 / 20, 5822 tuplesTue Nov 06 15:19:18 +0900 2007 - received 10 / 20, 5818 tuples
言語判定 Lingua::LanguageGuesser
多言語を識別可能。Pure Perl で実装されている。File.popen を使って Ruby でwrap する。誤識別がある(仕方ない)。CPU負荷がやや高い。
http://gensen.dl.itc.u-tokyo.ac.jp/LanguageGuesser/LanguageGuesser_ja.html
解析部twitter
DB
fetcher
analyzer
web UIhot botnotify bot
dRB
twitter API
importerlanguage guesser
user
どうやって?(再掲)
直近60分間のキーワード w の言及者数: TFtgt
発言者数: DFtgt
60分前~2日前のキーワード w の言及者数: TFref
発言者数: DFref
score(w) = TFtgt / DFtgt - TFref / DFref
キーワード w の評価値:
単語抽出 (初期バージョン)
MeCabで形態素解析→自立語を抽出評価式の性質から「直近60分以内に出現していない単語はキーフワードになりえない」直近60分以内に発言された単語すべてについてそれぞれ score(k) を計算してランク付け。
フレーズ抽出へのモチベーション
「美容院」を抽出したい。「涼宮ハルヒの憂鬱」も抽出したい。(非自立語も含むフレーズ)
現在の解析器 (1)チャンキング直近60分の発言
チャンク
涼 名詞,一般,*,*,*,*,涼,リョウ,リョー宮 名詞,一般,*,*,*,*,宮,ミヤ,ミヤハルヒ 名詞,一般,*,*,*,*,*の 助詞,連体化,*,*,*,*,の,ノ,ノ憂鬱 名詞,一般,*,*,*,*,憂鬱,ユウウツ,ユーウツを 助詞,格助詞,一般,*,*,*,を,ヲ,ヲみる 動詞,自立,*,*,一段,基本形,みる,ミル,ミルEOS
BOS/涼/宮/ハルヒ/の/憂鬱/を/みる/EOS:
「涼宮ハルヒの憂鬱をみる」
形態素解析
URL除去^@... 除去
句読点, 記号で分割
現在の解析器 (2)候補生成BOS/涼/宮/ハルヒ/の/憂鬱/を/みる/EOS
で打ち切り
i, j をシフトしながら連接スコア
を計算
出現数が1以下の場合打ち切り
Ci,j =j!
k=i
P (tk!1|tk)P (tk+1|tk)
Ci,j < 0.75 文字列i..j を候補へ
ji
現在の解析器 (3)スコア計算補正
「涼宮ハルヒの憂鬱」が出現するとき、その部分文字列「涼」「涼宮」「涼宮ハルヒ」… も必ず同時に出現する。ある文字列の部分文字列になっている文字列は、スコアを計算する際にその分を減算する。→「涼宮ハルヒ」だけで出現している場合を1回と計算する。
現在の解析器 (4)後処理
ゴミが残るのでNGワードリストでアドホックに除去する。大文字と小文字は少々厄介。mac, Mac, MAC, ...内部の処理は同一視。どれを出力すべきかという問題が残る(現在はランダム)。
言及者数をカウントするクエリ
count_by_sql ["SELECT COUNT(DISTINCT(user_id)) FROM statuses WHERE #{IGNORE_COND} AND language = ? AND (created_at BETWEEN ? AND ?) AND text @@ ?", language, t.ago(ago), t, add_pragma(word)]
Senna+Ludiaで簡単に全文検索
http://sourceforge.jp/projects/ludia/http://qwik.jp/senna/FrontPageJ.html
解析プロセスのログ2007-11-06 13:19:45 ANALYZER-ng(22499) begin for japanese-utf82007-11-06 13:19:46 ANALYZER-ng(22499) extracted 3120 sentences2007-11-06 13:20:12 ANALYZER-ng(22499) 6006 keywords extracted from 3120 sentences2007-11-06 13:20:12 ANALYZER-ng(22499) deleting stopwords ...2007-11-06 13:20:19 ANALYZER-ng(22499) odd terms removed (5902 terms)2007-11-06 13:20:19 ANALYZER-ng(22499) ignore case (5895 terms)2007-11-06 13:20:19 ANALYZER-ng(22499) trivial terms are removed (1796 terms)2007-11-06 13:21:38 ANALYZER-ng(22499) occurrence calculated (72.738133 s)2007-11-06 13:23:35 ANALYZER-ng(22499) modified DDFs calculated2007-11-06 13:23:35 ANALYZER-ng(22499) scores calculated (1563 terms)2007-11-06 13:23:40 ANALYZER-ng(22499) redundant terms removed (1151 terms)2007-11-06 13:23:42 ANALYZER-ng(22499) end for japanese-utf8 (237.531316 s)
2007-11-06 13:23:42 ANALYZER-ng(22499) begin for english2007-11-06 13:23:43 ANALYZER-ng(22499) extracted 6181 sentences2007-11-06 13:24:20 ANALYZER-ng(22499) 10168 keywords extracted from 6181 sentences2007-11-06 13:24:20 ANALYZER-ng(22499) deleting stopwords ...2007-11-06 13:24:33 ANALYZER-ng(22499) odd terms removed (9808 terms)2007-11-06 13:24:33 ANALYZER-ng(22499) ignore case (9444 terms)2007-11-06 13:24:33 ANALYZER-ng(22499) trivial terms are removed (2738 terms)2007-11-06 13:26:18 ANALYZER-ng(22499) occurrence calculated (96.306258 s)2007-11-06 13:27:59 ANALYZER-ng(22499) modified DDFs calculated2007-11-06 13:27:59 ANALYZER-ng(22499) scores calculated (2109 terms)2007-11-06 13:28:10 ANALYZER-ng(22499) redundant terms removed (1643 terms)2007-11-06 13:28:13 ANALYZER-ng(22499) end for english (270.044345 s)
出力系: Web UItwitter
DB
fetcher
analyzer
web UIhot botnotify bot
dRB
twitter API
importerlanguage guesser
user
Web UI
かなり素直なRailsアプリケーションTwitter 検索エンジンとしても動作解析結果をDBから取得キーフレーズ表示部は Javascript で自動更新RSS 出力あり
類似発言検索
Sennaの類似文書検索を利用する。クエリとして文書を与えると、類似する文書を取得できる。直近の自身の発言と類似する発言を検索できる。
出力系: bottwitter
DB
fetcher
analyzer
web UIhot botnotify bot
dRB
twitter API
importerlanguage guesser
user
hourly bot
一時間ごとに上位のフレーズを送信する。cronで定時実行。言語ごとにtwitterアカウントを用意:日本語版 http://twitter.com/buzztter英語版 http://twitter.com/buzztter_enクローラの異常を検知して送信をスキップする。
hot botバースト状態を通知する。条件:スコアが一定値を超えている, かつ直近10分間に5人以上が言及しているcronで1分毎に実行。同じキーワードは3時間通知しない。3時間に6通知まで。クローラの異常を検知して送信をスキップする。
ベッドの横から世界に発信。
buzztterを支えるモノ
ハードウェア on 自宅ラック
自作PC(メイン)Core 2 Duo 6400
(2.13GHz)Memory: 2GB
VM on 自作PC(補助クローラ)Pentium 4 2.53GHzMemory: 1GB
ソフトウェア
Debian etchPostgreSQL 8.1Ludia 1.0.0Senna 1.0.7Rails 1.2.4pound + mongrel
それが原動力。
反響
掲載書籍
twitterコミュニケーション・バイブル̶気軽に書ける1行ブログ ブラウザインスタントメッセンジャーケータイ対応菊地 芳枝 著
Twitter!̶Twitter APIガイドブック辻村 浩 著
twitter上での評判twitter、buzztter、twitter検索、tumblr、はてブ。これらが手放せない。http://twitter.com/akio0911/statuses/387770042
buzztterはtwitter-erの心を映す鏡http://twitter.com/maybowjing/statuses/344534932
相変わらずbuzztterはよく空気を読んでる。そもそも、そういう仕組みのモノなんだけど。http://twitter.com/NStyles/statuses/335544352
精読・速読・buzztter(略) buzztter というサービスが存在するからだ。自分が「速読の Twitter」を実行しなくても、このサイトを見れば Twitter の動きが大まかにではあるが読める。(略)http://worstman.net/blog/088
[twitter][comment]buzztterってめちゃくちゃ偏ってるよ。あくまでもオレが読んでる1500人強の全ログ傾向の印象だけど→このサイトを見れば Twitter の動きが大まかにではあるが読めるhttp://b.hatena.ne.jp/otsune/20071024
世界を知ることが、世界を変えてしまう。
系としてのbuzztter
メディアとしてのbuzztter重大ニュースの速報辞任, 事故, 訃報, ...twitterユーザにとっての重大ニュース新商品, 新機能, 買収, 訃報, ...twitterユーザが注目するテレビ番組アニメ, お笑い, ドキュメンタリー, ...災害情報地震, 雨, 雷, 火災, 停電, 電車遅延, ...
buzztterが与える影響
このbuzztterを見たあとでは、ばんごはんを餃子にしても、あえて餃子を避けても負けな気がする。(意識した時点でもう精神が餃子の支配下に置かれる)http://twitter.com/hatoko/statuses/281085152
buzztter入りしているのを見て、なんだか久々に赤福が食いたくなってきたhttp://twitter.com/AIce/statuses/346543102
buzztterに対するツッコミ
はい、buzztterダウト!http://twitter.com/night16/statuses/363321482
buzztter は毛ずきらしいhttp://twitter.com/kommm/statuses/362095092
@buzztter自重しろwwwwwwhttp://twitter.com/scudroid/statuses/339228382
buzztterに言わせたい
.@buzztterが北海道という単語をキーワードにするのが僕の夢。 http://twitter.com/smokeymonkey/statuses/386516592
buzztter に「HOT: 女装」と言わせるライフハック。 http://twitter.com/cress_cc/statuses/349727262
buzztterの可能性
ニュース速報より早い速報草の根的ニュースメディア特定のユーザ層のためのニュースメディアゆるいコミュニケーションハブ情報のサーキュレータ的役割
悩みの数だけ楽しみがある。
Open Issues
これが命。
Open Issues: 分析
類似発言のグルーピング
類語や表記揺れが別の単語として計算されている。
フレーズ抽出: ダム問題
上位フレーズの部分文字列が上位に出る。部分文字列のカウントは考慮しているはずだけれど・・・
評価式: 絶対数に敏感
助詞や数など絶対数が多いものが高スコアになる。
評価式: 朝方は敏感
全体の発言数が少ない時間帯に特に敏感になる。
botの検出
現状では ignore list 方式登録が面倒necotter 強敵発言を分析して自動で除外したい高い類似性 (対自己, 対他bot)follow/被followの分析
「情報操作」に脆弱
仲の良いユーザ同士が結束して特定のフレーズを発言することでbuzztter入りできてしまう。評価式が言及者数のみに基づいている限り避けられない。
ユーザ間の類似の活用
クラスタリング発言の類似性follow関係によるグラフ構造ユーザの紹介や推薦もできると楽しそう。通常時のクラスタを超えて共有される話題は重要そう。
位置情報との連携
L: 付きで位置情報をポストしている人がいる。ユーザの行動圏を把握して情報抽出を行えないか?季節感、天候、イベントの情報など、ローカルなbuzztterも楽しそう。
出力がないのであれば、存在しないのと同じだ。
Open Issues: 出力
hot bot の改善
精度の向上:毎朝「おはよう」が通知されてしまう。速報性の向上:現状はbuzztterのスコア依存。解析窓を小さくした別の分析方式を使った方がいいかもしれない。
言及数推移のグラフ
http://kizasi.jp のようなチャートをつけたい。長期間のログを検索可能な状態で保存しなければいけない。
widget
たとえば:OS X の Dashboard 用 widgetデスクトップアクセサリ純粋に工数的な問題で実現されていない。RSSは吐いているので是非作ってください(必要ならAPIも用意します)。
すべてのはじまり。
Open Issues: 入力
安定したクロールのために
twitter の API では public_timeline は遡ることができない。相互に補完する分散型のクローラをつくりたい。ネットワーク的にも分散配置したい。
次期分散クローラ構想twitter
fetcher fetcher fetcher
importer importer
DB DB DB
各ユーザが自由に利用
RESTなどでP2Pで補完
開発履歴
2007-04-12 プロジェクト開始2007-04-24 リリース2007-04-28 bot リリース2007-05-01 フレーズ抽出の実装2007-05-22 類似発言抽出機能2007-06-05 英語版リリース
まとめ
buzztterの裏側を紹介した。アイディアはとても簡単、でもシステムはけっこう大掛かり。まだまだ改善の余地あり。twitterは情報の宝庫。みんなでやってみませんか?