Анализаторы для обработки текста в поиске ИИ Azure

Note

Поиск с использованием ИИ Azure доступна через портал Azure, REST API и Azure SDKs. Он также лежит в основе Foundry IQ — управляемого слоя знаний, который преобразует корпоративный контент в многократно используемые базы знаний с учетом разрешений доступа для агентов на портале Microsoft Foundry.

Анализатор — это компонент системы полнотекстового поиска, отвечающий за обработку строк во время индексации и выполнения запроса. Обработка текста (также называемая лексическим анализом) преобразует строку запроса с помощью следующих действий:

  • Удалите несущественные слова (стоп-слова) и знаки пунктуации.
  • Разделение фраз и слов с дефисом на составные части.
  • Преобразование слов в верхнем регистре в слова в нижнем регистре.
  • Сокращение слов до примитивных корневых форм, чтобы обеспечить эффективность хранения и возможность поиска совпадений независимо от грамматических форм.

Выходные данные лексического анализатора — это последовательность маркеров.

Лексический анализ применяется к Edm.String полям, помеченным как "доступный для поиска", который указывает на полный текстовый поиск. Для полей с такой конфигурацией анализ происходит во время индексирования при создании маркеры, а затем снова во время выполнения запроса, когда запросы анализируются и обработчик ищет совпадающие маркеры. Совпадение чаще всего возникает, когда один и тот же анализатор используется как для индексирования, так и для запросов, но вы можете установить анализатор для каждой рабочей нагрузки независимо от требований.

Типы запросов, не имеющие полнотекстового поиска, такие как фильтры или нечеткий поиск, не проходят этап анализа на стороне запроса. Вместо этого средство синтаксического анализа отправляет эти строки непосредственно в поисковую систему, используя шаблон, который вы предоставляете в качестве основания для сопоставления. Как правило, для сопоставления шаблонов в этих формах запроса требуются токены целой строки. Чтобы обеспечить сохранение всех маркеров терминов во время индексирования, может потребоваться пользовательские анализаторы. Дополнительные сведения о том, когда и почему термины запросов анализируются, см. в полнотекстовом поиске в службе "Поиск ИИ Azure".

Чтобы получить дополнительные сведения о лексическом анализе, прослушайте следующий видеоролик с кратким объяснением.

Анализатор по умолчанию

В поиске ИИ Azure анализатор автоматически вызывается во всех строковых полях, помеченных как доступные для поиска.

По умолчанию поиск Azure AI использует анализатор Apache Lucene Standard (standard lucene), который разбивает текст на элементы в соответствии с правилами сегментации текста Юникода. Стандартный анализатор преобразует все знаки в нижний регистр. Анализу подвергаются как индексируемые документы, так и условия поиска во время индексирования и обработки запросов.

Можно переопределить значение по умолчанию для каждого поля. Альтернативные анализаторы:

Типы анализаторов

В следующем списке описывается, какие анализаторы доступны в службе "Поиск ИИ Azure".

Категория Описание
Стандартный анализатор Lucene По умолчанию. Не требуется спецификация или настройка. Этот универсальный анализатор подходит для многих языков и сценариев.
Встроенные анализаторы Используются "как есть" и указываются по имени. Существует два типа: языковые и независимые от языка.

Специализированные анализаторы (независящие от языка) используются для текстовых входных данных, требующих специализированной или минимальной обработки. К примерам анализаторов в этой категории относятся Asciifolding, Keyword, Pattern, Simple, Stop, Whitespace.

Анализаторы языка используются, когда требуется расширенная лингвистическая поддержка отдельных языков. Поиск ИИ Azure поддерживает 35 анализаторов языка Lucene и 50 анализаторов обработки естественного языка Майкрософт.
Пользовательские анализаторы Относится к пользовательской конфигурации комбинации существующих элементов, включающей один обязательный токенизатор и необязательные фильтры (символьные или токеновые).

Несколько встроенных анализаторов, таких как Pattern или Stop, поддерживают ограниченный набор параметров. Чтобы задать эти параметры, необходимо создать пользовательский анализатор, состоящий из встроенного анализатора и одного из альтернативных вариантов, описанных в разделе Встроенные анализаторы. Как и в случае любой другой пользовательской настройки, присвойте новой конфигурации имя, например myPatternAnalyzer, чтобы отличать ее от анализатора Pattern Lucene.

Назначение анализаторов

