mecab-spawn

1.0.1 • Public • Published

mecab-spawn

mecab-spawn は形態素解析器 MeCab とのプロセス間通信を簡易化するパッケージです。

インストール

npm install mecab-spawn

使い方

MeCab プロセスのスポーン

const mecabSpawn = require('mecab-spawn')
const mecab = mecabSpawn.spawn()

spawn() は引数がない場合、パスの通った mecab コマンドを実行しようとします。引数を指定した場合は child_process.spawn() にそのまま渡されます。

// UniDic 辞書を使用する
const mecab = mecabSpawn.spawn('mecab', ['-d', '/usr/local/lib/mecab/dic/unidic-mecab'])

解析

以下の例は文字列を解析し結果をコンソールに出力します。

mecab.analyze('メカブ\nスポーン')
  .then(result => {
    console.log(result)
  }).catch(err => {
    console.error(err)
  })
// => [ [ 'メカブ', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ],
//      'EOS',
//      [ 'スポーン', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ] ]

ファイルの内容を解析する場合、ファイルと辞書のエンコーディングが同じであれば analyze()Bufferオブジェクトを渡すことでデコード処理を省けます。

fs.readFile('filename.txt', 'utf-8', (err, data) => {
  if (err) {
    console.error(err)
  } else {
     mecab.analyze(data)
       .then(console.log)
       .catch(console.error)
  }
})

MeCab プロセスの終了

mecab.analyze('...').then(console.log)

mecab.kill()
  .then(message => {
    console.log(message)
  }).catch(err => {
    console.error(err)
  })
// => MeCab process is killed.

analyze() は非同期で実行されますが、mecab-spawn はタスクのキューを持つため kill() は解析結果が返された後に実行されます。

行パース関数

解析結果のうち eos のみ mecab.getEOSObject() の値がそのまま使われ、残りは全て行パース関数が処理します。

MeCab の解析結果に対して、初期状態では慣例的に \t, で行を分割した文字列の配列を返します。具体的には line.split(/[\t,]/) を実行するだけです。

これを手早く変更するには以下のように createLineParser() でパース関数を作成し設定します。

// カンマのみで行を分割する
mecab.lineParser = mecab.createLineParser(',')

行パース関数には自分で作成した関数を設定できます。 以下はUniDicの初期書式の行をオブジェクトとして返す行パース関数の設定例です。

// Make UniDic default morpheme an Object.
//   node-format-unidic: %m\t%f[9]\t%f[6]\t%f[7]\t%F-[0,1,2,3]\t%f[4]\t%f[5]\t%f[23]\n
//   unk-format-unidic:  %m\t%m\t%m\t%m\t%F-[0,1,2,3]\t%f[4]\t%f[5]\t0\n
mecab.lineParser = line => {
  if (line === 'BOS') {
    return 'BOS'
  }
  const tokens = line.split('\t')
  if (tokens.length !== 8) {
    return { whatIsThis: line }
  }
  const m = { surface: tokens[0] }
  if (tokens[1]) m.pron = tokens[1]
  if (tokens[2]) m.lForm = tokens[2]
  if (tokens[3]) m.lemma = tokens[3]
  const posArray = tokens[4].split('-')
  m.pos1 = posArray[0]
  if (posArray[1]) m.pos2 = posArray[1]
  if (posArray[2]) m.pos3 = posArray[2]
  if (posArray[3]) m.pos4 = posArray[3]
  if (tokens[5]) m.cType = tokens[5]
  if (tokens[6]) m.cForm = tokens[6]
  if (tokens[7]) m.aType = Number(tokens[7])
  return m
}

辞書のコーディングシステム

初期状態では UTF-8 辞書にのみ対応していますが、辞書に対応したエンコード/デコード関数を設定することで UTF-8 以外にも対応することができます。

npm install iconv-lite
// iconv-lite で EUC-JP 辞書に対応する
const iconv = require('iconv-lite')
// UTF-8 => EUC-JP
// EUC-JP のファイルを直接読ませる場合は不要
mecab.setDefaultEncoder(data => iconv.encode(data, 'eucjp'))
// EUC-JP => UTF-8
mecab.setDefaultDecoder(data => iconv.decode(data, 'eucjp'))

あるいは analyze() にエンコード/デコード関数を指定することで優先的に解析元データに合わせて変更できます。

const eucjpDecoder = data => iconv.decode(data, 'eucjp')
mecab.analyze(data, null, eucjpDecoder)

EOS オブジェクト

初期状態の解析結果では eos"EOS" 文字列オブジェクトですが、その後の処理の為に必要であれば変更可能です。

// 配列に入った eos を設定する。
mecab.setEOSObject(['EOS'])
mecab.analyze('メカブ\nスポーン\nスポーン').then(console.log)
// => [ [ 'メカブ', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ],
        [ 'EOS' ],
        [ 'スポーン', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ],
        [ 'EOS' ],
        [ 'スポーン', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ] ]

EOS フォーマット

mecab-spawnMeCab の解析出力完了時を調べるためにバイト列中の eos 出現回数を数えることで判断します。もし解析結果とeos-formatの区別がつかない場合は解析結果の読み取りに失敗します。

EOS フォーマットを設定する際に Windows や Mac で \rを設定する必要はありません。MeCab は \n を自動的に OS に合わせた改行文字で出力するからです。

// eos を変更する
mecabIPC.spawn('mecab', ['--eos-format=End\\sof\\sSentence\\n'])
mecab.setEOSSample('End of Sentence\\n')

Readme

Keywords

Package Sidebar

Install

npm i mecab-spawn

Weekly Downloads

0

Version

1.0.1

License

MIT

Unpacked Size

15.9 kB

Total Files

5

Last publish

Collaborators

  • rasensuihei