形態素解析について
形態素解析とは
l自然言語で書かれた文章を、単語ごとに分割して、
lそれぞれの品詞を判別する作業
l下記は、「毎週、火曜日は勉強会があります」という文章を解析した結果
l解析結果:
毎週:名詞
、:記号
火曜日:名詞
は:助詞
勉強:名詞
会:名詞
が:助詞
あり:動詞
ます:助動詞
解析の過程
l単語分割
l 文章から単語を切り出す
l品詞推定
l 切り出した単語の品詞を推定する
l文法の妥当性チェック
l 文法的に正しい並びを探す
環境
lNode.js
lMecab(形態素解析ツール)
文章を形態素解析
//mecab-sample.js
// MeCabを利用するためのモジュール
module.exports = function () {
//外部モジュールの取り込み
var exec = require('child_process').exec;
var iconv = require('iconv-lite');
var fs = require('fs');
var platform = require('os').platform();
//モジュール変数の定義
//一時ファイル
this.TMP_FILE = __dirname + '/__mecab_tmpfile';
// MeCabのコマンドライン
this.MECAB = 'mecab';
this.ENCODING = (platform.substr(0,3) == 'win')
? 'SHIFT_JIS' : 'UTF-8';
//形態素解析を実行する関数
this.parse = function (text, callback) {
var encoding = this.ENCODING;
text += "n";
//変換元テキストを一時ファイルに保存
if (encoding != 'UTF-8') {
var buf = iconv.encode(text, encoding);
fs.writeFileSync(this.TMP_FILE, buf, "binary");
} else {
fs.writeFileSync(this.TMP_FILE, text, "UTF-8");
}
文章を形態素解析
//コマンドを組み立てる
var cmd = [
this.MECAB,
'"' + this.TMP_FILE + '"'
].join(" ");
var opt = { encoding: 'UTF-8' };
if (encoding != 'UTF-8') opt.encoding = 'binary';
exec(cmd, opt,
function (err, stdout, stderr) {
if (err) return callback(err);
var inp;
//結果出力ファイルを元に戻す
if (encoding != 'UTF-8') {
iconv.skipDecodeWarning = true;
inp = iconv.decode(stdout, encoding);
} else {
inp = stdout;
}
//結果をパースする
inp = inp.replace(/r/g, "");
inp = inp.replace(/s+$/, "");
var lines = inp.split("n");
var res = lines.map(function(line) {
return line.replace('t', ',').split(',');
});
callback(err, res);
});
};
};
文章を形態素解析
// mecab-test.js
var Mecab = require('./mecab_sample.js');
var mecab = new Mecab();
var text = "毎週、火曜日は勉強会があります";
mecab.parse(text, function(err, items) {
for (var i in items) {
var k = items[i];
if (k == "EOS") continue;
console.log(k[0] + ":" + k[1]);
}
});
上記ファイルを実行
$ node mecab-test.js
文章を形態素解析
実行結果
毎週:名詞
、:記号
火曜日:名詞
は:助詞
勉強:名詞
会:名詞
が:助詞
あり:動詞
ます:助動詞
文章にふりがなを振る
//furigana.js
//フリガナを振るfor Node.js
//モジュールの取り込み
var fs = require('fs');
var Mecab = require('./mecab_sample.js');
var mecab = new Mecab();
//コマンドラインを調べる
var args = process.argv;
args.shift(); // nodeを除去
args.shift(); //スクリプト名を除去
//引数がなければプログラムの使い方を表示する
if (args.length <= 0) {
console.log("[USAGE] furigana.js入力テキスト");
process.exit();
}
//入力ファイルを読み込む-
var inputfile = args.shift();
var txt = fs.readFileSync(inputfile, "utf-8");
文章にふりがなを振る
//furigana.js
//形態素解析する
mecab.parse(txt, function (err, items) {
var res = "";
for (var i in items) {
var k = items[i];
var word = k[0];
var kana = k[8];
if (k == "EOS") continue;
//フリガナが必要なときを判定
if (word == kana || isHiragana(word)) {
res += word;
} else {
res += word + '(' + kana + ')';
}
}
console.log(res);
});
//ひらがな判定
function isHiragana(s) {
return (s.match(/^[あ-ん]+$/));
}
文章にふりがなを振る
//furigana.txt
たいていの人はほんとうになにがほしいのか、
心の中でわかっています。
人生の目標を教えてくれるのは直感だけ。
ただ、それに耳を傾けない人が多すぎるのです。
実行
$ node furigana.js furigana.txt
文章にふりがなを振る
実行結果
たいていの人(ヒト)はほんとうになにがほしいのか、
心(ココロ)の中(ナカ)でわかっています。
人生(ジンセイ)の目標(モクヒョウ)を
教え(オシエ)てくれるのは直感(チョッカン)だけ。
ただ、それに耳(ミミ)を傾け(カタムケ)ない人(ヒト)が
多(オオ)すぎるのです。
文章校正ツール
校正点
・「いい訳」と「言い訳」などの表記の違い
・「プログラマー」と「プログラマ」などの表記の違い
文章校正ツール
// kousei.js
//文章の校正ツール
var MAX_WORD = 40; //最大単語数の警告
var Mecab = require('./mecab_sample.js');
var mecab = new Mecab();
var fs = require('fs');
//引数をチェック
var args = process.argv;
args.shift(); //除去'node'
args.shift(); //除去 スクリプトのパス
if (args.length <= 0) {
console.log('node kousei.js textfile');
process.exit();
}
var filename = args.shift();
//ファイルを読み込む
var text = fs.readFileSync(filename, "utf-8");
//形態素解析を行う
mecab.parse(text, function(err, items) {
checkTaiou(items);
});
文章校正ツール
//対応チェック
function checkTaiou(items) {
var heiritujosi = 0, cur = [], lineno = 1;
var meisi = {};
var setuzokusi = {}, oldCur = [];
for (var i in items) {
var it = items[i];
var w = it[0];
if (w == "EOS") { //改行
lineno++;
setuzokusi = {};
oldCur = cur; cur = [];
continue;
}
//表記が不統一チェック
if (it[1] == "名詞" && w.length >= 2) {
var kana = it[8];
if (kana == undefined) kana = it[0]; //辞書にない単語対策
kana = kana.replace(/ー/g, ''); //カタカナ対策
if (meisi[kana] == undefined) {
meisi[kana] = w;
} else if (meisi[kana] != w) {
console.log("[確認]表記が不統一: " + meisi[kana] + " != " + w);
}
}
cur.push(w);
}
}
文章校正ツール
//kousei.txt
サーバ設定をするサーバーエンジニア
林檎とりんご
実行
$ node kousei.js kousei.txt
文章校正ツール
実行結果
[確認]表記が不統一:サーバ!=サーバー
[確認]表記が不統一:林檎!=りんご

形態素解析について