やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

MeCabユーザ辞書の作り方(Wikipediaの題名を名詞とした)

 Wikipediaのタイトルを名詞としたユーザ辞書を作成した。

成果物

CSVや辞書ファイルはサイズ制約によりアップできなかった

remote: error: Trace: 649cde14516aec807658d0769ac83529        
remote: error: File src/onomasticon.csv is 115.83 MB; this exceeds GitHub's file size limit of 100.00 MB        
remote: error: File src/wikipedia_20190817.dic is 233.50 MB; this exceeds GitHub's file size limit of 100.00 MB        
 ! [remote rejected] master -> master (pre-receive hook declined)

前回まで

問題: MeCabにIT用語辞書がない

$ mecab
クラウド
クラ  名詞,固有名詞,一般,*,*,*,クラ,クラ,クラ
ウド  名詞,一般,*,*,*,*,ウド,ウド,ウド
EOS
仮引数
仮 接頭詞,名詞接続,*,*,*,*,仮,カリ,カリ
引数  名詞,一般,*,*,*,*,引数,ヒキスウ,ヒキスー
EOS

 「クラウド」や「仮引数」は単一の語として認識して欲しい。

手順

  1. データ取得
  2. データの辞書CSV
  3. 辞書CSVコンパイル

1. データ取得

辞書 元データ MeCabCSV 辞書
Wikipedia 40.5MB 116MB 233MB
はてな 20.6MB - -
e-word - - -
mecab-ipadic-NEologd - - -

Wikipedia

$ curl -L http://dumps.wikimedia.org/jawiki/latest/jawiki-latest-all-titles-in-ns0.gz | gunzip > jawiki-latest-all-titles-in-ns0
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   185  100   185    0     0    212      0 --:--:-- --:--:-- --:--:--   212
100 11.3M  100 11.3M    0     0   624k      0  0:00:18  0:00:18 --:--:--  340k

 出力ファイルサイズ40.5MB。「仮引数」などの技術用語を含んでいる。

はてなキーワード

wget http://d.hatena.ne.jp/images/keyword/keywordlist_furigana.csv
sudo apt install nkf
nkf -w --overwrite keywordlist_furigana.csv

 出力ファイルサイズ20.6MB。キーワードは著名人名やネットスラングなどが多い。IT技術用語が欲しいのでこれは不要か。

失敗した方法

curl -L http://d.hatena.ne.jp/images/keyword/keywordlist_furigana.csv | iconv -f euc-jp -t utf-8 > keywordlist_furigana_iconv.csv

 なんかエラーになった。出力ファイルサイズ345KB。

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 14.2M  100 14.2M    0     0  1333k      0  0:00:10  0:00:10 --:--:-- 2263k
iconv: 位置 246869 に不正な入力シーケンスがあります

e-words

断念

 キーワード。

<div id="h1word">
<h1 id="word" style="position:relative">引数</h1>
<span class="alias">&nbsp;<span class="ascii thin">argument</span>&nbsp; <span class="ascii thin">args</span> <span class="sep">/</span> アーギュメント</span>
</div>

 読み。

<aside>
<div id="lastupdate">2017.10.31更新</div>
<div class="clear"></div>
<div id="pron">ひきすう</div>
<div class="clear"></div>
</aside>

 概要。

<div id="Summary"><p><strong>引数</strong>とは、プログラム中で<a href="%E9%96%A2%E6%95%B0.html">関数</a>や<a href="%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89.html">メソッド</a>、<a href="%E3%82%B5%E3%83%96%E3%83%AB%E3%83%BC%E3%83%81%E3%83%B3.html">サブルーチン</a>などを呼び出すときに渡す値のこと。渡された側はその値に従って処理を行い、結果を返す。OSなどで利用者が<a href="%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89.html">コマンド</a>を実行する際に指定する<a href="%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF.html">パラメータ</a>などを指すこともある(<a href="%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E5%BC%95%E6%95%B0.html">コマンドライン引数</a>)。</p></div>
意味
引数 キーワード表記
ひきすう 読み(キーワード表記)
argument 英語表記
args 英語表記(略記)
アーギュメント 読み(英語表記)

 これはサイト丸ごとダウンロードしてからスクレイピングせねばならないか。大変そう。キーワードをCSVで提供してくれたら助かるのだが。

