目的
前回記事で、「Twitterのリアルタイムな形態素解析結果集計」を目標として挙げました。この途中経過について報告します。
結論
Twitter野球実況を形態素解析(品詞毎に分解)し、チーム毎に集計できました。
動作は以下の通り。
形態素解析。 pic.twitter.com/H65mETOz0W
— すいばり@'16年度9試合2勝2敗 (@Suibari_cha) 2017年2月19日
内容
処理は以下の流れです。
- TwitterStreamingAPIから野球関連ツイートを拾う
- ツイートにどのチームのワードが含まれているか判定
- 形態素解析を行い、2で判定したチーム(のオブジェクト)に結果を加算
- 以降、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
展望
- MeCabデフォルトのIPA辞書では、当然、野球選手名を適切に解析できない("大谷翔平"→*["大谷","翔","平"]となる。["大谷翔平"]*と解析して欲しい)。MeCabではユーザ辞書追加も可能なので、野球選手の「フルネーム+読み」「苗字+読み」の辞書ファイルをスクレイピング等して作ろうか検討中。→導入しました
- 前回記事同様に、Socket.ioで集計結果をクライアントに転送して、リアルタイムに結果を図で示すのも良さそう。→D3.jsを導入しました