74219
Ubuntu 20.10の環境で、最新バージョンの[UniDic-
CWJ-2.3.0](https://unidic.ninjal.ac.jp/download)で[MeCab
0.996](http://taku910.github.io/mecab/)のユーザー辞書を作成したいですが、エラーが出ます。

下記を実行しました。

```

    $ /usr/local/libexec/mecab/mecab-dict-index -d /usr/local/lib/unidic/unidic-cwj-2.3.0 -u ~/foo/bar/foo.dic -f utf8 -t utf8 ~/foo/bar/foo.csv
    
```

foo.csvは下記です。

```

    ダイバーシティ,,,-200,名詞,普通名詞,一般,*,*,*,ダイバーシティ,ダイバーシティ-diversity,ダイバーシティ,ダイバーシティ,ダイバーシティ,ダイバーシティ,外,*,*,*,*,*,*,体,ダイバーシティ,ダイバーシティ,ダイバーシティ,ダイバーシティ,,,,,
    
```

[MeCabの説明書](https://taku910.github.io/mecab/dic.html)によって、左文脈IDと右文脈IDは「空にしておくとmecab-
dict-indexが自動的にIDを付与します」が、下記のエラーが出ました。

```

    dictionary.cpp(355) [cid->left_size() == matrix.left_size() && cid->right_size() == matrix.right_size()] Context ID files(/usr/local/lib/unidic/unidic-cwj-2.3.0/left-id.def or /usr/local/lib/unidic/unidic-cwj-2.3.0/right-id.def may be broken
    
```

下記のURLで似ている問題がありますが、解決方法は書いてありません。  
<https://github.com/taku910/mecab/issues/42>

しかし、旧バージョンの[unidic-
mecab-2.1.2](https://unidic.ninjal.ac.jp/back_number#unidic_bccwj)で辞書をコンパイルすることができます。

```

    $ /usr/local/libexec/mecab/mecab-dict-index -d ~/mecab/unidic-mecab-2.1.2_src/ -u ~/foo/bar/foo.dic -f utf8 -t utf8 ~/foo/bar/foo.csv
    ./pos-id.def is not found. minimum setting is used
    emitting double-array: 100% |###########################################|
    done!
    
```

[unidic-py](https://github.com/polm/unidic-
py/tree/master/extras)からのreiwa.33.csvを使ったら、最新バージョンのUniDic
2.3.0でMeCabの辞書をコンパイルすることもできます。

```

    /usr/local/libexec/mecab/mecab-dict-index -d /usr/local/lib/unidic/unidic-cwj-2.3.0 -u ~/foo/bar/reiwa33.dic -f utf8 -t utf8 ~/foo/bar/reiwa.33.csv
    /usr/local/lib/unidic/unidic-cwj-2.3.0/pos-id.def is not found. minimum setting is used
    reading /home/foo/bar/reiwa.33.csv ... 3
    emitting double-array: 100% |###########################################| 
    done!
    
```

reiwa.33.csvは下記です。

```

    令和,4786,4786,8205,名詞,固有名詞,一般,*,*,*,レイワ,令和,令和,レーワ,令和,レーワ,固,*,*,*,*,*,*,*,レイワ,レイワ,レイワ,レイワ,"1,0",*,*,*,*
    ㋿,5969,5969,2588,補助記号,一般,*,*,*,*,,㋿,㋿,,㋿,,記号,*,*,*,*,*,*,*,,,,,*,*,*,*,999999
    ㋿,4786,4786,3992,名詞,固有名詞,一般,*,*,*,レイワ,令和,㋿,レーワ,㋿,レーワ,固,*,*,*,*,*,*,*,レイワ,レイワ,レイワ,レイワ,"1,0",*,*,*,*
    
```

foo.csvとreiwa.33.csvの違いは、reiwa.33.csvに左文脈IDと右文脈IDが書いてあります。

ですから、左文脈IDと右文脈IDが必要みたいです。

左文脈IDと右文脈IDの選択方法をご教示いただけませんでしょうか。

どうぞよろしくお願いいたします。
CC BY-SA 4.0
2021-02-21T10:11:27.193
74178
2021-02-25T11:16:32.287
2021-02-25T11:16:32.287
3060
44059
question
ubuntu mecab
UniDic-2.3.0でMeCabのユーザー辞書をコンパイルする時、左と右の文脈IDの選択方法をお教えください。
アサーションに失敗しているのは以下の `CHECK_DIE(cid->left_size() == ...` の部分です。

**dictionary.cpp**

```

    if (!cid.get()) {
      cid.reset(new ContextID);
      cid->open(left_id_file.c_str(),
                right_id_file.c_str(), &config_iconv);
      CHECK_DIE(cid->left_size()  == matrix.left_size() &&
                cid->right_size() == matrix.right_size())
          << "Context ID files("
          << left_id_file
          << " or "
          << right_id_file << " may be broken";
    }
    
```

`cid->left_size()` が左文脈IDの個数, `cid->right_size()`
が右文脈IDの個数です。また、`matrix.left_size()` と `matrix.right_size()` は UniDic の
`matrix.def` ファイルの1行目に書かれている数値です(文脈IDは `0` から始まるので `+1`
になっています)。ただ、`matrix.bin` ファイルが存在する場合は、そちらを優先的に読み込みます(内容は `matrix.def` と同一)。

```

    $ tail -1 unidic-cwj-2.3.0/left-id.def
    18291 連体詞,*,*,*,*,*,*,*,混,*,*,*,4,*,*
    $ tail -1 unidic-cwj-2.3.0/right-id.def
    20489 連体詞,*,*,*,*,*,*,*,混,*,*,*,4,*,*
    $ head -1 unidic-cwj-2.3.0/matrix.def
    20490 18292
    
```

デバッグオプション(`-g`)を付けて MeCab をビルドして、gdb で実行経過をトレースします。

```

    $ gdb /usr/local/libexec/mecab/mecab-dict-index
                     :
    
    (gdb) break dictionary.cpp:352
    (gdb) run -d /var/tmp/unidic/unidic-cwj-2.3.0 -u foo.dic -f utf8 -t utf8 foo.csv
                     :
    
    Breakpoint 1, MeCab::Dictionary::compile (param=...,
        dics=std::vector of length 1, capacity 1 = {...}, output=0x7fffffffdc90 "foo.dic")
        at dictionary.cpp:352
    352               cid.reset(new ContextID);
    (gdb) next 2
    (gdb) p cid
    $1 = {
      _vptr.scoped_ptr = 0x7ffff7fa4810 <vtable for MeCab::scoped_ptr<MeCab::ContextID>+16>, ptr_ = 0x55555556aef0}
    (gdb) p cid.ptr_.left_.size()
    $2 = 18292
    (gdb) p cid.ptr_.right_.size()
    $3 = 20490
    
    (gdb) p matrix.lsize_
    $4 = 20490
    (gdb) p matrix.rsize_
    $5 = 18292
    
```

`matrix.left_size()` と `matrix.right_size()` が逆になっている事が判ります。これは
`connector.cpp` で設定されています。

**connector.cpp**

```

    bool Connector::open(const char* filename,
                         const char *mode) {
      CHECK_FALSE(cmmap_->open(filename, mode))
          << "cannot open: " << filename;
    
      matrix_ = cmmap_->begin();
    
      CHECK_FALSE(matrix_) << "matrix is NULL" ;
      CHECK_FALSE(cmmap_->size() >= 2)
          << "file size is invalid: " << filename;
    
      lsize_ = static_cast<unsigned short>((*cmmap_)[0]);
      rsize_ = static_cast<unsigned short>((*cmmap_)[1]);
                         :
    
```

左、右の順序で読み込んでいますが、先程示した様に、`matrix.def` では右、左の順序になっています。

```

    $ tail -1 unidic-cwj-2.3.0/left-id.def
    18291 連体詞,*,*,*,*,*,*,*,混,*,*,*,4,*,*
    $ tail -1 unidic-cwj-2.3.0/right-id.def
    20489 連体詞,*,*,*,*,*,*,*,混,*,*,*,4,*,*
    $ head -1 unidic-cwj-2.3.0/matrix.def
    20490 18292
    
```

そこで `matrix.def`, `unk.def`, `lex.csv` の右・左文脈IDを入れ替えます。

```

    $ awk 'NR==1{print $2, $1}NR>1{print $2, $1, $3}' matrix.def > matrix.def.reverse_lr
    $ mv matrix.def matrix.def.org
    $ ln -sf matrix.def.reverse_lr matrix.def
    $ awk -F, -vOFS=, '{tmp=$2;$2=$3;$3=tmp;print}' unk.def > unk.def.reverse_lr
    $ mv unk.def unk.def.org
    $ ln -sf unk.def.reverse_lr unk.def
    $ awk -vFPAT='([^,]+)|(\"[^\"]+\")' -vOFS=, '{tmp=$2;$2=$3;$3=tmp;print}' lex.csv > lex.csv.reverse_lr
    $ mv lex.csv lex.csv.org
    $ ln -sf lex.csv.reverse_lr lex.csv
    
```

`matrix.bin` などを再作成します(2~3時間程度かかるかもしれません)。

```

    $ /usr/local/libexec/mecab/mecab-dict-index -f utf8 -t utf8 -m matrix.def
    
```

`foo.csv` の中身は以下の様にします(`unidic` 形式)。

**foo.csv**

```

    ダイバーシティ,,,-200,名詞,普通名詞,一般,*,*,*,ダイバーシティ,ダイバーシティ-diversity,ダイバーシティ,ダイバーシティ,ダイバーシティ,ダイバーシティ,外,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
    
```

`foo.dic` を作成して形態素解析を行います。

```

    $ /usr/local/libexec/mecab/mecab-dict-index -d unidic-cwj-2.3.0 -u foo.dic -f utf8 -t utf8 foo.csv
    
    $ printf 'ダイバーシティとは何ですか？' | mecab -d unidic-cwj-2.3.0 -u foo.dic
    ダイバーシティ 名詞,普通名詞,一般,,,,ダイバーシティ,ダイバーシティ-diversity,ダイバーシティ,ダイバーシティ,ダイバーシティ,ダイバーシティ,外,,,,,,,,,,,,,,,,
    と   助詞,格助詞,,,,,ト,と,と,ト,と,ト,和,,,,,,,格助,ト,ト,ト,ト,,名詞%F1,動詞%F1,形容詞%F2@-1,,7099014038299136,25826
    は   助詞,係助詞,,,,,ハ,は,は,ワ,は,ワ,和,,,,,,,係助,ハ,ハ,ハ,ハ,,動詞%F2@0,名詞%F1,形容詞%F2@-1,,8059703733133824,29321
    何   代名詞,,,,,,ナニ,何,何,ナニ,何,ナニ,和,,,,,,,体,ナニ,ナニ,ナニ,ナニ,0,1,,,7674599819059712,27920
    です  助動詞,,,,助動詞-デス,終止形-一般,デス,です,です,デス,です,デス,和,,,,,,,助動,デス,デス,デス,デス,,形容詞%F2@-1,動詞%F2@0,名詞%F2@1,,7051468750332587,25653
    か   助詞,副助詞,,,,,カ,か,か,カ,か,カ,和,,,,,,,副助,カ,カ,カ,カ,,動詞%F2@0,形容詞%F2@-1,名詞%F1,,1530528809492992,5568
    ？   補助記号,句点,,,,,,？,？,,？,,記号,,,,,,,補助,,,,,,,,15676664324608,57
    EOS
    
```
CC BY-SA 4.0
2021-02-23T03:15:18.607
74219
2021-02-25T05:17:40.130
2021-02-25T05:17:40.130
44059
74178
answer