Chapter 04

ユーザー辞書の使い方

ikawaha
ikawaha
2021.06.02に更新

形態素解析結果についてもっと細かな調整をしたい!という要望もあるかなと思うのですが、これまで特に要望をもらったこともなかったのでユーザー辞書についてはそのままにしてきました。新しい形態素を拾いたいとか、辞書に載ってない形態素があって解析がいつもうまくいかない、とかそういったときに利用できる最低限の機能を提供します。

とはいえ、ユーザー辞書の形態素はコストを設定できないので、やはり不満が出てくることもあるかと思います。コストの設定までやってもいい気もするのですが、とりあえず単純なわかりやすい(実装が楽な)動作になっています。ご要望があれば issue いただければと思います。

  • ユーザー辞書に登録された語彙は最優先で使われます
  • ユーザー辞書の利用するには次の 3 つの方法があります
    • ユーザー辞書ファイルを用意して作成する
    • JSON で読み込んで作成する
    • 任意のデータから kagome のユーザー辞書構造体にコピーして作成する

ユーザー辞書ファイルを用意する

これは kuromoji のユーザー辞書と同じ形式です。

ここにサンプルがあります。

https://github.com/ikawaha/kagome/blob/master/_sample/userdic.txt
# コメントは # 始まりで書けます
# 1行1レコードとして形態素を登録できます
# 最初に見出し、そのあとに分割形式(分割は半角スペースで)、あとは対応するヨミと品詞です

日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞
関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム地名
朝青龍,朝青龍,アサショウリュウ,カスタム人名

これをファイルから読んでユーザー辞書を生成します。

        udic, err := tokenizer.NewUserDicRecords(user_dic_path)

同じ形態素が辞書にあったとしても、ユーザー辞書に登録されたものが最優先で利用されます。

JSON から読み込む

JSON にユーザー辞書を記録しておいて、それを読み込んでユーザー辞書を作成する方法もあります。
JSON の形式は以下のサンプルを見てもらえればわかると思います。ユーザー辞書ファイルと同じです。

一旦、UserDicRecord という構造体に読み込んでから、NewUserDic() すればユーザー辞書が生成されます。

        var rec tokenizer.UserDicRecords
        json.Unmarshal([]byte(`[
        {
            "text":"日本経済新聞",
            "tokens":["日本","経済","新聞"],
            "yomi":["ニホン","ケイザイ","シンブン"],
            "pos":"カスタム名詞"
        },
        {
            "text":"朝青龍",
            "tokens":["朝青龍"],
            "yomi":["アサショウリュウ"],
            "pos":"カスタム人名"
        }]`), &rec)
        udic, err := rec.NewUserDic()

独自のデーターをユーザー辞書として使いたいとき

独自に持ってるデータを使ってユーザー辞書を用意したいときは、UserDicRecords に形態素情報を詰め込んで、NewUserDic() してください。

        r := UserDicRecords{
                {
                        Text:   "日本経済新聞",
                        Tokens: []string{"日本", "経済", "新聞"},
                        Yomi:   []string{"ニホン", "ケイザイ", "シンブン"},
                        Pos:    "カスタム名詞",
                },
                {
                        Text:   "朝青龍",
                        Tokens: []string{"朝青龍"},
                        Yomi:   []string{"アサショウリュウ"},
                        Pos:    "カスタム人名",
                },
        }
        udic, err := r.NewUserDic()

ユーザー辞書の設定方法

上で用意したユーザー辞書を実際に使うサンプルです。

package main

import (
  "fmt"

  "github.com/ikawaha/kagome-dict/dict"
  "github.com/ikawaha/kagome-dict/ipa"
  "github.com/ikawaha/kagome/v2/tokenizer"
)

func main() {
  // ユーザー辞書を用意
  udic, err := dict.NewUserDict("userdict.txt")
  if err != nil {
    panic(err)
  }
  // オプションでユーザー辞書を設定
  t, err := tokenizer.New(ipa.Dict(), tokenizer.UserDict(udic), tokenizer.OmitBosEos())
  if err != nil {
    panic(err)
  }
  tokens := t.Analyze("関西国際空港限定トートバッグ", tokenizer.Search)
  for _, token := range tokens {
    fmt.Printf("%s\t%v\n", token.Surface, token.Features())
  }
}

Output:

関西国際空港	[テスト名詞 関西/国際/空港 カンサイ/コクサイ/クウコウ]
限定	[名詞 サ変接続 * * * * 限定 ゲンテイ ゲンテイ]
トートバッグ	[名詞 一般 * * * * *]