Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

事前学習済みモデル

Litsea は models/ ディレクトリに複数の事前学習済みモデルを同梱しています。

モデルの入手

モデルはリポジトリの models/ ディレクトリにあります。加えて、各リリースでは 8 つの言語モデルを個別のアセットとして添付しています。

https://github.com/mosuka/litsea/releases/download/<tag>/japanese.model
https://github.com/mosuka/litsea/releases/download/<tag>/japanese_pos.model
...

これらの URL はリリースごとに固定で、必要な言語だけを取得できます(8 個すべてで 24MB に対し、1 つあたり 84KB〜8MB)。これにより次の 2 つが可能になります。

  • remote_model feature を有効にすれば、CLI やライブラリが URL を直接受け取れます: litsea segment -l japanese https://github.com/mosuka/litsea/releases/download/<tag>/japanese.model
  • fromUri を持たない WebAssembly バインディングでも、ページ側で fetch してバイト列を Segmenter.fromBytes に渡せます

main ではなくリリースタグを指定しておくと、デプロイ先のモデル重みが固定されます。モデルはリリース間で再学習されることがあり、held-out スコアもそれに伴って変わります。

モデルカタログ

単語分割モデルは、学習コーパスの held-out テスト分割(学習に使用していない文)で 評価しています。単語 F1(Word F1) は単語の完全一致、境界 F1(Boundary F1) は個々の境界判定のスコアです。なお train コマンドが出力するのは学習データ自身で 測った in-sample 指標であり、ここに示す held-out の値より高くなる点に注意して ください。

