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 の segment_with_pos()二段構成(two-stage)モデル--posSegmenter::with_two_stage_learner、issue #147)に 支えられています。モデルファイルの litsea-two-stage v1 ヘッダがこの形式を 識別し(モデルファイル形式を参照)、 メソッドは Vec<(String, Upos)> の単語/タグのペアを返します。

仕組み

二段構成タグ付けは、文字レベルで POS クラスを採点することは一切ありません:

  1. stage 1 は二値の境界分類器で分割します – segment() が使うのと 構造的に同じスカラー重みの AdaBoost 形式なので、同じ速度で動きます。
  2. stage 2 は stage 1 が確定した単語ごとに、学習コーパスから構築した 候補タグ語彙表と単語単位の分類器でタグ付けします (モデルファイル形式を参照):
    • 学習時に観測されたタグが 1 個しかない、あるいは最頻タグが学習時の 出現の dominance 割合以上を占める表層は、分類器を一切呼ばずに タグ付けされます。
    • 曖昧な既知表層は、観測された候補タグのみ(マスク付き argmax)に 絞って採点されます(全 18 クラスではありません)。
    • 未知の表層は全クラス argmax にフォールバックします。

単語は平均して 1 文字より多くの文字を含み、大半の単語は曖昧でないか 分類器そのものをスキップするため、stage 2 の総コストは文字単位の多クラス 採点のごく一部で済みます。これが POS パスを通常の分割とほぼ同じ速さにして いる理由です: 歴史的な joint アーキテクチャ(二段構成への一本化に伴い削除) は各文字位置ごとに約 18 個の UPOS クラス全てを採点しており、同じコーパスで 1.8〜2.8 倍遅く動作していました。

方法論についての注記: 十分な学習エポック数を使う

二段構成の展開時に行ったエポックスイープ(10〜150 エポック)により、 モデル品質は旧来のモデルが学習されていた 10 エポック慣習を大きく超えて 向上し続け、UD GSD 学習セットでは 50 エポック前後でプラトーに達することが 分かりました。特に stage 1 の境界のみの特徴量は、よりリッチな文字ごとの 特徴量セットに比べて、同じコーパスで収束するのにより多くのエポックを 必要とします。同梱の二段構成モデルは 50 エポックを使用しています。 再学習の際、一発の低エポック実行ではこのアーキテクチャの到達可能な品質を 過小評価することになります。

実測の品質とスループット

held-out の数値は UD GSD/EWT test split に対する litsea evaluate --pos事前学習済みモデルを参照)です。スループットは 本プロジェクトの開発機での cargo bench -- external_corpus で、 専用のアイドルハードウェアではありません。実行間の振れ幅は無視できない 大きさです – 方法論とその限界については ベンチマークを参照してください。

言語Word F1Tagged F1スループット
日本語96.78%92.95%4.38M chars/s
中国語90.82%82.29%3.38M chars/s
韓国語99.88%93.95%4.21M chars/s
英語98.30%90.55%7.32M chars/s

留意すべき 2 つの観察:

  • 候補タグ制限は実在する品質レバーです。 既知単語の候補を実際に 観測されたものに制限することで、分類器がありえないタグを選ぶ機会の 大半が排除され、単語あたりの特徴量セットが小さいことによる不利を 補います。
  • スループットは語彙表のカバレッジによって変わります。 韓国語は held-out の未知語率が高いため、安価な dominance スキップや 候補マスクの経路ではなく、stage 2 の全クラスフォールバックを払う 単語の割合が大きくなります。英語は issue #198 以降その対極にあります: トークンの約 43% が空白であり、そのすべてが候補 1 個の語彙表ヒットと なって分類器を完全にスキップします。

ここで最も効くのはコーパスのプロトコル(issue #198)

stage 1 の分類器は、学習に使ったテキスト以上に良くはなりません。 issue #198 までは、二段構成の extractor は空白区切りの word/POS コーパスを読み込み、各文を単語表層の区切りなしの連結として 復元していました – 実際の文章に空白がない日本語・中国語では正しい 処理ですが、韓国語・英語では入力が持つ最も強い境界シグナルを 捨ててしまっていました。

代わりに空白保持コーパス(extract --pos --format tsv)で学習することで、 両言語とも専用の分割モデルと同水準に到達しました:

言語Word F1(変更前)Word F1(変更後)Tagged F1(変更前)Tagged F1(変更後)
韓国語94.01%99.88%83.20%93.95%
英語77.55%98.30%69.89%90.55%

(「変更前」の列は issue #196 の実運用/スペース付きの測定値であり、 空白非保持プロトコルの数値ではありません。したがってユーザーが実際に 得ていたものどうしの公平な比較になっています。)韓国語はいま korean.model の 99.91% との差が 0.03 ポイント、英語は english.model の 98.31% との差が 0.01 ポイントです。

空白非保持コーパスは2 つの異なる学習と推論のミスマッチを 引き起こしていましたが、どちらも解消されました:

  1. stage 1 は、これらの言語でほとんどの語境界を示す空白文字を 一度も見ていませんでした。
  2. stage 2 も、より分かりにくい形で影響を受けていました: その文脈 特徴量(L1L3 / R1R3cl1cl3 / cr1cr3)は 周囲の文字を参照しますが、推論時に単語の隣は通常空白であるのに対し、 空白非保持の学習では次の単語の文字になっていました。空白はトークンの 約 43% を占めるため、事実上すべての単語が影響を受けていました。

空白トークンには stage 2 の学習行を与えていません(退化した X クラス 1 個だけで学習行の約 43% を占めてしまうため)が、語彙表エントリは与えて います。これにより空白は候補 1 個となり、分類器を呼ばずに固定タグ経路で X としてタグ付けされます – 決定的であり、従来のモデルがフォールバック していた全クラス argmax の推測よりも安価です。

日本語・中国語はこの一連の変更の影響を受けません。これらの言語のテキスト には空白がなく、空白区切りコーパスは既に実際の入力と一致していたためです。

stage-2 特徴量セットの選び方

stage 2 の単語単位タガーは 3 種類の特徴量セット(litsea extract --pos--stage2-features特徴量の抽出を参照)で 抽出でき、タグ付け品質とスループットをトレードオフできます。分割品質は 影響を受けません – 分割は stage 1 だけで決まります。以下の数値は 同梱モデルと同じ 50 エポックでの値です。

特徴量セット中国語 Tagged F1韓国語 Tagged F1英語 Tagged F1
fast(既定)81.33%90.62%88.68%
balanced82.29%92.95%88.66%
full82.96%93.33%90.43%

(韓国語と英語は issue #198 に伴って空白保持コーパスで再スイープしており、 この 2 列はそのスイープの dev split の数値です。中国語の列はそれ以前の ものです。その結果、韓国語の勝者は balanced から full に変わりました。)

日本語では fast だけで Tagged F1 92.95% に到達するため、同梱の japanese_pos.model はこれを使用しています。 中国語では balancedfull の伸びの大半(82.29% vs 82.96%)を 明確に良いスループットで得られるため、chinese_pos.modelfull ではなく balanced を使用しています。空白保持コーパスでの 韓国語・英語では full が明確な勝者であるため(韓国語は 93.33% vs balanced の 92.95%、英語は 90.43% vs 他の 2 つの約 88.7%)、 korean_pos.modelenglish_pos.model はどちらも full を 使用しています。別の特徴量セットで再学習するには extract --pos --stage2-features <set> + train --pos を再実行するだけで、 パイプラインの他の部分を変更する必要はありません。