mecab-ipadic-NEologd

 新語集。だがコンパイルには1.5GB以上のメモリが必要らしい。PI3B+では無理。

2. データの辞書CSV

 以下Rubyコードを作成する。

# makedic.rb

require 'csv'

CSV.open("onomasticon.csv", 'w') do |csv|
  %w(jawiki-latest-all-titles-in-ns0 keywordlist_furigana.csv).each do |filename|
    open(filename).each do |title|
      title.strip!

      next if title =~ %r(^[+-.$()?*/&%!"'_,]+)
      next if title =~ /^[-.0-9]+$/
      next if title =~ /曖昧さ回避/
      next if title =~ /_\(/
      next if title =~ /^PJ:/
      next if title =~ /の登場人物/
      next if title =~ /一覧/

      title_length = title.length

      if title_length > 3
        score = [-36000.0, -400 * (title_length ** 1.5)].max.to_i
        csv << [title, nil, nil, score, '名詞', '一般', '*', '*', '*', '*', title, '*', '*']
      end
    end
  end
end

 実行する。5分ほどかかった。

ruby makedic.rb

実行結果

 はてなキーワードファイルを削除したため「keywordlist_furigana.csvが無い」という以下のエラーで終了した。

makedic.rb:5:in `initialize': No such file or directory @ rb_sysopen - keywordlist_furigana.csv (Errno::ENOENT)
    from makedic.rb:5:in `open'
    from makedic.rb:5:in `block (2 levels) in <main>'
    from makedic.rb:4:in `each'
    from makedic.rb:4:in `block in <main>'
    from /usr/lib/ruby/2.3.0/csv.rb:1282:in `open'
    from makedic.rb:3:in `<main>'

 onomasticon.csvファイルが作成される。116MB。

ls -1 | grep onomasticon.csv
onomasticon.csv

MeCabレコード

表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音

3. 辞書CSVコンパイル

/usr/lib/mecab/mecab-dict-index \
-d /usr/share/mecab/dic/ipadic \
-u wikipedia_20190817.dic \
-f utf-8 \
-t utf-8 \
onomasticon.csv

 コンパイルには5分ほどかかった。wikipedia_20190817.dicファイルサイズは233MB。

 ネットにある情報どおりにいかず苦労した。

失敗ログ

/usr/local/libexec/mecab/mecab-dict-index \
-d /usr/local/lib/mecab/dic/ipadic \
-u wikipedia_20190817.dic \
-f utf-8 \
-t utf-8 \
onomasticon.csv
dictionary_compiler.cpp(82) [param.load(DCONF(DICRC))] no such file or directory: /usr/local/lib/mecab/dic/ipadic/dicrc
find / -name "mecab-dict-index"
/usr/lib/mecab/mecab-dict-index
find / -name "dicrc"
/var/lib/mecab/dic/juman/dicrc
/var/lib/mecab/dic/ipadic-utf8/dicrc
/var/lib/mecab/dic/ipadic/dicrc
/usr/share/mecab/dic/juman/dicrc
/usr/share/mecab/dic/ipadic/dicrc

 許可がありませんというのが大量に出るが無視。それ以外をピックアップ。

 上記2つのパスを使って以下のようなコマンドに修正して実行。

/usr/lib/mecab/mecab-dict-index \
-d /var/lib/mecab/dic/ipadic-utf8 \
-u wikipedia_20190817.dic \
-f utf-8 \
-t utf-8 \
onomasticon.csv
/var/lib/mecab/dic/ipadic-utf8/pos-id.def is not found. minimum setting is used
reading onomasticon.csv ... dictionary_rewriter.cpp(136) [ifs] no such file or directory: /var/lib/mecab/dic/ipadic-utf8/rewrite.def

 rewrite.defを探す。

find / -name "rewrite.def"
/usr/share/mecab/dic/juman/rewrite.def
/usr/share/mecab/dic/ipadic/rewrite.def

 ipadic-utf8にはないが、ipadic,jumanにはある。

 以下のようにコマンド修正して実行。

/usr/lib/mecab/mecab-dict-index \
-d /var/lib/mecab/dic/ipadic \
-u wikipedia_20190817.dic \
-f utf-8 \
-t utf-8 \
onomasticon.csv
/var/lib/mecab/dic/ipadic/pos-id.def is not found. minimum setting is used
reading onomasticon.csv ... dictionary_rewriter.cpp(136) [ifs] no such file or directory: /var/lib/mecab/dic/ipadic/rewrite.def

 またエラー。たしかにrewrite.def/var/lib配下に存在しない。/usr/share配下にあるのだから。

 dicrc//var/lib配下と/usr/share配下の2つある。rewrite.def/usr/shareのほうにしかないっぽいので、dicrc/のパスを/usr/shareのほうに変える。

/usr/lib/mecab/mecab-dict-index \
-d /usr/share/mecab/dic/ipadic \
-u wikipedia_20190817.dic \
-f utf-8 \
-t utf-8 \
onomasticon.csv

 できた!

 ちなみに、以下のようにしたが「許可がありません」行を消せなかった。

find / -name "rewrite.def" 2>/dev/null # 「許可がありません」消えず
sudo find / -name "rewrite.def" 2>/dev/null # 応答なし
find / -name "rewrite.def" -v "許可がありません" # 「許可がありません」消えず

4. 使ってみる

mecab -u wikipedia_20190817.dic
クラウド
クラウド    名詞,一般,*,*,*,*,クラウド,*,*
EOS
仮引数
仮 接頭詞,名詞接続,*,*,*,*,仮,カリ,カリ
引数  名詞,一般,*,*,*,*,引数,ヒキスウ,ヒキスー
EOS

 「クラウド」は単語になったが「仮引数」が変わらず分離されてしまう。

echo 'レーベンシュタイン距離' | mecab --unk-feature "未知語"
レーベンシュタイン 未知語
距離  名詞,一般,*,*,*,*,距離,キョリ,キョリ
EOS
echo 'レーベンシュタイン距離' | mecab -u wikipedia_20190817.dic --unk-feature "未知語"
レーベンシュタイン距離   名詞,一般,*,*,*,*,レーベンシュタイン距離,*,*
EOS

 あれ、こちらでは最後の列がwikipediaとなっているのに……。

echo "クラウドファンディングを有効活用する。" | mecab -Owakati
クラウドファンディング を 有効 活用 する 。 

5. ユーザ辞書パス設定(mecabrc

find / -name "mecabrc"
/etc/mecabrc
sudo leafpad /etc/mecabrc
;
; Configuration file of MeCab
;
; $Id: mecabrc.in,v 1.3 2006/05/29 15:36:08 taku-ku Exp $;
;
dicdir = /var/lib/mecab/dic/debian

; userdic = /home/foo/bar/user.dic

; output-format-type = wakati
; input-buffer-size = 8192

; node-format = %m\n
; bos-format = %S\n
; eos-format = EOS\n

 以下のように任意パスに指定する。

userdic = /home/pi/root/sys/workflow/db/dictionary/mecab/userdic/wikipedia_20190817.dic

 保存して終了。

 ターミナルで以下コマンド実行。ユーザ辞書のパスを渡さずとも、ユーザ辞書が反映されて「クラウド」が単語になった。

mecab
クラウド
クラウド    名詞,一般,*,*,*,*,クラウド,*,*
EOS

update-alternatives

sudo update-alternatives --config mecab-dictionary
alternative mecab-dictionary (/var/lib/mecab/dic/debian を提供) には 3 個の選択肢があります。

  選択肢    パス                          優先度  状態
------------------------------------------------------------
* 0            /var/lib/mecab/dic/ipadic-utf8   80        自動モード
  1            /var/lib/mecab/dic/ipadic        70        手動モード
  2            /var/lib/mecab/dic/ipadic-utf8   80        手動モード
  3            /var/lib/mecab/dic/juman         30        手動モード

現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください: 

 mecab-dictionaryという名前で/var/lib/mecab/dic/ipadic-utf8を指すことができる。でもこいつ、ユーザ辞書作成するときにrewrite.defが無いとエラーを吐かれたパス……。何の役に立つの?

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux