LoginSignup
0

More than 5 years have passed since last update.

Node.js+MeCab+StreamingAPIでTwitter実況を解析する

Last updated at Posted at 2017-02-19

目的

 前回記事で、「Twitterのリアルタイムな形態素解析結果集計」を目標として挙げました。この途中経過について報告します。

結論

 Twitter野球実況を形態素解析(品詞毎に分解)し、チーム毎に集計できました。
 動作は以下の通り。

内容

 処理は以下の流れです。

  1. TwitterStreamingAPIから野球関連ツイートを拾う
  2. ツイートにどのチームのワードが含まれているか判定
  3. 形態素解析を行い、2で判定したチーム(のオブジェクト)に結果を加算
  4. 以降、1の度に2~3繰り返し

コード

// 形態素解析クロージャ
function analyzeString() {
  const INDEX_WORD     = 0;
  const INDEX_WORDTYPE = 1;
  var result = {};
  for (key in q_json) result[key] = {};

  return function(text, cheer_teams) {
    mcb.parse(text, function(err, arr_words){
      if (err) throw err;
      arr_words.forEach(function(val, idx, arr){
        if (val[INDEX_WORDTYPE] == "名詞" ||
            val[INDEX_WORDTYPE] == "固有名詞") {
          var word = val[INDEX_WORD];
          if (checkJa(word)) {
            for (var i = 0; i < cheer_teams.length; i++) {
              // resultオブジェクトにその言葉があるか?
              if (result[cheer_teams[i]][word] != undefined) {
                // 言葉があるので加算する
                result[cheer_teams[i]][word] += 1;
              } else {
                // 言葉がないので追記
                result[cheer_teams[i]][word]  = 1;
              }
            }
          }
        }
      });
      var arr = [];
      arr_words.forEach( function(value, index, array){
        arr.push(value[0]);
      });
      console.log("words: " + arr);
      console.log('elements: ' + arr_words.length + ' words');
      console.log(result);
    });
  }

  function checkJa(str) {
    var isJapanese = false;

    for(var i=0; i < str.length; i++){
      if(str.charCodeAt(i) >= 256) {
        return isJapanese = true;
      }
    }
  }
}

MeCabの選定理由

 当初は形態素解析のモジュールにはMeCabでなくkuromojiを使うつもりでした。
 しかし、一度の解析に0.5秒強ほど時間がかかり、要件であるTwitter実況に追従できませんでした(メモリリークしnodeが強制終了してしまう)。
 よってMeCabの非同期解析モジュール(mecab-async)を選定しました。
 同様の現象にあわれた方の解決のために、エラーログを記載しておきます。

Feb 16 22:43:09 localhost kernel: Out of memory: Kill process 17191 (node) score 913 or sacrifice child
Feb 16 22:43:09 localhost kernel: Killed process 17191, UID 500, (node) total-vm:2266088kB, anon-rss:381672kB, file-rss:76kBFeb 16 22:43:09 localhost kernel: node: page allocation failure. order:0, mode:0x280da

展望

  1. MeCabデフォルトのIPA辞書では、当然、野球選手名を適切に解析できない("大谷翔平"→["大谷","翔","平"]となる。["大谷翔平"]と解析して欲しい)。MeCabではユーザ辞書追加も可能なので、野球選手の「フルネーム+読み」「苗字+読み」の辞書ファイルをスクレイピング等して作ろうか検討中。→導入しました
  2. 前回記事同様に、Socket.ioで集計結果をクライアントに転送して、リアルタイムに結果を図で示すのも良さそう。→D3.jsを導入しました

参考

  1. Qiita: "続・node.js で社会性フィルター" @albno273
  2. GitHub: "node-mecab-async" @hecomi

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0