アルゴリズムについての注記: japanese.modelchinese.modelkorean.modelenglish.model は 2 クラス(境界/非境界)の Averaged Perceptron として学習した後、 スカラーの特徴量重みへ畳み込んでいます(issue #165)。ファイル自体は従来どおり プレーンな AdaBoost テキスト形式のままで、Segmenter::with_learner / AdaBoost::load_model_from_path は無変更で動作します。この畳み込みは 無損失な変換であり(導出は scripts/collapse_binary_perceptron.py の docstring を参照)近似ではありません: この方法で学習した perceptron は、 同じコーパス・同じテンプレートで AdaBoost の presence-stump 弱学習器より 大幅に高い held-out 品質に達します。代わりにモデルファイルは大きくなり (非ゼロ重みを持つ特徴量が増えるため)、学習手順も通常の train ではなく train --perceptron を経由します(詳細は下記の学習手順を参照)。

japanese.model

プロパティ
言語日本語
学習コーパスUD Japanese-GSD
エポック数50
剪定後の特徴量数|重み| 上位 40,000
単語 F1(held-out)96.70%
境界 F1(held-out)98.59%
ファイルサイズ約 1.1 MB

korean.model

プロパティ
言語韓国語
学習コーパスUD Korean-GSD(空白保持 TSV コーパス)
エポック数30
特徴量テンプレートタグなし(pointwise、issue #183)
剪定後の特徴量数剪定なし(3,132 特徴量)
単語 F1(held-out)99.91%
境界 F1(held-out)99.96%
ファイルサイズ約 86 KB

韓国語モデルは、元の語節(어절)間の空白を保持したテキストで学習・評価して います(各空白は独立したトークンとして扱い、空白トークンは F1 の計算から 除外します)。韓国語では空白がほとんどの語境界を示すため、学習時に空白を 参照できるモデルは UD Korean-GSD の基準をほぼ決定的に解決できます – これが 韓国語の特徴量数・ファイルサイズが小さいままである理由でもあります(モデルが 学習すべき曖昧性がほとんど残っていないため)。日本語と 中国語は空白を使わずに表記されるため、プロトコルは従来のままです。

さらに韓国語モデルは 16 個のタグ依存特徴量テンプレートUP*/BP*/UQ*/BQ*/TQ*。直前 1〜3 文字の境界判定結果を参照する)を 使わずに学習しています: 空白シグナルがあるため、これらのテンプレートは 計測上何も寄与していませんでした(タグなし 99.91% vs タグあり 99.90%、 特徴量は約 22% 減)。タグ依存特徴を持たないモデルは pointwise – 各位置の判定が入力テキストのみに依存する – ため、segment() は逐次 スコアリングパスを丸ごとスキップします(issue #183)。他言語での トレードオフは後述のタグなし(pointwise)モデル を参照してください。

english.model

プロパティ
言語英語
学習コーパスUD English-EWT(空白保持 TSV コーパス)
エポック数20
特徴量テンプレートタグなし(pointwise、issue #183)、WC 特徴量なし
剪定後の特徴量数剪定なし(4,794 特徴量)
単語 F1(held-out)98.31%
境界 F1(held-out)99.18%
ファイルサイズ約 125 KB

korean.model と同様に english.model も、元の空白を保持したテキストで 学習・評価しています(各空白は独立したトークンとして扱い、F1 の計算からは 除外します)。空白保持の学習プロトコル、複数語トークン(短縮形)の扱い、 20 エポックとタグなし/WC 特徴量なしの構成を選んだエポックスイープについては English を参照してください。英語には短縮形 (contraction)、ハイフンでつながる複合語、“U.S.” のような略語といった 境界の曖昧性が残っているため、同じ空白保持レシピを共有していても、 held-out の単語 F1 は韓国語のほぼ決定的な 99.91% を下回ります。

chinese.model

プロパティ
言語中国語(簡体字・繁体字)
学習コーパスUD Chinese-GSD
エポック数100
剪定後の特徴量数|重み| 上位 70,000
単語 F1(held-out)90.69%
境界 F1(held-out)95.64%
ファイルサイズ約 2.0 MB

RWCP.model

プロパティ
言語日本語
ソースオリジナルの TinySegmenter から抽出
ライセンスBSD 3-Clause (Taku Kudo)
ファイルサイズ約 22 KB

JEITA_Genpaku_ChaSen_IPAdic.model

プロパティ
言語日本語
学習コーパスJEITA プロジェクト 杉田玄白コーパス
トークナイザChaSen with IPAdic
ファイルサイズ約 16 KB

学習手順

RWCP.modelJEITA_Genpaku_ChaSen_IPAdic.model はレガシー・互換用モデルで、 従来どおりに学習(または取得)しています – 通常の AdaBoost 手順は モデルの学習を参照してください。 japanese.modelchinese.modelkorean.model は binary-perceptron 畳み込み手順 (issue #165)で再学習しています。エンジンの変更は不要ですが、通常の litsea train に加えて数ステップが必要です:

# 1. プレーンな境界特徴量を抽出(従来と同じステップ)。--tag-free を付けると
#    16 個のタグ依存テンプレートを除外して pointwise モデルを学習できる
#    (korean.model で使用。次節を参照)。
litsea extract -l <language> [韓国語なら --format tsv] [--tag-free] <corpus> <features.txt>

# 2. 境界ラベル 1/-1 を B/O にリマップする。これは見た目の問題ではなく
#    正しさのために必須: perceptron 自身のタイブレーク(クラスインデックスが
#    小さい方が勝つ)を、AdaBoost の「score >= 0.0 は境界を優先する」という
#    規約と一致させるためのもの。"1"/"-1" のまま学習すると、タイの解決方向が
#    黙って逆転してしまう。
sed -i 's/^1\t/B\t/; s/^-1\t/O\t/' <features.txt>

# 3. 2 クラスの Averaged Perceptron として学習する。--perceptron は
#    汎用のトレーナー(PerceptronTrainer はラベルを不透明な文字列として
#    扱う)。
litsea train --perceptron --num-epochs <N> <features.txt> <perceptron.model>

# 4. プレーンな AdaBoost モデル形式へ畳み込む(無損失 -- 導出はスクリプトの
#    docstring を参照)。
scripts/collapse_binary_perceptron.py <perceptron.model> <collapsed.model>

# 5. 任意: 特徴量数の増加が `cargo bench -- external_corpus` のスループットを
#    許容範囲を超えて悪化させる場合、上位 N 特徴量に剪定し held-out 品質と
#    速度の両方を再確認する。
scripts/prune_adaboost_model.py <collapsed.model> <pruned.model> <n>

エポック数と剪定閾値は固定値ではなく言語ごとのチューニング項目です – 上記の同梱モデルを選んだのと同じように、エポックスイープと品質・スループットの トレードオフスイープから決めてください(スイープの全データは issue を参照)。 大まかな傾向として、品質は少数のエポックを大きく超えて向上し続け、最終的には プラトーに達するか(日本語は約 50 エポックを超えると軽度のオーバーフィットが 見られます)、単一の「正しい」エポック数があるわけではありません。剪定による 品質劣化は言語固有の崖に達するまで緩やかに進む傾向があるため、数値を推測するの ではなく、cargo bench のスループットが回復し始める付近の剪定レベルを いくつか試してください。

タグなし(pointwise)モデル

境界特徴量テンプレートのうち 16 個(UP*/BP*/UQ*/BQ*/TQ*)は、 モデル自身が直前 1〜3 文字で下した境界判定の結果を参照します。これは 各判定を直前の判定に連鎖させるため、segment() のスコアリングを厳密に 逐次的なパスへ縛り付けます。これらを使わずに学習したモデル (litsea extract --tag-free)は pointwise – 各位置が入力テキスト のみに依存する – になり、segment() はモデルのロード時にこれを検出して 逐次パスを丸ごとスキップします(issue #183)。

タグ特徴量の価値は言語によって大きく異なります(すべて UD GSD テスト 分割上の、収束確認済みエポックスイープによる計測値。issue #183):

言語単語 F1(タグあり)単語 F1(タグなし)スループット変化
韓国語99.90%99.91%高速化(逐次パスをスキップ)
英語98.71%98.68%*高速化(逐次パスをスキップ)
日本語96.70%96.33%実測 end-to-end 約 +45〜50%
中国語90.69%90.18%実測 end-to-end 約 +12%

* 英語の dev split での比較(タグあり 98.71% vs タグなし 98.68%、差は 0.03pt)はどちらを選んでも大差ない水準であり、同梱モデルは韓国語と同じ スループット上の理由からタグなしで出荷しています。上記の english.model の held-out テスト分割の数値(98.31%)はスイープの最後に一度だけ計測した ものであり、この dev split の対比とは直接比較できません。

語節間の空白シグナルがある韓国語ではタグ特徴量は何も寄与しないため、 korean.model はタグなしで同梱しています(サイズも約 22% 減)。英語も 同じ理由(空白シグナルが支配的であるため)でほぼ同様の状況にあります。 日本語・中国語ではまだ単語 F1 で 0.37〜0.51pt の価値があるため、 同梱モデルはタグ特徴量を保持しています – 品質がデフォルトです。 速度を優先するワークロードでは、上記の手順に extract ステップの --tag-free を加えて再学習してください。スループットの数値は本 プロジェクトの開発マシンでベンチマークの ペア計測方法論により測定したものなので、持ち越せるのは絶対値ではなく 比率と考えてください。

二段構成の品詞推定モデル

二段構成アーキテクチャ(issue #147)は、 文字位置ごとに全 UPOS クラスを採点する代わりに、二値の境界分類器で分割し、 確定した各単語を候補タグ語彙表と単語単位のタガーでタグ付けします。

held-out 行は UD GSD/EWT テスト分割に対して litsea evaluate --pos で測定した 単語 / タグ付き単語 F1 です(モデルの評価を 参照)。日本語と中国語は空白を使わずに表記されるため、コーパスと実際の入力は 同一のものです。韓国語と英語はスペース区切りであり、空白保持コーパス (--format tsv、issue #198)で学習・評価しているため、以下の数値も同様に 実運用の数値です。 「stage-2 特徴量セット」は単語単位テンプレートの選択 (fastbalancedfull特徴量の抽出を参照) で、二段構成タグ付けの 実測トレードオフから言語ごとに同梱モデル用に選定しています。スループットは ベンチマークページと同じコーパスに対する cargo bench -- external_corpus によるもので、本プロジェクトの開発機で 計測しています(専用のアイドルハードウェアではありません – そのページの方法論の注記を参照)。

エポック数についての注記: 二段構成の同梱にあたって行ったエポックスイープ (10〜150 エポック)では、stage 1 の分割品質は特に 10 エポックを大きく 超えて向上し続け、50 エポック付近でプラトーに達することが判明しました – 以下の同梱二段構成モデルは、このスイープから得た 50 エポックを使用して います。再学習の際、一発の低エポック実行ではこのアーキテクチャの到達可能な 品質を過小評価することになります (方法論についての注記を参照)。

japanese_pos.model

プロパティ
言語日本語
学習コーパスUD Japanese-GSD(7,050 文)
エポック数50
stage-2 特徴量セットfast
単語 F1(held-out)96.78%
タグ付き単語 F1(held-out)92.95%
スループット4.38M chars/s
ファイルサイズ約 5.4 MB

chinese_pos.model

プロパティ
言語中国語(簡体字・繁体字)
学習コーパスUD Chinese-GSD(3,997 文)
エポック数50
stage-2 特徴量セットbalanced
単語 F1(held-out)90.82%
タグ付き単語 F1(held-out)82.29%
スループット3.38M chars/s
ファイルサイズ約 8.0 MB

korean_pos.model

プロパティ
言語韓国語
学習コーパスUD Korean-GSD(4,400 文、空白保持 TSV プロトコル)
エポック数20
stage-2 特徴量セットfull
単語 F1(held-out)99.88%
タグ付き単語 F1(held-out)93.95%
スループット4.21M chars/s
ファイルサイズ約 4.0 MB

韓国語のスループットのプロファイルは語彙表に起因します: held-out テキストの 34.5% が未知語(学習時に未出現の表層)で、未知語は常に stage 2 の全クラスフォールバックを払うことになり、安価な dominance スキップや候補マスクの経路を使えません。そのため日本語・中国語より 多くの割合の韓国語の単語が stage 2 のフルコストを負担します。

韓国語のプロトコルについての注記: korean_pos.model は空白保持 TSV コーパス(issue #198)で学習しており、これは korean.model が使うのと 同じプロトコルです。そのため単語 F1(99.88%)は korean.model の 99.91% と直接比較でき、二段構成の stage 1 分類器はいまや専用の分割モデルと ほぼ同等に達しています。issue #198 までは空白非保持の word/POS コーパスで学習しており、実際のスペース付き入力に対するスコアは 94.01% でした。学習プロトコルの切り替えにより 単語 F1 +5.9 ポイント、 タグ付き単語 F1 +10.8 ポイント向上しています。再学習に伴い、stage-2 特徴量セットは balanced から full へ、エポック数は 50 から 20 へ 変更しました。いずれも新しいコーパス上の dev split スイープから 選び直したものです。

english_pos.model

プロパティ
言語英語
学習コーパスUD English-EWT(12,544 文、空白保持 TSV プロトコル)
エポック数50
stage-2 特徴量セットfull
単語 F1(held-out)98.30%
タグ付き単語 F1(held-out)90.55%
スループット7.32M chars/s
ファイルサイズ約 3.1 MB

英語のプロトコルについての注記: english_pos.model は空白保持 TSV コーパス(issue #198)で学習しているため、単語 F1(98.30%)は english.model の 98.31% と直接比較でき、二段構成の stage 1 分類器は いまや専用の分割モデルとほぼ同等に達しています。

これはモデルカタログの中で最大の品質変化です。issue #198 までは、 二段構成パイプラインはコーパスを空白なしで連結したテキストで学習して おり、英語のテキストが実際に含んでいる空白を捨てていました。その結果、 モデルのスコアは空白非保持プロトコルで 70.33%、実際のスペース付き 入力で 77.55% でした。入力が本来持っている空白どおりに学習すること で、単語 F1 +20.8 ポイント、タグ付き単語 F1 +20.7 ポイント向上し、 推論も約 3.6 倍高速になりました(2.05M -> 7.32M chars/s): 空白が候補 1 個の語彙表エントリを持つようになったため、トークンの約 43% が stage 2 の分類器ではなく packed モデルの固定タグ経路でタグ付けされます。

この変更は 2 つの異なる学習と推論のミスマッチを同時に解消しました。 stage 1 は、英語のほぼすべての語境界を示す空白文字を一度も見て いませんでした。stage 2 の文脈特徴量(L*/R*/cl*/cr*)も影響を 受けており、推論時に単語の隣は通常空白であるのに対し、空白非保持の 学習では次の単語の文字になっていました。どちらも現在は segment --pos が実際に計算するものと一致しています。

使用方法

echo "これはテストです。" | litsea segment --pos -l japanese models/japanese_pos.model

出力:

これ/PRON は/ADP テスト/NOUN です/AUX 。/PUNCT

モデルの選択

  • 日本語には、最高精度を求める場合は japanese.model を、オリジナルの TinySegmenter との互換性を重視する場合は RWCP.model を使用
  • 中国語には chinese.model を使用
  • 韓国語には korean.model を使用
  • 英語には english.model を使用
  • 品詞推定には二段構成モデル(japanese_pos.modelchinese_pos.modelkorean_pos.modelenglish_pos.model)を segment --pos / evaluate --pos とともに使用してください (アーキテクチャと実測値は 二段構成タグ付けを参照。英語については 特に、english_pos.model の分割品質に頼る前に上記のプロトコルについての 注記を必ず読んでください)。
  • ドメイン固有の用途には、独自モデルの学習または既存モデルの再学習を検討

サンプルデータ

resources/ ディレクトリには以下も含まれています:

  • bocchan.txt – 坊っちゃん(夏目漱石)、約 307 KB。segment_long_japanese ベンチマークと差分テストに使用。
  • wagahaiwa_nekodearu.txt – 吾輩は猫である(夏目漱石)、約 1.1 MB、青空文庫。
  • mujeong.txt – 무정(李光洙、1917)、約 786 KB、ko.wikisource。
  • rulin_waishi.txt – 儒林外史(呉敬梓)、約 985 KB、zh.wikisource。
  • pride_and_prejudice.txt – Pride and Prejudice(Jane Austen)、約 688 KB、Project Gutenberg eBook #1342(ヘッダー・フッター・挿絵キャプションを除去し、1 行 1 段落に整形)。

wagahaiwa_nekodearu.txtmujeong.txtrulin_waishi.txt の 3 つは外部の tokenizer-speed-bench のコーパスとバイト同一で、external_corpus ベンチマークグループが使用します (ベンチマークを参照)。pride_and_prejudice.txt は同じベンチマークグループの英語のケースに使われますが、この外部ハーネス側 にはまだ対応するコーパスがありません。いずれもパブリックドメインです。