フィルタ
文字フィルタ(Character Filter)とトークンフィルタ(Token Filter)は、lindera-analysisのTokenizerパイプラインにおける前処理・後処理の2つの段階です。
- 文字フィルタはセグメンテーションの前に入力テキストを変換します。バイトオフセットは自動的に補正されるため、変換後のテキストに対して生成されたトークンでも、元のフィルタ前のテキストにおける位置が正しく報告されます。
- トークンフィルタはSegmenterが生成したトークンのリストをセグメンテーションの後に変換します。
どちらのフィルタも設定方法は共通で、kind文字列(CLIの--character-filter / --token-filterフラグでもkind:{"json": "args"}という形式で使用されます)と、フィルタ固有のパラメータを持つJSONのargsオブジェクトで構成されます。
文字フィルタ
文字フィルタはYAML設定ファイルのcharacter_filtersキーで設定します。各エントリは順番に適用され、あるフィルタの出力が次のフィルタの入力になります。
unicode_normalize
4種類の標準的なUnicode正規化形式のいずれかを使って入力テキストを正規化します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
kind | string | はい | nfc、nfd、nfkc、nfkdのいずれか |
例:
{
"kind": "unicode_normalize",
"args": {
"kind": "nfkc"
}
}
japanese_iteration_mark
日本語の踊り字(繰り返し記号)である々、ゝ、ゞ、ヽ、ヾを、それぞれが繰り返す文字に置き換えて正規化します。ひらがな・カタカナの繰り返し記号については、必要に応じて濁点の付与・除去も行います。
パラメータ:
| パラメータ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
normalize_kanji | bool | いいえ | false | 漢字の踊り字々を正規化する |
normalize_kana | bool | いいえ | false | ひらがな・カタカナの踊り字ゝ、ゞ、ヽ、ヾを正規化する |
例:
{
"kind": "japanese_iteration_mark",
"args": {
"normalize_kanji": true,
"normalize_kana": true
}
}
mapping(文字フィルタ)
mappingのキーに一致する部分を対応する値に置き換えます。入力テキスト全体に対して、Aho-Corasickオートマトンによる最長一致検索を行います。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
mapping | object(string to string) | はい | 置換対象の部分文字列と、その置換先の対応表 |
例:
{
"kind": "mapping",
"args": {
"mapping": {
"リンデラ": "Lindera"
}
}
}
regex
正規表現にマッチした箇所をすべて、リテラルな置換文字列で置き換えます。キャプチャグループの内容は置換文字列に展開されません。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
pattern | string | はい | 正規表現(regexクレートの構文) |
replacement | string | はい | patternにマッチした箇所すべてを置き換えるリテラル文字列 |
例:
{
"kind": "regex",
"args": {
"pattern": "\\s{2,}",
"replacement": " "
}
}
トークンフィルタ
トークンフィルタはYAML設定ファイルのtoken_filtersキーで設定します。各フィルタは、Segmenterが生成したトークンリストに対して順番に適用されます。
japanese_base_form
トークンの表層形を、辞書のbase_form(またはorthographic_base_form)フィールドに登録された原形(辞書形)に置き換えます。動詞・形容詞のレンマ化(見出し語化)として機能します。未知語処理によって生成されたトークン(token.word_id.is_unknown())は変更されません。
このフィルタに設定パラメータはありません。
例:
{
"kind": "japanese_base_form"
}
japanese_compound_word
品詞タグがtagsのいずれかに一致する連続したトークンを、1つの複合語トークンに結合します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
tags | array<string> | はい | 結合対象となるトークンを示す品詞タグ(カンマ区切りで最大4階層) |
new_tag | string | いいえ | 結合後のトークンに付与する品詞タグ。省略した場合は複合語が付与される |
例:
{
"kind": "japanese_compound_word",
"args": {
"tags": [
"名詞,数",
"名詞,接尾,助数詞"
],
"new_tag": "名詞,数"
}
}
japanese_kana
トークンテキストをひらがなとカタカナの間で相互変換します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
kind | string | はい | "hiragana"はカタカナをひらがなに、"katakana"はひらがなをカタカナに変換する |
例:
{
"kind": "japanese_kana",
"args": {
"kind": "hiragana"
}
}
japanese_katakana_stem
カタカナのトークンの末尾にある長音記号(ー、U+30FC)を除去します。ただし、トークンの文字数がminより大きい場合のみ除去されます。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
min | 正の整数 | はい | 末尾の長音記号をステミングする対象となる、カタカナトークンの最小文字数 |
例:
{
"kind": "japanese_katakana_stem",
"args": {
"min": 3
}
}
japanese_keep_tags
品詞タグがtagsのいずれかに一致するトークンのみを保持し、それ以外を除去します。
タグは 4 階層のカンマ区切りに正規化され(不足分は * で補完)、各トークンの先頭 4 つの品詞詳細と完全一致で比較されます。IPADIC の助詞トークンは必ず 助詞,係助詞 のようにサブカテゴリを持つため、助詞 単独では一致しません。一方、助動詞はサブカテゴリを持たないため(助動詞,*,*,*)、助動詞 単独で一致します。この動作は japanese_stop_tags も同様です。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
tags | array<string> | はい | 保持する品詞タグ(カンマ区切りで最大4階層) |
例:
{
"kind": "japanese_keep_tags",
"args": {
"tags": [
"名詞,一般"
]
}
}
japanese_number
トークンの表層テキストに含まれる日本語の数値表現(漢数字、大字、全角数字)をアラビア数字に変換します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
tags | array<string>またはnull | いいえ | 変換対象を限定する品詞タグ(カンマ区切りで最大4階層)。省略またはnullの場合はすべてのトークンが変換対象になる |
例:
{
"kind": "japanese_number",
"args": {
"tags": [
"名詞,数"
]
}
}
japanese_reading_form
トークンの表層テキストを、辞書のreadingフィールドに登録された読み(カタカナ)に置き換えます。未知語処理によって生成されたトークン(token.word_id.is_unknown())は変更されません。
このフィルタに設定パラメータはありません。
例:
{
"kind": "japanese_reading_form"
}
japanese_stop_tags
品詞タグがtagsのいずれかに一致するトークンを除去します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
tags | array<string> | はい | 除去する品詞タグ(カンマ区切りで最大4階層) |
例:
{
"kind": "japanese_stop_tags",
"args": {
"tags": [
"助詞,格助詞,一般",
"助詞,係助詞",
"助詞,連体化",
"助動詞"
]
}
}
keep_words
表層テキストがwordsのいずれかに完全一致するトークンのみを保持します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
words | array<string> | はい | 保持する表層形の一覧 |
例:
{
"kind": "keep_words",
"args": {
"words": [
"すもも",
"もも"
]
}
}
korean_keep_tags
最初の品詞タグがtagsのいずれかに一致する韓国語トークンのみを保持します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
tags | array<string> | はい | 保持する品詞タグ |
例:
{
"kind": "korean_keep_tags",
"args": {
"tags": [
"NNG"
]
}
}
korean_reading_form
トークンの表層テキストを、辞書のreadingフィールドに登録された読みに置き換えます。未知語処理によって生成されたトークン(token.word_id.is_unknown())は変更されません。
このフィルタに設定パラメータはありません。
例:
{
"kind": "korean_reading_form"
}
korean_stop_tags
最初の品詞タグがtagsのいずれかに一致する韓国語トークンを除去します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
tags | array<string> | はい | 除去する品詞タグ |
例:
{
"kind": "korean_stop_tags",
"args": {
"tags": [
"EP",
"EF",
"JKG"
]
}
}
length
表層テキストの文字数が[min, max]の範囲に収まるトークンのみを保持します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
min | 符号なし整数 | いいえ | 最小文字数(この値を含む) |
max | 符号なし整数 | いいえ | 最大文字数(この値を含む) |
例:
{
"kind": "length",
"args": {
"min": 2,
"max": 3
}
}
lowercase
トークンの表層テキストを小文字に変換します。
このフィルタに設定パラメータはありません。
例:
{
"kind": "lowercase"
}
mapping(トークンフィルタ)
mappingのキーに一致する部分を、各トークンの表層テキスト内で対応する値に置き換えます。Aho-Corasickオートマトンによる最長一致検索を使用します。文字フィルタのmappingのトークン版に相当します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
mapping | object(string to string) | はい | 置換対象の部分文字列と、その置換先の対応表 |
例:
{
"kind": "mapping",
"args": {
"mapping": {
"籠": "篭"
}
}
}
remove_diacritical_mark
トークンの表層テキストからダイアクリティカルマーク(発音区別符号)を除去し、その後テキストの元のUnicode正規化形式を再適用します。
パラメータ:
| パラメータ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
japanese | bool | いいえ | false | 日本語の濁点・半濁点の結合文字(分解済みの濁音・半濁音仮名に含まれるものなど)も除去する |
例:
{
"kind": "remove_diacritical_mark",
"args": {
"japanese": false
}
}
stop_words
表層テキストがwordsのいずれかに完全一致するトークンを除去します。
パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
words | array<string> | はい | 除去する表層形の一覧 |
例:
{
"kind": "stop_words",
"args": {
"words": [
"も",
"の"
]
}
}
uppercase
トークンの表層テキストを大文字に変換します。
このフィルタに設定パラメータはありません。
例:
{
"kind": "uppercase"
}
YAML設定
文字フィルタとトークンフィルタは、Segmenterと一緒に1つのYAMLファイルで設定します。ファイル全体の形式は設定を参照してください。関連する部分だけを抜粋すると次のようになります。
character_filters:
- kind: "unicode_normalize"
args:
kind: "nfkc"
- kind: "japanese_iteration_mark"
args:
normalize_kanji: true
normalize_kana: true
token_filters:
- kind: "japanese_stop_tags"
args:
tags:
- "助詞,格助詞,一般"
- "助詞,係助詞"
- "助詞,連体化"
- "助動詞"
- kind: "japanese_katakana_stem"
args:
min: 3
- kind: "lowercase"
- kind: "length"
args:
min: 2
Rust API
文字フィルタとトークンフィルタは、プログラムから作成・適用することもできます。
use lindera::dictionary::load_dictionary; use lindera::mode::Mode; use lindera::segmenter::Segmenter; use lindera_analysis::character_filter::BoxCharacterFilter; use lindera_analysis::character_filter::unicode_normalize::{ UnicodeNormalizeCharacterFilter, UnicodeNormalizeKind, }; use lindera_analysis::token_filter::BoxTokenFilter; use lindera_analysis::token_filter::japanese_stop_tags::JapaneseStopTagsTokenFilter; use lindera_analysis::token_filter::japanese_katakana_stem::JapaneseKatakanaStemTokenFilter; use lindera_analysis::tokenizer::Tokenizer; use lindera::LinderaResult; fn main() -> LinderaResult<()> { let dictionary = load_dictionary("embedded://ipadic")?; let segmenter = Segmenter::new(Mode::Normal, dictionary, None); let mut tokenizer = Tokenizer::new(segmenter); // 文字フィルタを追加 let normalize_filter = UnicodeNormalizeCharacterFilter::new(UnicodeNormalizeKind::NFKC); tokenizer.append_character_filter(BoxCharacterFilter::from(normalize_filter)); // トークンフィルタを追加 let stop_tags_filter = JapaneseStopTagsTokenFilter::new( vec![ "助詞,格助詞,一般".to_string(), "助詞,係助詞".to_string(), "助詞,連体化".to_string(), "助動詞".to_string(), ] .into_iter() .collect(), ); tokenizer.append_token_filter(BoxTokenFilter::from(stop_tags_filter)); let katakana_stem_filter = JapaneseKatakanaStemTokenFilter::new(std::num::NonZeroUsize::new(3).unwrap()); tokenizer.append_token_filter(BoxTokenFilter::from(katakana_stem_filter)); // フィルタを適用してトークナイズ let tokens = tokenizer.tokenize("Linderaは形態素解析エンジンです。")?; for token in tokens { println!( "token: {:?}, details: {:?}", token.surface, token.details ); } Ok(()) }
append_character_filterとappend_token_filterメソッドは、フィルタを追加した順番で登録します。文字フィルタはセグメンテーション前のテキストに対して順次適用され、トークンフィルタはセグメンテーション後のトークンリストに対して順次適用されます。