「Open JTalk のほぼ定型文のための辞書類のサイズの調査」では縮小化を試みなかったMeCab 辞書類のサイズを小さくすることを試したので、その記録を備忘録として残しておく。 「Open JTalk のほぼ定型文のための辞書類のサイズの調査」では Open JTalk で使用されている mecab のシステム辞書 sys.dic のサイズを小さくすることを試みたが、それ以外の matrix.bin、unk.dic、char.bin はそのままであった。sys.dic は78,490 kBから 7 kBに大幅に小さくなったが、matrix.binが 3,704 kBあり、ESP32を使った M5Stack などのIoT、組み込みシステムには大きすぎる問題が残っていた。
考え方
「Open JTalk のほぼ定型文のための辞書類のサイズの調査」で sys.dic を小さくするときと同様に、定型文で必要なものだけを含むようにすることで、実行時に必要となる辞書類のサイズを小さくする。 用意されているファイルの文脈IDで利用されているものだけを抽出し、その値の範囲が狭くなるようにIDを割り振りなおす。Pythonで処理して小さくしたファイルを生成する。今回は matrix.bin を小さくすることを主たる目的とする。
実行時に必要となるファイル
実行時に必要となるMeCabの辞書類のファイルは以下の通りである。組み込み機器などの資源の乏しい環境で音声合成を可能にするためには、これらのファイルのサイズを小さくすることが必要である。
- sys.dic
- unidic-csj.csv、naist-jdic.csv から生成したシステム辞書
- matrix.bin
- matrix.def をコンパイルしたバイナリファイル
- char.bin
- char.def をコンパイルした文字カテゴリマップのバイナリファイル
- unk.dic
- unk.def から生成した未定義語の品詞等の辞書
入力ファイルの検討
MeCab の辞書構造と汎用テキスト変換ツールとしての利用 を基にして変換する観点から調査した。 以下で利用している例はすべて Open JTalk に同梱されている MeCab の ファイルを処理して生成した派生物(の一部)である。 辞書類を小さくするためには、文脈ID の範囲を小さくするように変換する必要がある。
単語ファイル
mecab-dict-index.exe では、unidic-csj.csv、naist-jdic.csv などの .csv 拡張子をもっているファイルが語彙として処理される。これらは「,」区切りのCSVファイルである。 1行が1単語に相当している。次に例を示す。
1 |
換気,9,9,4519,名詞,サ変接続,*,*,*,*,換気,カンキ,カンキ,0/3,C2 |
左から順に、単語、左文脈ID (left-id)、右文脈ID (right-id)であり、その後が単語に関する情報である。 left-id、right-id は、この後に説明する matrix.def で使用されており、matrix.def によって生成される matrix.bin の大きさは、このID数の最大値によって決まるため、matrix.bin を小さくするためには、id の値の範囲(最大値)を小さくする必要がある。つまり .csvファイルの left-id、right-idを書き換える必要がある。 Open JTalk で用意されている辞書ではleft-idとright-idの文脈IDの割り当ては同じと考えられる。
語彙についての unidic-csj.csv、naist-jdic.csv 以外に以下のファイルが存在する。
matrix.def
連接表 matrix.def の例を次に示す。
1 2 3 4 5 6 7 |
1377 1377 0 0 -323 0 1 1 0 2 -1451 1376 1374 -3640 1376 1375 -1491 1376 1376 -109 |
先頭行が前件文脈ID数、後件文脈ID数を表す。空白で区切られている。ID数はID の最大値+ 1 の値をとる。上記の例では、IDの最大値(最大id)が 1376 のため、id数 は 1377 である。途中で使われていないidがあっても、matrix.def から生成される matrix.bin は、(前件文脈ID数 × 後件文脈ID数) に比例する形で大きくなるので、matrix.bin を小さくするためには、最大ID を小さくする必要があり、結果として2行目以降のID の変換が必要である。
2行目以降が連接表の要素を表し、前件文脈ID、後件文脈ID、コストが空白で区切られている。2行目以降の順序はどのようになっていてもかまわないようである。Open JTalk で用意されているファイルでは ID順にソートされているが、ID順でないファイルでもmatrix.bin の生成には支障がない。 また、同じ前件文脈ID、後件文脈IDに対して複数行があってもエラーなどにはならない。変換処理を行った結果のファイルに重複行があってもそのままでよいことになる。 前件文脈IDと後件文脈IDの割り振りは Open JTalk で用意されている辞書では同じと考えられるので、以下では前件文脈IDと後件文脈IDを区別せず扱う。
matrix.bin のサイズを小さくするために、前件文脈ID、後件文脈IDを変換して、最大IDが小さくなるように処理する。
char.def
char.def は、未知語処理のための文字のカテゴリ定義ファイルとのこと。 unk.def で利用されるカテゴリ名などが定義されている。 処理すべき文脈ID を含まないので、辞書類の縮小のためには何もしない。
char.bin を小さくするためには、何かできることがあるかもしれないが、今回は対象外である。
unk.def
unk.def は未知語用の辞書とのこと。例を次に示す。CSV形式である。
1 2 3 4 5 |
DEFAULT,13,13,4190,記号,一般,*,*,*,* SPACE,14,14,8094,記号,空白,*,*,*,* KANJI,1,1,10654,名詞,一般,*,*,*,* KANJI,10,10,15603,名詞,サ変接続,*,*,*,* SYMBOL,10,10,15331,名詞,サ変接続,*,*,*,* |
オリジナル辞書/コーパスからのパラメータ推定 などには項目についての明確な説明がないが、左から順に、カテゴリ名、前件文脈ID、後件文脈IDであり、その後がカテゴリ情報と考えられる。 文脈ID の変換が必要である。
DEFAULT と SPACE は、明示的に使っていなくても必要なカテゴリラベルのようである。
_left-id.def
_left-id.def は、左文脈ID の定義ファイルである。 左文脈IDとその情報が空白で区切られている。文脈IDについての変換が必要である。
1 2 3 4 5 |
0 BOS/EOS,*,*,*,*,*,BOS/EOS 1 その他,間投,*,*,*,*,* 2 フィラー,*,*,*,*,*,* 3 感動詞,*,*,*,*,*,* 4 記号,アルファベット,*,*,*,*,* |
_right-id.def
Open JTalk に同梱されているものでは _right-id.def と _left-id.def は同一。
feature.def
内部状態の素生列を変換するためのテンプレートとのこと。文脈IDを含まないので辞書類を小さくするための変換は不要のはず。
_rewrite.def
素性列から内部状態素生列への変換の定義とのこと。文脈IDを含まないので辞書類を小さくするための変換は不要のはず。
_pos-id.def
品詞IDの定義とのこと。文脈IDではないので変換は不要のはず。
small-jdic.csv.orig
「Open JTalk のほぼ定型文のための辞書類のサイズの調査」で生成したファイルも文脈IDを変換する必要がある。以下では、このファイルを small-jdic.csv.orig とする。拡張子を .csv とすると mecab-dict-index.exe で処理されてしまうので、異なる拡張子.orig にする。
変換の必要なファイルのまとめ
変換が必要な部分を次にまとめる matrix.def
ファイル名 | 区切り | 変換対象 カラム番号 |
入力文字 コード |
出力文字 コード |
---|---|---|---|---|
matrix.def | 空白 | 0,1 (2行目以降) |
ASCII |
ASCII (utf-8, shift-JIS) |
unk.def | コンマ (CSV) |
1,2 (必須ラベル 処理必要) |
utf-8 | utf-8 |
_left-id.def |
空白 | 0 | utf-8 | utf-8 |
small-jdic.csv.orig | コンマ (CSV) |
1,2 | shift-JIS | shift-JIS |
変換プログラム
文脈IDの割り振り直しの対応関係を示すIDマッピングを生成するプログラムと、IDマッピングに従った変換Iを行うプログラムを Python3 で作成した。
IDマッピングの生成
前処理によって縮小した語彙のCSVファイル small-jdic.csv.orig から IDマッピングを示すファイル id.map を生成する場合を示す。
必須ラベルとして DEFAULT と SPACE がないといけないようなので、それらに対してもIDのマッピングを割り当てる。DEFAULT と SPACE以外にも「ほぼ定型文」に含まれる品詞情報で必須のものがあるかもしれない。その場合には、必須ラベルを増やす必要がある。
python のプログラム例を示す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import os import csv # ファイル名は必要に応じて変更する input_csv_file_name = "small-jdic.csv.orig" mapping_file_name = "id.map" # 初期化 ids = {} labels = {} idNo = 0 # IDマッピング生成関数 def mapping(oldID): global idNo, ids, labels if ids.get(oldID)== None: print(oldID, idNo, ids.get(oldID)) ids[oldID] = idNo labels[idNo] = oldID idNo = idNo + 1 # CSVファイルに基づくIDマッピング dic_csv_file = open(input_csv_file_name, "r", encoding="shift-jis", errors="", newline="" ) dic_file = csv.reader(dic_csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True) for row in dic_file: left = row[1] right = row[2] mapping(left) mapping(right) dic_csv_file.close() # 必須ラベルIDのIDマッピング essential_label_list = ["DEFAULT", "SPACE"] for label in essential_label_list: mapping(label) # IDマッピングの出力 maxid = idNo mapping_file = open(mapping_file_name, "w") for idNo in range(0, maxid): print(labels[idNo], idNo, sep=",", file=mapping_file) mapping_file.close() |
コマンド引数は以下の通り。
1 |
usage: map-id.py [-h] [--mapping_file_name MAPPING_FILE_NAME] [--output_file_name OUTPUT_FILE_NAME]<br />[--encoding ENCODING] [--delimiter DELIMITER] [--special] [--essential_label]<br />input_file_name N [N ...] |
IDマッピングに従った変換
IDマッピングを示すファイル id.map に基づいて変換を行う。
変換プログラム例を示す。出力ファイルを指定する -o オプションもしくはリダイレクトを利用してファイルに保存する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
import sys import argparse import io essential_label_list = ["DEFAULT", "SPACE"] def make_mapping_file(args): input_file_name = args.input_file_name columns = args.columns mapping_file_name = args.mapping_file_name output_file_name = args.output_file_name encoding = args.encoding delimiter = args.delimiter special = args.special essential_label = args.essential_label # 初期化 maxid = 0 ids = {} # マッピングの読み込み mapping_file = open(mapping_file_name, "r", encoding="UTF-8", errors="", newline="" ) for rawline in mapping_file: line = rawline.strip() print(line) row = line.split(",") label = row[0] id = row[1] ids[label] = id maxid = max(maxid, int(id)) mapping_file.close() # convert file input_file = open(input_file_name, "r", encoding=encoding, errors="", newline="" ) if output_file_name : output_file = open(output_file_name, "w", encoding=encoding) else: output_file = io.TextIOWrapper(sys.stdout.buffer, encoding=encoding) first_line = True for rawline in input_file: if (not special) or (not first_line): # normal case line = rawline.strip() list = line.split(delimiter) print(list) values = [ ids.get(list[i]) for i in columns ] print(values) if ( all(values) ) : print(values, len(list)) for i in range(len(list)): if ( i in columns ): print(ids[list[i]], file=output_file, end="") else: print(list[i], file=output_file, end="") if ( i != (len(list)-1) ): print(delimiter, file=output_file, end="") print(file=output_file) elif essential_label : # for unk.def if list[0] in essential_label_list: print(list[0], ids[list[0]], ids[list[0]], *list[3:], sep=",", file=output_file) else: # for matrix.def number_of_id = maxid + 1 print(str(number_of_id) + delimiter + str(number_of_id)) first_line = False input_file.close() output_file.close() if __name__ == '__main__': parser = argparse.ArgumentParser(description='map-id') parser.add_argument("input_file_name", help="input file") parser.add_argument('columns', metavar='N', type=int, nargs='+', help='column number(s) (0-based)') parser.add_argument("--mapping_file_name", "-m", help="id mapping file", default="id.map") parser.add_argument("--output_file_name", "-o", help="output file") parser.add_argument("--encoding", "-e", help="encoding (utf-8 or shift-jis)", default="shift-jis") parser.add_argument("--delimiter", "-d", help="delimiter (',' or ' ')", default=",") parser.add_argument("--special", "-s", help="process first line for matrix.def", action="store_true") parser.add_argument("--essential_label", "-l", help="process essential label list for unk.def", action="store_true") args = parser.parse_args() make_mapping_file(args) |
-d で delimiter を指定する。スペース(" ") もしくはコンマ(",")を指定する。
-e で encoding を指定する。UTF-8 ("utf-8") もしくは Shift-JIS ("shift-jis") を指定する。
small-jdic.csv.orig
「Open JTalk のほぼ定型文のための辞書類のサイズの調査」で生成したファイル(ここでは、small-jdic.csv.orig)にIDマッピングをするためには次のコマンドを実行する。
1 |
python map-id.py small-jdic.csv.orig 1 2 -e "shift-jis" -d "," |
ファイル small-jdic.csv に出力するためには、リダイレクトするか以下のように -o オプションを利用する。これ以降も同様である。
1 |
python map-id.py small-jdic.csv.orig 1 2 -e "shift-jis" -d "," -o small-jdic.csv |
_matrix.def
_matrix.def にIDマッピングをするためには次のコマンドを実行する。
1 |
python map-id.py _matrix.def 0 1 -s -d " " |
-s は先頭行の前件文脈ID数、後件文脈ID数を特別扱いするためのオプションである。
_unk.def
_unk.def にIDマッピングをして、出力を得るためには次のコマンドを実行する。
1 |
python map-id.py _unk.def 1 2 -l -e "utf-8" -d "," |
-l は、必須ラベルを特別扱いするためのオプションである。
_left-id.def, _right-id.def
_left-id.def にIDマッピングをするためには次のコマンドを実行する。
1 |
python map-id.py _left-id.def 0 -e "utf-8" -d " " |
_right-id.def も同様というか、_left-id.def を処理した結果を使えばよい。
変換例
「リビングのCO2濃度は1,234.567890ppmです。
窓を開けて換気してください。」を例文として、mecab で処理して生成した次の small-jdic.csv.org を基にした場合を示す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
リビング,1345,1345,2754,名詞,一般,*,*,*,*,リビング,リビング,リビング,1/4,C1 の,392,392,4274,助詞,連体化,*,*,*,*,の,ノ,ノ,0/1,動詞%F2@0/形容詞%F1 CO2,1345,1345,6910,名詞,一般,*,*,*,*,CO2,シーオーツー,シーオーツー,5/6,C2 濃度,1345,1345,5398,名詞,一般,*,*,*,*,濃度,ノウド,ノード,1/3,C1 は,284,284,3143,助詞,係助詞,*,*,*,*,は,ハ,ワ,0/1,名詞%F1/動詞%F2@0/形容詞%F2@0 1,1355,1355,3025,名詞,数,*,*,*,*,1,イチ,イチ,2/2,C3 ,,1355,1355,4269,名詞,数,*,*,*,*,,,,,,,*/*,* 2,1355,1355,3980,名詞,数,*,*,*,*,2,ニ,ニ,1/1,C3 3,1355,1355,3983,名詞,数,*,*,*,*,3,サン,サン,0/2,C3 4,1355,1355,3882,名詞,数,*,*,*,*,4,ヨン,ヨン,1/2,C1 .,1355,1355,5545,名詞,数,*,*,*,*,.,.,.,*/*,* 5,1355,1355,3518,名詞,数,*,*,*,*,5,ゴ,ゴ,1/1,C3 6,1355,1355,3624,名詞,数,*,*,*,*,6,ロク,ロク,2/2,C3 7,1355,1355,3375,名詞,数,*,*,*,*,7,ナナ,ナナ,1/2,C3 8,1355,1355,3679,名詞,数,*,*,*,*,8,ハチ,ハチ,2/2,C3 9,1355,1355,4540,名詞,数,*,*,*,*,9,キュウ,キュー,1/2,C3 0,1355,1355,2904,名詞,数,*,*,*,*,0,ゼロ,ゼロ,1/2,C3 ppm,1345,1345,11820,名詞,一般,*,*,*,*,* です,485,485,3489,助動詞,*,*,*,特殊・デス,基本形,です,デス,デス’,1/2,名詞%F2@1/動詞%F1/形容詞%F2@0 。,8,8,-31,記号,句点,*,*,*,*,。,。,。,*/*,* 窓,1345,1345,6031,名詞,一般,*,*,*,*,窓,マド,マド,1/2,C3 を,179,179,3914,助詞,格助詞,一般,*,*,*,を,ヲ,ヲ,0/1,動詞%F5/名詞%F1 開け,652,652,4912,動詞,自立,*,*,一段,連用形,開ける,アケ,アケ,0/2,* て,330,330,5055,助詞,接続助詞,*,*,*,*,て,テ,テ,0/1,動詞%F1/形容詞%F1/名詞%F5 換気,1343,1343,4519,名詞,サ変接続,*,*,*,*,換気,カンキ,カンキ,0/3,C2 し,635,635,7768,動詞,自立,*,*,サ変・スル,連用形,する,シ,シ,0/1,* て,330,330,5055,助詞,接続助詞,*,*,*,*,て,テ,テ,0/1,動詞%F1/形容詞%F1/名詞%F5 ください,1292,1292,9213,動詞,非自立,*,*,五段・ラ行特殊,命令i,くださる,クダサイ,クダサイ,3/4,* 。,8,8,-31,記号,句点,*,*,*,*,。,。,。,*/*,* |
id.map
small-jdic.csv.orig を基にして IDマッピングの対応表ファイル id.map を生成する。左側のIDを右側のIDにマッピングする必要があることを示す。最後の2行は、必須ラベルの処理のためのものである。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
1345,0 392,1 284,2 1355,3 485,4 8,5 179,6 652,7 330,8 1343,9 635,10 1292,11 DEFAULT,12 SPACE,13 |
small-jdic.csv
small-jdic.csv.orig にIDマッピングすることで small-jdic.csv を生成する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
リビング,0,0,2754,名詞,一般,*,*,*,*,リビング,リビング,リビング,1/4,C1 の,1,1,4274,助詞,連体化,*,*,*,*,の,ノ,ノ,0/1,動詞%F2@0/形容詞%F1 CO2,0,0,6910,名詞,一般,*,*,*,*,CO2,シーオーツー,シーオーツー,5/6,C2 濃度,0,0,5398,名詞,一般,*,*,*,*,濃度,ノウド,ノード,1/3,C1 は,2,2,3143,助詞,係助詞,*,*,*,*,は,ハ,ワ,0/1,名詞%F1/動詞%F2@0/形容詞%F2@0 1,3,3,3025,名詞,数,*,*,*,*,1,イチ,イチ,2/2,C3 ,,3,3,4269,名詞,数,*,*,*,*,,,,,,,*/*,* 2,3,3,3980,名詞,数,*,*,*,*,2,ニ,ニ,1/1,C3 3,3,3,3983,名詞,数,*,*,*,*,3,サン,サン,0/2,C3 4,3,3,3882,名詞,数,*,*,*,*,4,ヨン,ヨン,1/2,C1 .,3,3,5545,名詞,数,*,*,*,*,.,.,.,*/*,* 5,3,3,3518,名詞,数,*,*,*,*,5,ゴ,ゴ,1/1,C3 6,3,3,3624,名詞,数,*,*,*,*,6,ロク,ロク,2/2,C3 7,3,3,3375,名詞,数,*,*,*,*,7,ナナ,ナナ,1/2,C3 8,3,3,3679,名詞,数,*,*,*,*,8,ハチ,ハチ,2/2,C3 9,3,3,4540,名詞,数,*,*,*,*,9,キュウ,キュー,1/2,C3 0,3,3,2904,名詞,数,*,*,*,*,0,ゼロ,ゼロ,1/2,C3 ppm,0,0,11820,名詞,一般,*,*,*,*,* です,4,4,3489,助動詞,*,*,*,特殊・デス,基本形,です,デス,デス’,1/2,名詞%F2@1/動詞%F1/形容詞%F2@0 。,5,5,-31,記号,句点,*,*,*,*,。,。,。,*/*,* 窓,0,0,6031,名詞,一般,*,*,*,*,窓,マド,マド,1/2,C3 を,6,6,3914,助詞,格助詞,一般,*,*,*,を,ヲ,ヲ,0/1,動詞%F5/名詞%F1 開け,7,7,4912,動詞,自立,*,*,一段,連用形,開ける,アケ,アケ,0/2,* て,8,8,5055,助詞,接続助詞,*,*,*,*,て,テ,テ,0/1,動詞%F1/形容詞%F1/名詞%F5 換気,9,9,4519,名詞,サ変接続,*,*,*,*,換気,カンキ,カンキ,0/3,C2 し,10,10,7768,動詞,自立,*,*,サ変・スル,連用形,する,シ,シ,0/1,* て,8,8,5055,助詞,接続助詞,*,*,*,*,て,テ,テ,0/1,動詞%F1/形容詞%F1/名詞%F5 ください,11,11,9213,動詞,非自立,*,*,五段・ラ行特殊,命令i,くださる,クダサイ,クダサイ,3/4,* 。,5,5,-31,記号,句点,*,*,*,*,。,。,。,*/*,* |
matrix.def
_matrix.def にIDマッピングをすることで matrix.def を生成する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
14 14 5 5 -465 5 6 -174 5 2 148 5 8 1077 5 1 22 5 4 775 5 10 -1232 5 7 -196 5 11 1138 5 9 -155 5 0 -770 5 3 1710 6 5 305 6 6 170 6 2 -990 6 8 542 6 1 -2722 6 4 119 6 10 -5683 6 7 -2813 6 11 1001 6 9 -1235 6 0 -456 6 3 -298 2 5 -64 2 6 1121 2 2 215 2 8 1215 2 1 -1397 2 4 -769 2 10 -2164 2 7 -1475 2 11 -734 2 9 140 2 0 -165 2 3 98 8 5 1192 8 6 1089 8 2 -471 8 8 2965 8 1 198 8 4 229 8 10 -1754 8 7 481 8 11 -4763 8 9 860 8 0 924 8 3 432 1 5 -818 1 6 2169 1 2 2489 1 8 1453 1 1 -4 1 4 1006 1 10 -3941 1 7 -660 1 11 823 1 9 -1782 1 0 -2022 1 3 -1416 4 5 -3309 4 6 -152 4 2 -1005 4 8 -4835 4 1 -1380 4 4 -2855 4 10 751 4 7 1357 4 11 1038 4 9 970 4 0 992 4 3 1092 10 5 -312 10 6 -657 10 2 -1005 10 8 -6344 10 1 -764 10 4 -2384 10 10 -4809 10 7 1140 10 11 -6192 10 9 -1439 10 0 -625 10 3 -2575 7 5 1296 7 6 -630 7 2 -659 7 8 -7302 7 1 -1116 7 4 -1666 7 10 -2497 7 7 52 7 11 -5428 7 9 205 7 0 747 7 3 -1511 11 5 -2265 11 6 379 11 2 -24 11 8 -2858 11 1 579 11 4 -484 11 10 952 11 7 975 11 11 -1746 11 9 1417 11 0 1665 11 3 1521 9 5 -2082 9 6 -4333 9 2 -3117 9 8 455 9 1 -3432 9 4 -1411 9 10 -5273 9 7 -64 9 11 -3412 9 9 -338 9 0 274 9 3 -1206 0 5 -1631 0 6 -4859 0 2 -3418 0 8 25 0 1 -3981 0 4 -2351 0 10 -2520 0 7 -259 0 11 -375 0 9 -577 0 0 35 0 3 -1446 3 5 840 3 6 -1458 3 2 68 3 8 819 3 1 -3209 3 4 -1909 3 10 -1862 3 7 -259 3 11 -635 3 9 -1976 3 0 -1363 3 3 -3222 |
unk.def
_unk.def にIDマッピングすることで unk.def を生成する。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
DEFAULT,12,12,4190,記号,一般,*,*,*,*,* SPACE,13,13,8094,記号,空白,*,*,*,*,* KANJI,0,0,10654,名詞,一般,*,*,*,*,* KANJI,9,9,15603,名詞,サ変接続,*,*,*,*,* SYMBOL,9,9,15331,名詞,サ変接続,*,*,*,*,* NUMERIC,3,3,25847,名詞,数,*,*,*,*,* ALPHA,0,0,11820,名詞,一般,*,*,*,*,* HIRAGANA,0,0,12341,名詞,一般,*,*,*,*,* HIRAGANA,9,9,18559,名詞,サ変接続,*,*,*,*,* KATAKANA,0,0,8360,名詞,一般,*,*,*,*,* KANJINUMERIC,3,3,26419,名詞,数,*,*,*,*,* GREEK,0,0,7019,名詞,一般,*,*,*,*,* CYRILLIC,0,0,6975,名詞,一般,*,*,*,*,* |
left-id.def, right-id.def
_left-id.def にIDマッピングしたファイルを left-id.def とする。
1 2 3 4 5 6 7 8 9 10 11 12 |
5 記号,句点,*,*,*,*,BOS/EOS 6 助詞,格助詞,一般,*,*,*,を 2 助詞,係助詞,*,*,*,*,は 8 助詞,接続助詞,*,*,*,*,て 1 助詞,連体化,*,*,*,*,の 4 助動詞,*,*,*,特殊・デス,基本形,です 10 動詞,自立,*,*,サ変・スル,連用形,する 7 動詞,自立,*,*,一段,連用形,* 11 動詞,非自立,*,*,五段・ラ行特殊,命令i,下さる 9 名詞,サ変接続,*,*,*,*,* 0 名詞,一般,*,*,*,*,* 3 名詞,数,*,*,*,*,* |
結果
上記の処理をしたファイルを基に .bin 、.dic ファイルを生成した。
生成された辞書ファイルのサイズを次の表にまとめる。
サイズ(kB) | mecab-naist-jdic | 文脈IDの割り振り直し後 |
---|---|---|
char.bin | 257 | 257 |
matrix.bin | 3,704 | 1 |
sys.dic | 78,490 | 7 |
unk.dic | 6 | 5 |
今回の処理をすることで matrix.bin のサイズは十分に小さくなり、ESP32などの組み込みシステムでも利用可能なレベルになっていると思う。今回は入力文が非常に短い場合の結果であるが、文を長くしても語彙が限られる「ほぼ定型文」ならかなり小さくできると考える。char.bin のサイズは変わっていない。合計で270kBが必要である。
Text-to-Speechを実際に実行するためには、HTS_engine が必要である。これを含んだ Windows10上の open_talk.exe は 1,411kBであり、音声合成に必要な音響モデルの例の nitech_jp_atr503_m001.htsvoice が1,142kBである。
以上を合計すると2,823kBであり、ESP32に移植してもそれほど大きく変わらなないことが期待できる。M5Stack Core 2 なら PS RAM が8MBで、フラッシュが 16MBなので容量的には動作させることが可能と思われる。
課題
ESP32 用にクロスコンパイルして、M5Stack Core 2で動作させることが次の課題になる。時間ができたら試してみたい。