予測パイプライン
本章では、Segmenter::segment() が入力テキストを処理する手順をステップごとに解説します。
例: “これはテストです。” の分割
ステップ 1: パディングで配列を初期化
chars: ["B3", "B2", "B1"]
types: ["O", "O", "O" ]
tags: ["U", "U", "U", "U"]
tags 配列には “U” が 1 つ余分に追加されます。これは tags[3] が最初の実際の文字のタグを表し、先行する境界判定がないため “Unknown” に設定されるためです。
ステップ 2: 入力文字のスキャン
入力の各文字について、言語固有のパターンを使用して種別を決定し、配列に追加します:
chars: ["B3","B2","B1", "こ","れ","は","テ","ス","ト","で","す","。"]
types: ["O", "O", "O", "I", "I", "I", "K", "K", "K", "I", "I", "P"]
ステップ 3: 終了センチネルの追加
chars: [..., "。", "E1", "E2", "E3"]
types: [..., "P", "O", "O", "O" ]
ステップ 4: 反復と予測
位置 i を 4 から len(chars) - 3 まで繰り返します:
i=4 (れ): Extract features → predict → label=-1 (O) → word="これ"
i=5 (は): Extract features → predict → label=+1 (B) → push "これ", word="は"
i=6 (テ): Extract features → predict → label=+1 (B) → push "は", word="テ"
i=7 (ス): Extract features → predict → label=-1 (O) → word="テス"
i=8 (ト): Extract features → predict → label=-1 (O) → word="テスト"
i=9 (で): Extract features → predict → label=+1 (B) → push "テスト", word="で"
i=10(す): Extract features → predict → label=-1 (O) → word="です"
i=11(。): Extract features → predict → label=+1 (B) → push "です", word="。"
ステップ 5: 最後の単語をプッシュ
残りの単語 “。” を結果に追加します。
結果
["これ", "は", "テスト", "です", "。"]
各位置での予測の仕組み
各位置 i で、セグメンタは以下を実行します:
-
特徴量の抽出 –
get_attributes(i, tags, chars, types)を呼び出し、38-42 個の特徴量からなるHashSet<String>を構築 -
スコアの計算 – AdaBoost 学習器がマッチするすべての特徴量のモデル重みとバイアスを合計:
score = bias + sum(model[feature] for feature in attributes) -
判定 –
score >= 0の場合、その文字は新しい単語を開始(境界)、そうでなければ現在の単語を継続 -
タグの更新 – tags 配列に “B” または “O” をプッシュし、後続の位置での特徴量抽出に影響を与える
学習と予測の比較
| 観点 | 学習(process_corpus) | 予測(segment) |
|---|---|---|
| タグの情報源 | アノテーション済みコーパスから事前計算 | モデルにより動的に生成 |
| 最初のタグ | “U”(位置 3 の “B” を上書き) | “U”(先行する判定なし) |
| ラベル | コーパスから既知(+1 または -1) | AdaBoost による予測 |
| 特徴量 | コールバックを通じてファイルに書き出し | predict() に直接渡される |
学習時は、タグが正解のコーパス分割から導出されるため、モデルは正しい境界判定から学習します。予測時は、タグがその場で生成されるため、各判定は過去のすべての予測に依存します – これは左から右への貪欲法(Left-to-right Greedy)アプローチです。
パフォーマンス特性
分割アルゴリズムは入力長に対して線形です:
- 各文字位置を 1 回ずつ訪問: O(n)
- 各位置での特徴量抽出: O(1)(固定数の特徴量)
- 各位置での予測: O(f)、f はアクティブな特徴量の数(約 38-42)
- 合計: O(n * f)、実質的に O(n)