Распознавание данных в тексте является довольно распространенной задачей. И компания Microsoft предоставляет набор бесплатных библиотек recognizers-text, которые можно использовать для этой задачи.
Microsoft.Recognizers.Text.Number: для распознавания чисел в тексте
Microsoft.Recognizers.Text.NumberWithUnit: для распознавания в тексте чисел вместе с единицами измерения
Microsoft.Recognizers.Text.DateTime: для распознавания в тексте дат и времени
Microsoft.Recognizers.Text.Sequence: для распознавания последовательностей типа номер телефона, адрес электронной почты и т.д.
Microsoft.Recognizers.Text.Choice: для распознавания ответов типа да/нет, истина/ложь.
Установим все эти пакеты и через пакетный менеджер Nuget.
Для распознавания данных в тексте применяется ряд классов:
NumberRecognizer (пакет Microsoft.Recognizers.Text.Number
)
ChoiceRecognizer (пакет Microsoft.Recognizers.Text.Choice
)
SequenceRecognizer (пакет Microsoft.Recognizers.Text.Sequence
)
DateTimeRecognizer (пакет Microsoft.Recognizers.Text.DateTime
)
NumberWithUnitRecognizer (пакет Microsoft.Recognizers.Text.NumberWithUnit
)
Для распознавания конкретных данных эти классы определяют ряд статических методов:
NumberRecognizer.RecognizeNumber()
: распознает числа
NumberRecognizer.RecognizeOrdinal()
: распознает порядковые числа
NumberRecognizer.RecognizePercentage()
: распознает значения процентов
NumberWithUnitRecognizer.RecognizeAge()
: распознает возраст
NumberWithUnitRecognizer.RecognizeCurrency()
: распознает валюты
NumberWithUnitRecognizer.RecognizeDimension()
: распознает различные значения, которые применяются при измерении
NumberWithUnitRecognizer.RecognizeTemperature()
: распознает температуры
DateTimeRecognizer.RecognizeDateTime()
: распознает дату и время
SequenceRecognizer.RecognizePhoneNumber()
: распознает номер телефона
SequenceRecognizer.RecognizeIpAddress()
: распознает ip-адрес
SequenceRecognizer.RecognizeEmail()
: распознает адрес электронной почты
SequenceRecognizer.RecognizeURL()
: распознает адрес URL
SequenceRecognizer.RecognizeGUID()
: распознает значение guid
SequenceRecognizer.RecognizeQuotedText()
: распознает цитаты
SequenceRecognizer.RecognizeHashtag()
: распознает хеш-тег
ChoiceRecognizer.RecognizeBoolean()
: распознает булевые значения
Все эти методы в качестве первого параметра принимает текст, в котором надо распознать данные, а в качестве второго - культуру.
Результатом методов является список объектов ModelResult
, который хранит результы распозначания в следующих свойствах:
Text
: подстрока в текста, которая сопоставляется с данными
Start
: индекс начала сопоставленной подстроки
End
: конечный индекс сопоставленной подстроки
TypeName
: тип сопоставленного значения
Resolution
: собственно данные сопоставления. Представляет словарь, где ключ value собственно представляет распознанные данные.
Что касается языковых культур, для которых доступно преобразование на момент написания данной статьи:
Culture.English, Culture.EnglishOthers, Culture.Dutch, Culture.Chinese, Culture.French, Culture.Italian, Culture.Japanese, Culture.Korean, Culture.Portuguese, Culture.Spanish, Culture.SpanishMexican, Culture.Turkish, Culture.German
Также ожидается добавление поддержки для арабского, японского, корейского и шведского языков.
Для распознавания чисел применяется метод NumberRecognizer.RecognizeNumber() из пакета Microsoft.Recognizers.Text.Number
:
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.Number; // results - набор найденных чисел var results = NumberRecognizer.RecognizeNumber("I have three apples and five oranges", Culture.English); foreach(var result in results) { Console.WriteLine($"Распознанный текст: {result.Text}"); Console.WriteLine($"Начальный индекс в строке: {result.Start}"); Console.WriteLine($"Начальный индекс в строке: {result.End}"); Console.WriteLine($"Распознаное значение: {result.Resolution["value"]}\n"); }
В данном случае исходное предложение "I have three apples and five oranges" содержит два числа: "three" и "five". Распознавание идет для английского языка. Соответственно консольный вывод распознавания будет следующим:
Распознанный текст: three Начальный индекс в строке: 7 Начальный индекс в строке: 11 Распознаное значение: 3 Распознанный текст: five Начальный индекс в строке: 24 Начальный индекс в строке: 27 Распознаное значение: 5
Таким образом, числа 3 и 5 распознаны.
Для распознавания порядковых чисел применяется метод NumberRecognizer.RecognizeOrdinal(). При обнаружении порядкового числительного она получает его числовое значение:
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.Number; // results - набор найденных чисел var results = NumberRecognizer.RecognizeOrdinal("The fifth book and the eleventh pencil", Culture.English); foreach (var result in results) { Console.WriteLine($"{result.Text} - {result.Resolution["value"]}"); }
Консольный вывод:
fifth - 5 eleventh - 11
Для распознавания процентов применяется метод NumberRecognizer.RecognizePercentage():
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.Number; var results = NumberRecognizer.RecognizePercentage("sixty-seven percents", Culture.English); foreach (var result in results) { Console.WriteLine($"{result.Text}: {result.Resolution["value"]}%"); // sixty-seven percent: 67% }
Для распознавания возраста применяется метод NumberWithUnitRecognizer.RecognizeAge():
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.NumberWithUnit; var results = NumberWithUnitRecognizer.RecognizeAge("Tom is thirty-eight years old", Culture.English); foreach (var result in results) { Console.WriteLine(result.Text); // thirty-eight years old Console.WriteLine(result.Resolution["value"]); // 38 }
Для распознавания валют применяется метод NumberWithUnitRecognizer.RecognizeCurrency():
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.NumberWithUnit; var results = NumberWithUnitRecognizer.RecognizeCurrency("the sum was $ 15.4 million", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]); // 15400000 } results = NumberWithUnitRecognizer.RecognizeCurrency("1 RUB = 0.013 EUR", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]); // 1 и 0.013 }
Для распознавания различных размеров, весов, расстояний, масс применяется метод NumberWithUnitRecognizer.RecognizeDimension():
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.NumberWithUnit; var results = NumberWithUnitRecognizer.RecognizeDimension("ten kg equals 22.0462262185 pounds", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]); // 10 и 22.0462262185 } results = NumberWithUnitRecognizer.RecognizeDimension("It took him half an hour to drive home from work. He averaged thirty-four miles per hour. ", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]"); // 34 }
Для распознавания температур применяется метод NumberWithUnitRecognizer.RecognizeTemperature():
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.NumberWithUnit; var results = NumberWithUnitRecognizer.RecognizeTemperature( @" The official highest recorded temperature is now 56.7°C (134°F), which was measured on 10 July 1913 at Greenland Ranch, Death Valley, California, USA ", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]); // 56.7 и 134 }
Для распознавания дат и времени применяется метод DateTimeRecognizer.RecognizeDateTime():
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.DateTime; var results = DateTimeRecognizer.RecognizeDateTime("I will go back 8pm today or 7am tomorrow", Culture.English); foreach (var result in results) { foreach (var value in result.Resolution.Values) { if (value is List<Dictionary<string, string>> dates) { foreach (var date in dates) Console.WriteLine(date["value"]); } } }
Здесь получение результата немного отличается от предыдущих примеров. В частности, атрибут result.Resolution.Values
представляет коллекцию значений,
где все элементы представляет список с одним словарем (тип List<Dictionary<string, string>>
), в котором собственно сопоставленное время хранится в элементе value
Результат работы программы:
2023-01-22 20:00:00 2023-01-23 07:00:00
Пакет Microsoft.Recognizers.Text.Sequence
предоставляет класс SequenceRecognizer, в котором есть ряд методов для распознавания последовательностей:
SequenceRecognizer.RecognizePhoneNumber()
(номер телефона)
SequenceRecognizer.RecognizeEmail()
(адрес электронной почты)
SequenceRecognizer.RecognizeURL()
(адрес URL)
SequenceRecognizer.RecognizeGUID()
(значение guid)
SequenceRecognizer.RecognizeIpAddress()
(id-адрес)
SequenceRecognizer.RecognizeQuotedText()
(цитаты)
SequenceRecognizer.RecognizeHashtag()
(хеш-тег)
Применение некоторых функций
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.Sequence; var results = SequenceRecognizer.RecognizePhoneNumber("Main contact: +1-234-567-8901", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]); // +1-234-567-8901 } results = SequenceRecognizer.RecognizeEmail("Second contact: tom@somemail.com", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]); // tom@somemail.com }
Пакет Microsoft.Recognizers.Text.Choice
предоставляет тип ChoiceRecognizer, который с помощью метода RecognizeBoolean
позволяет распознать утверждения или отрицания в виде булевых значений:
using Microsoft.Recognizers.Text; using Microsoft.Recognizers.Text.Choice; var results = ChoiceRecognizer.RecognizeBoolean("Ok, I'll be doing that", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]); // true } results = ChoiceRecognizer.RecognizeBoolean("No, I don't agree", Culture.English); foreach (var result in results) { Console.WriteLine(result.Resolution["value"]); // false }