みんな、Taggerにはnilとか”"(空文字)とかを引数に渡しちゃだめですよ!
>> MeCab::Tagger.new.parseToNode(nil) (irb):1: [BUG] Segmentation fault ruby 1.8.7 (2009-04-08 patchlevel 160) [x86_64-linux]
単体で動かしていればすぐに気が付いたんだろうけど、デプロイした後で起こっていたのでなかなか気付きませんでした。
みんな、Taggerにはnilとか”"(空文字)とかを引数に渡しちゃだめですよ!
>> MeCab::Tagger.new.parseToNode(nil) (irb):1: [BUG] Segmentation fault ruby 1.8.7 (2009-04-08 patchlevel 160) [x86_64-linux]
単体で動かしていればすぐに気が付いたんだろうけど、デプロイした後で起こっていたのでなかなか気付きませんでした。
こんな会話があったのが、12日の夜。
[2009/09/12 22:58:25] えがちゃんの発言: ひまだなーw [2009/09/12 22:58:27] えがちゃんの発言: なにします?w [2009/09/12 22:58:29] えがちゃんの発言: なんかサービスつくりたいw [2009/09/12 23:03:57] tkosugaの発言: なんのサービス? [2009/09/12 23:04:07] tkosugaの発言: この話に食いつく [2009/09/12 23:04:25] えがちゃんの発言: pimoteのAPIをつかったサービスですねー
そこからbuzzterみたいなのを作りたいと言う話になりましたので、
颯爽とpimotterをリリースしました!この公開が13日19時30分ですので、話しが始まってからリリースまで21時間という速さです。
精度はまだまだ低いのですが、雰囲気は十分に感じ取ってもられるのではないかなと思います。
pimoteで流行しているキーワードを自動的に抽出し、それをピックアップして見ることができます。これでどんな事が流行しているのか一目で分かりますね!
このウェブサービスはrails 2.3.2 を使って作られています。pimoteサーバーには5分間隔で最新のタイムラインを取得しに行っています。画面に表示されるタイムライン解析結果はmemcachedを使って3分間キャッシュしてます。タイムラインの解析にはMeCabを使いました。
pimoteといいますか、twitterで流れる文章はほとんど口語で流れてるプラス、名詞だけ抜きだせば良いというものではないという事が分かってきました。
アスキーアートも抜き出せると良いのですが、パターンで一致させるぐらいしか方法が思いつきませんでした(ここは未実装です)
さっくりと作る分には誰が作っても同じような実装になると思うので、ここにこのサービスの中核となるMeCabで構文解析された単語の取り捨てをするコードを貼り付けます。
#
# もっとちゃんと作らないと。後で時間かけてかなー。
#
def self.necessary?(surface, feature, prev_feature)
#p surface + ", feature:" + feature + ", prev_feature: " + prev_feature.to_s
return false if surface.blank?
return false if surface.split(//u).collect{|c| MARKS.include?(c)}.all?
return false if /[[:cntrl:]|[:blank:]|[:punct:]]+/ =~ surface
return true if (/^名詞,(一般|固有名詞|サ変接続|形容動詞語幹|ナイ形容詞語幹)/ =~ feature)
return true if (/^形容詞,(自立)/ =~ feature)
return true if (/^接頭詞,名詞接続/ =~ feature)
return true if (/^感動詞/ =~ feature)
return false if prev_feature.blank?
#
# この2つ次は絶対に拾う
#
if (/^接頭詞,名詞接続/ =~ prev_feature)
return true
end
if (/^名詞/ =~ prev_feature)
return true if (/^助詞,(.*,連語|終助詞|係助詞)/ =~ feature)
return true if (/^動詞,(非自立)/ =~ feature)
end
if (/^助詞,格助詞,連語/ =~ prev_feature)
return true if (/^助動詞/ =~ feature)
end
if (/^助詞,係助詞/ =~ prev_feature)
return true if (/^助詞,終助詞/ =~ feature)
end
if (/^動詞,非自立/ =~ prev_feature)
return true if (/^動詞,非自立/ =~ feature)
end
false
end
ASCII_ART_MARKS = %w{゚ ノ Д 冫}
ASCII_MARKS = %w{… ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ ^ _ ` { | } ~ > <}
ZENKAKU_MARKS = %w{ 、 。 , . ・ : ; ? ! ゛ ゜ ´ ` ¨ ^  ̄ _ ヽ ヾ ゝ ゞ 〃 仝 々 〆 〇 ー ― ‐ / \ ~ ∥ | … ‥ ‘ ’ “ ” ( ) 〔 〕 [ ] { } 〈 〉 《 》 「 」 『 』 【 】 + - ± × ÷ = ≠ < > ≦ ≧ ∞ ∴ ♂ ♀ ° ′ ″ ℃ ¥ $ ¢ £ % # & * @ § ☆ ★ ○ ● ◎ ◇ ◆ □ ■ △ ▲ ▽ ▼ ※ 〒 → ← ↑ ↓ 〓 ∈ ∋ ⊆ ⊇ ⊂ ⊃ ∪ ∩ ∧ ∨ ¬ ⇒ ⇔ ∀ ∃ ∠ ⊥ ⌒ ∂ ∇ ≡ ≒ ≪ ≫ √ ∽ ∝ ∵ ∫ ∬ Å ‰ # ♭ ♪ † ‡ ¶ ◯ ─ │ ┌ ┐ ┘ └ ├ ┬ ┤ ┴ ┼ ━ ┃ ┏ ┓ ┛ ┗ ┣ ┳ ┫ ┻ ╋ ┠ ┯ ┨ ┷ ┿ ┝ ┰ ┥ ┸ ╂ ∮ ∑ ∟ ⊿ ¦ ' " }
MARKS = ASCII_MARKS + ZENKAKU_MARKS + ASCII_ART_MARKS
よそで書かれたテキストを自分のサーバーにもってきて加工するだけのサービスって楽ですね。負荷の問題もありませんし。接続先は1つですし。次からのサービスを作るときに、このあまりの楽々さに溺れてしまわないよう気をつけたいと思います。