Lindera

Токенизатор lindera выполняет морфологический анализ на основе словаря. Он предназначен для японского и корейского языков, в которых слова не разделяются пробелами, а грамматические маркеры (частицы) присоединяются непосредственно к словам.

Для китайского текста: Хотя lindera поддерживает китайский язык через словарь cc-cedict, мы рекомендуем использовать jieba токенизатор. Jieba специально разработана для сегментации китайских слов и обеспечивает лучшие результаты.

Обзор

Японский и корейский - агглютинативные языки: грамматические маркеры, называемые частицами, присоединяются непосредственно к существительным, образуя многочисленные комбинации. Например:

Язык

Корневое слово

+ частица

= Комбинированная форма

Значение

Корейский

서울 (Сеул)

에서

서울에서

в Сеуле

Японский

東京 (Токио)

東京に

в Токио

Токенизатор lindera:

  1. Сегментирует текст на отдельные морфемы (слова и частицы)

  2. Помечает каждую лексему информацией о части речи (POS) из словаря

  3. Применяет фильтры для удаления нежелательных лексем (например, частиц, знаков препинания).

Этот двухэтапный процесс - сегментация с последующей фильтрацией на основе POS - позволяет точно контролировать, какие лексемы будут проиндексированы для поиска.

Необходимые условия

Пользователи Milvus 2.6+: Вы можете пропустить этот раздел. Все словари предварительно скомпилированы и включены в официальный релиз.

Для Milvus 2.5.x необходимо скомпилировать Milvus с включенными определенными словарями. Все словари должны быть явно включены во время компиляции.

Чтобы включить определенные словари, включите их в команду компиляции:

make milvus TANTIVY_FEATURES=lindera-ipadic,lindera-ko-dic

Полный список доступных словарей:

Словарь

Язык

Описание

lindera-ko-dic

Корейский

Морфологический словарь корейского языка(MeCab Ko-dic)

lindera-ipadic

Японский

Стандартный морфологический словарь(MeCab IPADIC)

линдара-ипадик-неологд

Японский

Расширенный словарь с новыми словами и собственными существительными(IPADIC NEologd)

lindera-unidic

Японский

Академический стандартный словарь(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

Параметр

Описание

type

Тип токенизатора. Установлено значение "lindera".

dict_kind

Словарь, используемый для определения лексики. Возможные значения:

  • ko-dic: Корейский - корейский морфологический словарь(MeCab Ko-dic)

  • ipadic: : Японский - Стандартный морфологический словарь(MeCab IPADIC)

  • ipadic-neologd: Японский со словарем неологизмов (расширенный) - Включает новые слова и собственные существительные(IPADIC NEologd)

  • unidic: Японский UniDic (расширенный) - Академический стандартный словарь с подробной лингвистической информацией(UniDic)

  • cc-cedict: Мандаринский китайский (традиционный/упрощенный) - Поддерживаемый сообществом китайско-английский словарь(CC-CEDICT)

filter

Список фильтров уровня токенизатора для применения после сегментации. Каждый фильтр - это объект с:

  • kind: Тип фильтра. Поддерживаемые значения:

    • korean_stop_tags: Удалять лексемы, соответствующие указанным корейским POS-тегам.

    • japanese_stop_tags: Удалить лексемы, соответствующие указанным японским POS-тегам.

  • tags: Список POS-тегов для фильтрации. Доступные теги зависят от kind:

    • Для korean_stop_tags: Используйте точные коды тегов (например, JKS, JKO, SF). Корейские теги требуют точного соответствия. Полный список, основанный на наборе тегов Sejong, см. в источнике Lindera Korean stop tags.

    • Для japanese_stop_tags: Используйте точные коды тегов (например, 助詞,格助詞, 助詞,係助詞, 助動詞). Японские теги требуют точного соответствия. Полный список (IPADIC) см. в справочнике по японским POS-тегам.

Определив 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), (маркер темы) и (маркер объекта), которые обычно не используются для поиска.

Японский пример

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 результат будет включать такие частицы, как (притяжательный), (маркер темы) и です (копула).

Попробуйте Managed Milvus бесплатно

Zilliz Cloud работает без проблем, поддерживается Milvus и в 10 раз быстрее.

Начать
Обратная связь

Была ли эта страница полезной?