リンデラ
lindera トークナイザーは辞書ベースの形態素解析を行います。これは、単語がスペースで区切られず、文法マーカー(助詞)が直接単語に付加される日本語と韓国語用に設計されています。
中国語テキストの場合:lindera はcc-cedict 辞書によって中国語をサポートしていますが、代わりに jiebaの使用をお勧めします。Jieba は中国語の単語分割に特化して設計されており、よりよい結果が得られます。
概要
日本語と韓国語は膠着語です。助詞と呼ばれる文法マーカーが名詞に直接くっついて、多数の組み合わせを形成します。例えば
言語 |
ルートワード |
+助詞 |
= 結合形 |
意味 |
|---|---|---|---|---|
韓国語 |
서울(ソウル) |
에서 |
서울에서 |
ソウルにて |
日本語 |
東京 |
に |
東京に |
東京に |
lindera トークン化:
テキストを個々の形態素(単語と助詞)に分割する。
各トークンに辞書の品詞情報をタグ付け。
フィルタを適用して、不要なトークン(助詞や句読点など)を削除する。
この2段階のプロセス(セグメンテーションと品詞ベースのフィルタリング)により、検索用にインデックス化されるトークンを正確に制御できます。
前提条件
Milvus 2.6以上のユーザー:このセクションはスキップできます。すべての辞書はコンパイル済みで、公式リリースに含まれています。
Milvus 2.5.xの場合、特定の辞書を有効にしてMilvusをコンパイルする必要があります。すべての辞書はコンパイル時に明示的にインクルードする必要があります。
特定の辞書を有効にするには、コンパイルコマンドにその辞書を含めます:
make milvus TANTIVY_FEATURES=lindera-ipadic,lindera-ko-dic
利用可能な辞書の完全なリスト
辞書 |
言語 |
説明 |
|---|---|---|
リンデラ韓国語 |
韓国語 |
韓国語形態素解析辞書(MeCab Ko-dic) |
リンデラ・イパディック |
日本語 |
標準形態素辞書(MeCab IPADIC) |
リンデラ・イパディック・ネオロゴド |
日本語 |
新語や固有名詞を含む拡張辞書(IPADIC NEologd) |
リンデラ-ユニディック |
日本語 |
学術標準辞書(UniDic) |
lindera-cc-cedict |
中国語 |
コミュニティ管理型中英辞書(CC-CEDICT) |
たとえば、すべての辞書を有効にする場合:
make milvus TANTIVY_FEATURES=lindera-ipadic,lindera-ipadic-neologd,lindera-unidic,lindera-ko-dic,lindera-cc-cedict
構成
lindera トークナイザを使用する解析器を構成するには、tokenizer.type をlindera に設定し、dict_kind で辞書を選択し、オプションでフィルタを適用します。
analyzer_params = {
"tokenizer": {
"type": "lindera",
"dict_kind": "ko-dic",
"filter": [
{
"kind": "korean_stop_tags",
"tags": ["SP", "SSC", "SSO", "SC", "SE", "SF", "JKS", "JKC", "JKG", "JKO", "JKB", "JKV", "JKQ", "JX", "JC", "UNK", "EP", "ETM"]
}
]
}
}
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", new HashMap<String, Object>() {{
put("type", "lindera");
put("dict_kind", "ko-dic");
put("filter", Arrays.asList(
new HashMap<String, Object>() {{
put("kind", "korean_stop_tags");
put("tags", Arrays.asList(
"SP", "SSC", "SSO", "SC", "SE", "SF",
"JKS", "JKC", "JKG", "JKO", "JKB", "JKV", "JKQ",
"JX", "JC", "UNK", "EP", "ETM"
));
}}
));
}});
analyzerParams := map[string]interface{}{
"tokenizer": map[string]interface{}{
"type": "lindera",
"dict_kind": "ko-dic",
"filter": []interface{}{
map[string]interface{}{
"kind": "korean_stop_tags",
"tags": []string{
"SP", "SSC", "SSO", "SC", "SE", "SF",
"JKS", "JKC", "JKG", "JKO", "JKB", "JKV", "JKQ",
"JX", "JC", "UNK", "EP", "ETM",
},
},
},
},
}
const analyzer_params = {
"tokenizer": {
"type": "lindera",
"dict_kind": "ko-dic",
"filter": [
{
"kind": "korean_stop_tags",
"tags": ["SP", "SSC", "SSO", "SC", "SE", "SF", "JKS", "JKC", "JKG", "JKO", "JKB", "JKV", "JKQ", "JX", "JC", "UNK", "EP", "ETM"]
}
]
}
};
# restful
パラメータ |
説明 |
|---|---|
|
トークナイザーのタイプ。これは |
|
語彙の定義に使用する辞書。指定可能な値:
|
|
セグメンテーションの後に適用する、トークナイザーレベルのフィルターのリスト。各フィルターは、次のようなオブジェクトです:
|
analyzer_params を定義した後、コレクションスキーマを定義するときにVARCHAR フィールドに適用できます。これにより、Milvusは指定された解析器を使用してそのフィールドのテキストを処理し、効率的なトークン化とフィルタリングを行うことができます。詳細については、使用例を参照してください。
使用例
アナライザ設定をコレクションスキーマに適用する前に、run_analyzer メソッドを使用して動作を確認してください。
韓国語の例
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530")
analyzer_params = {
"tokenizer": {
"type": "lindera",
"dict_kind": "ko-dic",
"filter": [
{
"kind": "korean_stop_tags",
"tags": ["SP", "SSC", "SSO", "SC", "SE", "SF", "JKS", "JKC", "JKG", "JKO", "JKB", "JKV", "JKQ", "JX", "JC", "UNK", "EP", "ETM"]
}
]
}
}
# Sample Korean text: "서울에서 맛있는 음식을 먹었습니다" (I ate delicious food in Seoul)
sample_text = "서울에서 맛있는 음식을 먹었습니다"
result = client.run_analyzer(sample_text, analyzer_params)
print("Analyzer output:", result)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.RunAnalyzerReq;
import io.milvus.v2.service.vector.response.RunAnalyzerResp;
ConnectConfig config = ConnectConfig.builder()
.uri("http://localhost:19530")
.build();
MilvusClientV2 client = new MilvusClientV2(config);
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", new HashMap<String, Object>() {{
put("type", "lindera");
put("dict_kind", "ko-dic");
put("filter", Arrays.asList(
new HashMap<String, Object>() {{
put("kind", "korean_stop_tags");
put("tags", Arrays.asList(
"SP", "SSC", "SSO", "SC", "SE", "SF",
"JKS", "JKC", "JKG", "JKO", "JKB", "JKV", "JKQ",
"JX", "JC", "UNK", "EP", "ETM"
));
}}
));
}});
List<String> texts = new ArrayList<>();
texts.add("서울에서 맛있는 음식을 먹었습니다");
RunAnalyzerResp resp = client.runAnalyzer(RunAnalyzerReq.builder()
.texts(texts)
.analyzerParams(analyzerParams)
.build());
List<RunAnalyzerResp.AnalyzerResult> results = resp.getResults();
import (
"context"
"encoding/json"
"fmt"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: "localhost:19530",
APIKey: "root:Milvus",
})
if err != nil {
fmt.Println(err.Error())
// handle error
}
analyzerParams := map[string]interface{}{
"tokenizer": map[string]interface{}{
"type": "lindera",
"dict_kind": "ko-dic",
"filter": []interface{}{
map[string]interface{}{
"kind": "korean_stop_tags",
"tags": []string{
"SP", "SSC", "SSO", "SC", "SE", "SF",
"JKS", "JKC", "JKG", "JKO", "JKB", "JKV", "JKQ",
"JX", "JC", "UNK", "EP", "ETM",
},
},
},
},
}
bs, _ := json.Marshal(analyzerParams)
texts := []string{"서울에서 맛있는 음식을 먹었습니다"}
option := milvusclient.NewRunAnalyzerOption(texts).
WithAnalyzerParams(string(bs))
result, err := client.RunAnalyzer(ctx, option)
if err != nil {
fmt.Println(err.Error())
// handle error
}
import { MilvusClient } from "@zilliz/milvus2-sdk-node";
const client = new MilvusClient({
uri: "http://localhost:19530",
});
const analyzer_params = {
tokenizer: {
type: "lindera",
dict_kind: "ko-dic",
filter: [
{
kind: "korean_stop_tags",
tags: [
"SP",
"SSC",
"SSO",
"SC",
"SE",
"SF",
"JKS",
"JKC",
"JKG",
"JKO",
"JKB",
"JKV",
"JKQ",
"JX",
"JC",
"UNK",
"EP",
"ETM",
],
},
],
},
};
const sample_text = "서울에서 맛있는 음식을 먹었습니다";
const result = await client.run_analyzer(sample_text, analyzer_params);
console.log("Analyzer output:", result);
# restful
期待される出力:
['서울', '맛있', '음식', '먹', '습니다']
korean_stop_tags がない場合、에서 (in),는 (topic marker),을 (object marker)のような助詞が出力される。
日本語の例
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530")
analyzer_params = {
"tokenizer": {
"type": "lindera",
"dict_kind": "ipadic",
"filter": [
{
"kind": "japanese_stop_tags",
"tags": ["接続詞", "助詞,格助詞", "助詞,格助詞,一般", "助詞,格助詞,引用", "助詞,格助詞,連語", "助詞,係助詞", "助詞,終助詞", "助詞,接続助詞", "助詞,特殊", "助詞,副助詞", "助詞,副助詞/並立助詞/終助詞", "助詞,連体化", "助詞,副詞化", "助詞,並立助詞", "助動詞", "記号,一般", "記号,読点", "記号,句点", "記号,空白", "記号,括弧閉", "記号,括弧開", "その他,間投", "フィラー", "非言語音"]
}
]
}
}
# Sample Japanese text: "東京スカイツリーの最寄り駅はとうきょうスカイツリー駅です"
sample_text = "東京スカイツリーの最寄り駅はとうきょうスカイツリー駅です"
result = client.run_analyzer(sample_text, analyzer_params)
print("Analyzer output:", result)
// java
// go
import { MilvusClient } from "@zilliz/milvus2-sdk-node";
const client = new MilvusClient({
uri: "http://localhost:19530",
});
const analyzer_params = {
"tokenizer": {
"type": "lindera",
"dict_kind": "ipadic",
"filter": [
{
"kind": "japanese_stop_tags",
"tags": ["接続詞", "助詞,格助詞", "助詞,格助詞,一般", "助詞,格助詞,引用", "助詞,格助詞,連語", "助詞,係助詞", "助詞,終助詞", "助詞,接続助詞", "助詞,特殊", "助詞,副助詞", "助詞,副助詞/並立助詞/終助詞", "助詞,連体化", "助詞,副詞化", "助詞,並立助詞", "助動詞", "記号,一般", "記号,読点", "記号,句点", "記号,空白", "記号,括弧閉", "記号,括弧開", "その他,間投", "フィラー", "非言語音"]
}
]
}
}
// Sample Japanese text: "東京スカイツリーの最寄り駅はとうきょうスカイツリー駅です"
const sample_text = "東京スカイツリーの最寄り駅はとうきょうスカイツリー駅です"
const result = await client.run_analyzer(sample_text, analyzer_params);
console.log("Analyzer output:", result);
# restful
期待される出力:
['東京', 'スカイ', 'ツリー', '最寄り駅', 'とう', 'きょう', 'スカイ', 'ツリー', '駅']
japanese_stop_tags がなければ、の (所有格)、は (トピック・マーカー)、です (コピュラ)のような助詞が出力される。