Настройка анализатора является необязательной. Как правило, можно использовать стандартный анализатор Lucene по умолчанию, чтобы узнать, как он работает. Если запросы не возвращают ожидаемые результаты, можно выбрать другой анализатор.

  1. Если вы используете пользовательский анализатор, добавьте его в индекс поиска в разделе "анализатор". Дополнительные сведения см. в Создание индекса и Добавление пользовательских анализаторов.

  2. При определении поля задайте для свойства "анализатор" одно из следующих значений: встроенный анализатор, например ключевое слово, анализатор языка такой как en.microsoft, или пользовательский анализатор (определенный в той же схеме индекса).

      "fields": [
     {
       "name": "Description",
       "type": "Edm.String",
       "retrievable": true,
       "searchable": true,
       "analyzer": "en.microsoft",
       "indexAnalyzer": null,
       "searchAnalyzer": null
     },
    
  3. Если вы используете анализатор языка, необходимо использовать свойство "анализатор", чтобы указать его. Свойства searchAnalyzer и IndexAnalyzer не применяются к анализаторам языка.

  4. В качестве альтернативы можно задать "indexAnalyzer" и "searchAnalyzer", чтобы использовать разные анализаторы для каждой рабочей нагрузки. Эти свойства работают вместе в качестве замены свойства "анализатора", которое должно иметь значение NULL. Для индексирования и запросов можно использовать различные анализаторы, если одно из этих действий требует определенного преобразования, которое не требуется другому.

      "fields": [
     {
       "name": "ProductGroup",
       "type": "Edm.String",
       "retrievable": true,
       "searchable": true,
       "analyzer": null,
       "indexAnalyzer": "keyword",
       "searchAnalyzer": "standard"
     },
    

Когда добавлять анализаторы

Добавлять и назначать анализаторы лучше всего во время активной разработки, когда часто выполняется удаление и воссоздание индексов.

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

Чтобы изменить анализатор существующего поля, необходимо удалить и повторно создать весь индекс (вы не можете перестроить отдельные поля). Для индексов в рабочей среде перестроение можно отложить, создав другое поле с новым назначением анализатора, и начать использовать его. Для внедрения нового поля используется запрос Update Index, а запрос mergeOrUpload позволяет заполнить его. Позже в рамках планового обслуживания индекса можно очистить его, чтобы удалить устаревшие поля.

Вы можете использовать запрос Update Index, чтобы добавить новое поле к имеющемуся индексу, и запрос mergeOrUpload, чтобы заполнить его.

Чтобы добавить пользовательский анализатор в существующий индекс, передайте флаг allowIndexDowntime в Update Index, если хотите избежать следующей ошибки:

"Index update not allowed because it would cause downtime. In order to add new analyzers, tokenizers, token filters, or character filters to an existing index, set the 'allowIndexDowntime' query parameter to 'true' in the index update request. Note that this operation will put your index offline for at least a few seconds, causing your indexing and query requests to fail. Performance and write availability of the index can be impaired for several minutes after the index is updated, or longer for very large indexes."

Рекомендации по работе с анализаторами

В этом разделе даны рекомендации по работе с анализаторами.

Использование одного анализатора для чтения и записи при отсутствии особых требований

Поиск ИИ Azure позволяет указать различные анализаторы для индексирования и поиска с помощью свойств поля IndexAnalyzer и searchAnalyzer. Если не указано иное, анализатор, заданный свойством analyzer, будет использоваться для обеих операций — индексирования и поиска. Если не указать анализатор, будет использоваться стандартный анализатор Lucene.

Мы рекомендуем использовать один анализатор для индексации и запросов при отсутствии специальных требований. Обязательно тщательно протестируйте его. Если обработка текста отличается во время поиска и индексирования, возникает риск несоответствия между терминами запроса и индексированных терминами, когда конфигурации анализатора поиска и индексирования не согласованы.

Тестирование во время активной разработки

Переопределение стандартного анализатора требует перестроения индекса. Если возможно, решите, какие анализаторы использовать в процессе активной разработки, перед внедрением индекса в рабочую среду.

Проверка токенизированных терминов

Если поиск не возвращает ожидаемые результаты, как правило, проблема заключается в несоответствии токенов между терминами на входе в запрос и токенизированными терминами в индексе. Если токены не одинаковые, то совпадения не возникают. Чтобы изучить результаты токенизатора, мы рекомендуем использовать API анализа в качестве инструмента исследования. Ответ содержит маркеры, которые создаются определенным анализатором.

Примеры REST

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

Пример пользовательского анализатора

В этом примере демонстрируется определение анализатора с настраиваемыми параметрами. Настраиваемые параметры для фильтров типа char, лексических анализаторов и фильтров маркеров указываются отдельно как именованные конструкции, а затем в определении анализатора на них приводятся ссылки. Стандартные элементы используются как есть, и сослаться на них можно по имени.

Рассмотрим этот пример:

  • Анализаторы являются свойством класса поля для поискового поля.

  • Пользовательский анализатор входит в определение индекса. Он может быть незначительно настроенным (например, настройка одного параметра в одном фильтре) или настроенным в нескольких местах.

  • В таком случае пользовательский анализатор "my_analyzer" в свою очередь использует настроенный стандартный лексический анализатор "my_standard_tokenizer" и два фильтра маркеров: с нижним регистром и настроенный фильтр типа asciifolding — "my_asciifolding".

  • Он также определяет 2 пользовательских фильтра char: "map_dash" и "remove_whitespace". Первый заменяет все тире символом подчеркивания, в то время как второй удаляет все пробелы. В соответствии с правилами сопоставления, все пробелы должны быть закодированы в формате UTF-8. Фильтры символов применяются перед токенизацией и будут влиять на полученные токены (стандартный токенизатор разбивает по тире и пробелам, но не по подчеркиванию).

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"my_analyzer"
        }
     ],
     "analyzers":[
        {
           "name":"my_analyzer",
           "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
           "charFilters":[
              "map_dash",
              "remove_whitespace"
           ],
           "tokenizer":"my_standard_tokenizer",
           "tokenFilters":[
              "my_asciifolding",
              "lowercase"
           ]
        }
     ],
     "charFilters":[
        {
           "name":"map_dash",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["-=>_"]
        },
        {
           "name":"remove_whitespace",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["\\u0020=>"]
        }
     ],
     "tokenizers":[
        {
           "name":"my_standard_tokenizer",
           "@odata.type":"#Microsoft.Azure.Search.StandardTokenizerV2",
           "maxTokenLength":20
        }
     ],
     "tokenFilters":[
        {
           "name":"my_asciifolding",
           "@odata.type":"#Microsoft.Azure.Search.AsciiFoldingTokenFilter",
           "preserveOriginal":true
        }
     ]
  }

