Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ hasami は、MeCab などの外部の解析エンジンを使わずに Rust で
- **外部エンジンに依存しない**: MeCab や Sudachi を呼ばず、辞書の構築から解析までを hasami だけで行います
- **ラティスと Viterbi**: 辞書の語と未知語の候補をラティスに並べ、接続コストと単語コストの和が最小になる分け方を選びます
- **並列解析**: `hasami tokenize` は標準入力の行を CPU の数だけ並列に解析します。1 スレッドの API と Python バインディングの実測は [ベンチマーク](#ベンチマーク) にあります
- **読みと発音**: トークンごとに読みと発音を返します。文脈で読みが変わる語(「他」「数」など)と、1〜2 文字の英字の略語(AI・PC など)は、解析の後で読みを直します
- **読みと発音**: トークンごとに読みと発音を返します。文脈で読みが変わる語(「他」「数」など)、数詞と助数詞の音便(「三本」「一回」「三百」など)、1〜2 文字の英字の略語(AI・PC など)は、解析の後で読みを直します
- **MeCab 形式の辞書から作る**: MeCab 形式の CSV と matrix.def・char.def・unk.def から辞書を作ります。配布辞書は IPAdic、IPAdic + NEologd、IPAdic + NEologd + SudachiDict の 3 つで、SudachiDict は IPAdic の品詞体系に写して足します。UniDic は手元でビルドできます
- **辞書のマージと修復**: 既存の辞書に MeCab 形式の CSV を足せます。`hasami repair` は、誤読や誤った品詞の元になるエントリを直すか取り除きます
- **すぐに読み込める辞書**: 辞書は mmap でそのまま参照する形式(.hsd v5)です。読み込むときはヘッダと小さな表だけを検査し、本体は解析で触れたページだけを読みます
Expand Down
19 changes: 19 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,23 @@ hasami は入力を文字単位の double-array trie で辞書引きし、未知
`100km`・`3GB`・`5V` は単位読み、`100 km`・`3 GB`・`5 V` はケーエム・ジービー・ブイの綴り読みになる。
既知語で 3 文字以上の英字にカタカナの読みがある場合は、従来どおり辞書の読みを優先する(`NASA` → ナサ)。

数詞と隣接する助数詞の読み・発音には音便を反映する。本・杯・匹、回・個、分と、位の数詞の百・千が対象で、
「三本」はサン / ボン、「一回」はイッ / カイ、「三百本」はサン / ビャッ / ポンになる。
時・時間の四・七・九もヨ・シチ・クに直す。IPAdic 体系の数詞・助数詞を対象に、数詞の末尾と助数詞の読みを表で照合する。
固有名詞や対応表にない読み、空白・タブ・改行で離れた語は補正しない。
複数字の漢数字も字ごとの標準読みと内部の百・千の音便を確認し、「十一」がテンイチなら補正しない。
IPAdic で未知の普通名詞になる「ぷん」は、仮名から補完したプンのときだけ例外として扱う。

人・日の和語読みは数詞列全体を確認する。一人・二人はヒト / リ、フタ / リ、二日〜十日と十四日・二十四日は
フツ / カ、ミッ / カなどにする。八日の読みはヨウ / カ、発音はヨー / カで、各トークンに空でない読みを残す。
十二人・十三日には和語読みを適用しない。和語読みの対象外の日の七・九はシチ・クにし、十七日はジューシチニチになる。
数詞列全体が標準の読み・発音のときだけ和語読みにし、十がテンなどの別読みなら変更しない。
一日のツイタチは日付と期間を区別できないので補正せず、
二十日のハツカも現在のトークンに分配しない。小数点(点・`.`・`.`)以下には音便・和語読みを適用しない。
一語の「十分」の直後に「前」「後」が隣接する場合はジュップンに直すが、「十分に」「十分な」は変えない。
補正は読み・発音だけを変更し、表層形・品詞・原形・位置・コスト・辞書由来の情報を保つ。
複数桁の ASCII 数字を位取りで読む処理は、この数詞と助数詞の補正には含まれない。
対応表は [Open JTalk 1.11 の数詞規則](https://github.com/r9y9/open_jtalk/blob/1.11/src/njd_set_digit/njd_set_digit_rule_utf_8.h)
を参考に、トークンの読みを補正する独立した処理として実装している。

補助平面の CJK 拡張漢字・互換漢字も、char.def の明示指定がなければ漢字として未知語候補を作る。
31 changes: 1 addition & 30 deletions src/lattice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,19 +360,6 @@ fn apply_contextual_readings(tokens: &mut [Token]) {
continue;
}
}
// TTS の「10分」→「十ぷん」では末尾の十を促音化する。
// 「十分(ジュウブン)」や、十年・十番など別の助数詞には適用しない。
if &*tokens[i].surface == "十"
&& tokens[i].pos.starts_with("名詞,数")
&& tokens
.get(i + 1)
.is_some_and(|t| &*t.surface == "ぷん" && t.pos.starts_with("名詞,接尾,助数詞"))
{
let reading: Arc<str> = Arc::from("ジュッ");
tokens[i].reading = Arc::clone(&reading);
tokens[i].pronunciation = reading;
continue;
}
if DECIMAL_COUNTER_OVERRIDES
.iter()
.any(|&(surface, _)| &*tokens[i].surface == surface)
Expand Down Expand Up @@ -421,6 +408,7 @@ fn apply_contextual_readings(tokens: &mut [Token]) {
tokens[i].pronunciation = kana;
}
}
crate::numeric::apply_counter_readings(tokens);
}

/// 仮名のみからなる表層形をカタカナの読みに変換する。
Expand Down Expand Up @@ -1975,23 +1963,6 @@ mod tests {
}
}

#[test]
fn test_ten_minutes_euphony_requires_numeric_ten_and_minute_suffix() {
for (ten_pos, counter, counter_pos, expected) in [
("名詞,数,*,*", "ぷん", "名詞,接尾,助数詞,*", "ジュッ"),
("名詞,数,*,*", "ねん", "名詞,接尾,助数詞,*", "ジュウ"),
("名詞,一般,*,*", "ぷん", "名詞,接尾,助数詞,*", "ジュウ"),
("名詞,数,*,*", "ぷん", "名詞,固有名詞,人名,一般", "ジュウ"),
] {
let mut tokens = vec![
reading_token("十", ten_pos, "ジュウ"),
reading_token(counter, counter_pos, "プン"),
];
apply_contextual_readings(&mut tokens);
assert_eq!(&*tokens[0].reading, expected);
}
}

fn reading_token(surface: &str, pos: &str, reading: &str) -> Token {
Token {
surface: surface.into(),
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ mod kana;
#[cfg(feature = "analyzer")]
pub mod lattice;
#[cfg(feature = "analyzer")]
mod numeric;
#[cfg(feature = "analyzer")]
pub mod pos;
pub mod sentence;

Expand Down
Loading
Loading