Files
VRCT/src-python/docs/details/transliteration_context_rules.md
2025-10-14 07:28:03 +09:00

397 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# transliteration_context_rules.py - 文脈的転写ルールエンジン
## 概要
トークン化された結果に対して文脈依存の転写ルールを適用するコンパクトなルールエンジンです。隣接するトークンの情報に基づいて読み(かな)を動的に修正し、より自然で正確な転写を実現します。
## 主要機能
### 文脈依存転写
- 隣接トークン情報を利用した読み修正
- 優先度ベースのルール適用順序
- 正規表現・完全一致の両方に対応
### ルールエンジン
- 埋め込み型ルール定義外部JSONファイル不要
- 前方・後方の隣接トークン検査対応
- インプレース変更による効率的処理
### 動的読み変更
- 文脈に応じたかな読みの書き換え
- ひらがな・ヘボン式の自動クリア
- 呼び出し元での再計算トリガー
## ルール定義構造
### DEFAULT_RULES
```python
DEFAULT_RULES = {
"rules": [
{
"name": "nan_next_tdna", # ルール名
"target": "", # 対象文字
"match_mode": "equals", # マッチモード
"direction": "next", # 検査方向
"kana_set": ["", "", ""...], # 条件文字セット
"on_true": {"kana": "ナン"}, # 条件真時のアクション
"on_false": {"kana": "ナニ"} # 条件偽時のアクション
}
]
}
```
### ルール要素
#### 基本設定
- **name**: ルールの識別名
- **target**: 適用対象となる文字・文字列
- **priority**: 適用優先度(高い順に処理)
- **match_mode**: マッチングモード("equals"/"regex"
#### 条件設定
- **direction**: 隣接トークン検査方向("next"/"prev"
- **kana_set**: 条件判定用の文字セット
- **pattern**: 正規表現パターンregex時
#### アクション設定
- **on_true**: 条件成立時のアクション
- **on_false**: 条件不成立時のアクション
- **kana**: 設定する新しいかな読み
## 主要関数
### apply_context_rules
```python
def apply_context_rules(results: List[Dict[str, Any]], use_macron: bool = False) -> List[Dict[str, Any]]
```
文脈ルールをトークンリストに適用
#### パラメータ
- **results**: `Transliterator.split_kanji_okurigana`で生成されたトークン辞書のリスト
- **use_macron**: 互換性のためのパラメータ(ルール処理では未使用)
#### 戻り値
- **List[Dict[str, Any]]**: 修正されたトークンリスト(インプレース変更も実施)
#### 必須キー
各トークン辞書は以下のキーを含む必要があります:
- **orig**: 元の文字・文字列
- **kana**: かな読み
- **hira**: ひらがな表記
- **hepburn**: ヘボン式ローマ字
## 使用方法
### 基本的な文脈ルール適用
```python
from models.transliteration.transliteration_context_rules import apply_context_rules
# トークン化された結果(例)
results = [
{"orig": "", "kana": "ナニ", "hira": "なに", "hepburn": "nani"},
{"orig": "", "kana": "", "hira": "", "hepburn": "do"},
{"orig": "", "kana": "", "hira": "", "hepburn": "mo"}
]
# 文脈ルールの適用
modified_results = apply_context_rules(results)
# 結果確認
for token in modified_results:
print(f"{token['orig']}: {token['kana']} -> {token['hira']} ({token['hepburn']})")
# 期待される出力(「何度」の場合):
# 何: ナン -> (再計算必要) (再計算必要)
# 度: ド -> ど (do)
# も: モ -> も (mo)
```
### カスタムルールでの処理
```python
# 独自ルール定義の例
custom_rules = {
"rules": [
{
"name": "custom_rule_example",
"target": "",
"match_mode": "equals",
"direction": "next",
"kana_set": ["", "", "", "", ""],
"priority": 100,
"on_true": {"kana": "イマ"},
"on_false": {"kana": "コン"}
}
]
}
# 注意:現在の実装では DEFAULT_RULES が固定使用されています
# カスタムルールを使用するには関数の拡張が必要です
```
### 正規表現マッチングの例
```python
# 正規表現ルールの定義例
regex_rule = {
"name": "kanji_pattern_rule",
"match_mode": "regex",
"pattern": r"^[一-龯]$", # 任意の漢字1文字
"direction": "next",
"kana_set": ["", "", "", "", ""],
"priority": 50,
"on_true": {"kana": "特殊読み"},
"on_false": {"kana": "通常読み"}
}
```
### 転写パイプラインでの統合
```python
def complete_transliteration_pipeline(text):
"""完全な転写パイプライン"""
# 1. 初期分割・転写
transliterator = Transliterator()
tokens = transliterator.split_kanji_okurigana(text)
# 2. 文脈ルール適用
tokens = apply_context_rules(tokens)
# 3. 修正されたトークンの再計算
for token in tokens:
if token.get("kana") and not token.get("hira"):
# ひらがな・ヘボン式の再計算
token["hira"] = katakana_to_hiragana(token["kana"])
token["hepburn"] = hiragana_to_hepburn(token["hira"])
return tokens
# 使用例
text = "何度でも挑戦する"
result = complete_transliteration_pipeline(text)
for token in result:
print(f"{token['orig']} -> {token['kana']} -> {token['hira']} -> {token['hepburn']}")
```
## ルール処理ロジック
### 処理フロー
1. **ルール準備**
- 優先度の降順でソート
- 正規表現の事前コンパイル
2. **トークン走査**
- 各トークンに対してルールを順次適用
- 空の`orig`を持つトークンはスキップ
3. **マッチング判定**
- `equals`: 完全一致判定
- `regex`: 正規表現マッチ判定
4. **隣接トークン検査**
- `direction`に基づく隣接トークン特定
- 空のトークンをスキップして有効トークンを検索
5. **条件評価**
- 隣接トークンの`kana`の先頭文字チェック
- `kana_set`との一致判定
6. **アクション実行**
- 条件に応じて`on_true`/`on_false`を選択
- `kana`の書き換えと`hira`/`hepburn`のクリア
### アルゴリズム詳細
```python
def process_token_with_rules(token_index, tokens, rules):
"""単一トークンのルール処理アルゴリズム"""
token = tokens[token_index]
orig = token.get("orig", "")
# 空トークンはスキップ
if not orig:
return
for rule in rules: # 優先度順
# マッチング判定
if not matches_rule(orig, rule):
continue
# 隣接トークン検索
neighbor = find_neighbor_token(token_index, tokens, rule["direction"])
if neighbor:
# 条件評価
condition = evaluate_condition(neighbor, rule["kana_set"])
# アクション実行
action = rule["on_true"] if condition else rule["on_false"]
apply_action(token, action)
# 最初にマッチしたルールで処理終了
break
def find_neighbor_token(current_index, tokens, direction):
"""隣接する有効トークンを検索"""
if direction == "next":
for i in range(current_index + 1, len(tokens)):
if tokens[i].get("orig"):
return tokens[i]
elif direction == "prev":
for i in range(current_index - 1, -1, -1):
if tokens[i].get("orig"):
return tokens[i]
return None
```
## 具体的なルール例
### 「何」の読み分けルール
```python
{
"name": "nan_next_tdna",
"target": "",
"match_mode": "equals",
"direction": "next",
"kana_set": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"on_true": {"kana": "ナン"},
"on_false": {"kana": "ナニ"}
}
```
#### 動作例
```python
# 「何度」の場合
tokens = [
{"orig": "", "kana": "ナニ"}, # 初期状態
{"orig": "", "kana": ""} # 次のトークン
]
# ルール適用後
tokens = [
{"orig": "", "kana": "ナン"}, # 「ド」が kana_set に含まれるため "ナン" に変更
{"orig": "", "kana": ""}
]
# 「何回」の場合
tokens = [
{"orig": "", "kana": "ナニ"}, # 初期状態
{"orig": "", "kana": "カイ"} # 次のトークン
]
# ルール適用後
tokens = [
{"orig": "", "kana": "ナニ"}, # 「カイ」が kana_set に含まれないため "ナニ" のまま
{"orig": "", "kana": "カイ"}
]
```
## エラーハンドリング
### 正規表現コンパイルエラー
```python
# 不正な正規表現の安全な処理
for rule in rules:
if rule.get("match_mode") == "regex" and rule.get("pattern"):
try:
rule["_re"] = re.compile(rule["pattern"])
except Exception as e:
print(f"正規表現コンパイルエラー: {rule['pattern']} - {e}")
rule["_re"] = None # 無効化
```
### 不正なトークン構造
```python
# 必須キーの存在確認
def validate_token(token):
"""トークンの妥当性検証"""
required_keys = ["orig", "kana", "hira", "hepburn"]
for key in required_keys:
if key not in token:
print(f"警告: トークンに必須キー '{key}' が不足")
token[key] = "" # デフォルト値を設定
return token
```
## パフォーマンス考慮事項
### 効率的な処理
- インプレース変更によるメモリ効率
- 優先度ソートによる早期終了
- 正規表現の事前コンパイル
### スケーラビリティ
- 大量トークンでの線形処理時間
- ルール数の増加に対する適切な対応
- キャッシュ機能の追加可能性
## 拡張可能性
### ルール形式の拡張
```python
# より複雑なルール例(将来的な拡張)
complex_rule = {
"name": "multi_condition_rule",
"target": "",
"conditions": [
{"direction": "prev", "kana_set": ["", ""]},
{"direction": "next", "kana_set": ["", ""]}
],
"operator": "AND", # or "OR"
"actions": {
"all_true": {"kana": "ゴン"},
"any_true": {"kana": "ゲン"},
"all_false": {"kana": ""}
}
}
```
### 動的ルール追加
```python
def add_runtime_rule(new_rule):
"""実行時ルール追加(拡張版)"""
# ルールの検証
if validate_rule_format(new_rule):
DEFAULT_RULES["rules"].append(new_rule)
return True
return False
```
## 依存関係
### 必須依存関係
- `typing`: 型ヒント
- `re`: 正規表現処理
### 関連モジュール
- `transliteration_transliterator.py`: メイン転写クラス
- `transliteration_kana_to_hepburn.py`: かな→ヘボン式変換
## 注意事項
- ルール適用後は`hira``hepburn`が空文字列になるため、呼び出し元での再計算が必要
- 現在のルールは日本語に特化している
- ルール適用順序は優先度に依存するため、適切な設定が重要
- 正規表現ルールはパフォーマンスに影響する可能性がある
## 将来の改善点
- 外部ルールファイルの読み込み対応
- より複雑な条件式のサポート
- ルール適用ログ・デバッグ機能
- 言語別ルールセットの対応
- パフォーマンス最適化とキャッシュ機能