Пример назначения анализатора для каждого поля

Стандартный анализатор используется по умолчанию. Предположим, что необходимо заменить анализатор по умолчанию другим стандартным анализатором, например анализатором шаблона. Если вы не задаете настраиваемые параметры, необходимо указать его только по имени в определении поля.

Элемент "analyzer" переопределяет стандартный анализатор на уровне каждого поля. Глобальное переопределение отсутствует. В этом примере text1 использует анализатор шаблона, а значение text2, которое не указывает анализатор, использует значение по умолчанию.

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text1",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"pattern"
        },
        {
           "name":"text2",
           "type":"Edm.String",
           "searchable":true
        }
     ]
  }

Совмещение анализаторов для индексирования и поиска

API включает атрибуты индекса для указания других анализаторов для индексирования и поиска. Атрибуты searchAnalyzer и indexAnalyzer необходимо указывать вместе, заменяя одиночный атрибут analyzer.

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "indexAnalyzer":"whitespace",
           "searchAnalyzer":"simple"
        },
     ],
  }

Пример анализатора языка

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

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "indexAnalyzer":"whitespace",
           "searchAnalyzer":"simple"
        },
        {
           "name":"text_fr",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"fr.lucene"
        }
     ],
  }

Примеры C#

Если вы используете примеры кода пакета SDK для .NET, можно добавить эти примеры для использования или настройки анализаторов.

Назначение анализатора языка

Любой анализатор, используемый "как есть", без конфигурации, указывается в определении поля. Нет необходимости в создании записи в разделе [analyzers] индекса.

Языковые анализаторы используются как есть. Чтобы использовать их, вызовите LexicalAnalyzer, указав тип LexicalAnalyzerName, предоставляющий текстовый анализатор, поддерживаемый в поиске ИИ Azure.

Пользовательские анализаторы аналогично задаются в определении поля, но для их работы необходимо указать анализатор в определении индекса, как описано в следующем разделе.

    public partial class Hotel
    {
       . . . 
        [SearchableField(AnalyzerName = LexicalAnalyzerName.EnLucene)]
        public string Description { get; set; }

        [SearchableField(AnalyzerName = LexicalAnalyzerName.FrLucene)]
        [JsonPropertyName("Description_fr")]
        public string DescriptionFr { get; set; }

        [SearchableField(AnalyzerName = "url-analyze")]
        public string Url { get; set; }
      . . .
    }

Определение пользовательского анализатора

Если требуется настройка или конфигурация, добавьте к индексу конструкцию анализатора. После его определения можно добавить его в определение поля, как показано в предыдущем примере.

Создайте объект CustomAnalyzer. Пользовательский анализатор — это определяемое пользователем сочетание известного токенизатора, нуля или более фильтров токенов и нуля или более символьных фильтров.

В следующем примере создается пользовательский анализатор с именем "url-analyze", использующий токенизатор uax_url_email и фильтр токенов в нижнем регистре.

private static void CreateIndex(string indexName, SearchIndexClient adminClient)
{
   FieldBuilder fieldBuilder = new FieldBuilder();
   var searchFields = fieldBuilder.Build(typeof(Hotel));

   var analyzer = new CustomAnalyzer("url-analyze", LexicalTokenizerName.UaxUrlEmail)
   {
         TokenFilters = { LexicalTokenFilterName.Lowercase }
   };

   var definition = new SearchIndex(indexName, searchFields);

   definition.Analyzers.Add(analyzer);

   adminClient.CreateOrUpdateIndex(definition);
}

Следующие шаги

Подробное описание выполнения запроса можно найти в полнотекстовом поиске в службе "Поиск ИИ Azure". В этой статье используются примеры для пояснения реакций, являющихся, на первый взгляд, нелогичными.

Дополнительные сведения об анализаторах см. в следующих статьях: