Как заменить регулярные выражения нейронной сетью?
Наиболее часто используемый инструмент для поиска подстроки определенного вида в тексте – это регулярные выражения. Но можно ли вместо регулярного выражения использовать нейронную сеть, которая бы выполняла ту же самую задачу?
Задача: найти в тексте описание стоимости недвижимости, то есть численное обозначение и стоимость, записанную прописью. Например, 2 050 000 (два миллиона пятьдесят тысяч) руб., 00 коп. Задача усложняется тем, что «рубли» и «копейки» могут быть в любом месте (перед скобками или после) и могут быть сокращены.
Чтобы решить данную задачу, будем использовать NLP (Natural Language Processing), морфологический анализатор и нейронную сеть. Подключаем соответствующие библиотеки:
Прежде всего необходимо выполнить обработку текста.
1. Токенизируем текст с помощью nltk.
2. Уберем стоп-слова из текста и знаки препинания, которые нам не нужны (например, : или “).
3. После этого пройдемся по тексту и выберем фрагменты, в которых встречается слово «рубли» в полном варианте или в сокращенном. В итоге получаем фрагменты предложений, которые содержат одинаковое количество слов/знаков/чисел. Именно в этих фрагментах мы и будем искать стоимость.
Следующим шагом нужно представить «слова» в виде чисел, так как нейронная сеть работает только с числами. Для этого пройдемся по каждому полученному фрагменту и определим части речи для каждого «слова». В этом нам поможет морфологический анализатор pymorphy2.
При анализе выделим 6 групп значений:
- PNCT – знаки пунктуации: ( ) . ,
- NUMB – числа
- NUMR – числительные
- NOUN – существительные: «тысяча», «миллион», «миллиард»
- NOUN – существительные: «рубль», «копейка» и их сокращенные формы
- Все остальные части речи, которые не встречаются в нужных нам фрагментах
Каждое «слово» в зависимости от того, в какую группу оно попало, представим в виде вектора значений из 6 чисел, содержащего 0 и 1 – 0, если число не относится к данной группе, 1 – если относится. Получается, что каждое «слово» закодировано пятью нулями и одной единицей. Каждый фрагмент, в котором мы будем искать стоимость, содержит 23 «слова», соответственно получаем 138 чисел для одного фрагмента. Именно эти значения будем подавать на вход нейронной сети.
Чтобы обучить нейронную сеть, составим выборку. Входные данные уже имеются, остается составить выходные. Выходные данные для одного фрагмента будут представлены в виде 23 чисел – 0 и 1. Единицами обозначим тот фрагмент, который в итоге нужно выбрать из текста и который содержит стоимость.
Как преобразовывались данные:
Фрагмент, содержащий стоимость:
Фрагмент, преобразованный в числа:
Выходные данные для фрагмента:
Создаем модель нейронной сети. Она будет состоять из 4 плотно связанных слоев Dense, с учетом входного и выходного. Используем наиболее распространенную функцию активации «relu» для каждого слоя, кроме выходного. Также добавим слой Dropout, чтобы предотвратить переобучение модели.
Важным критерием работы нейронной сети оказалась функция потерь. Наиболее стабильный и достоверный результат получился при функции потерь MSE (средняя квадратическая ошибка).
Обучаем модель и выполняем предсказания для тестовых данных. На выходе получаем последовательность из 23 чисел для каждого фрагмента. Числа, которые больше 0,9 – нужные нам значения, заменим их на 1. Находим начало и конец последовательности единиц. Далее по индексам начала и конца последовательности единиц выбираем стоимость из фрагмента текста.
Что получается при обработке тестовых данных?
Фрагмент, в котором ищем стоимость
Фрагмент, преобразованный в числа
Значения, полученные после работы нейронной сети
Выбранный фрагмент стоимости
Процент корректно выбранных фрагментов стоимости составляет 94% по результатам работы данной нейронной сети.
Интересно, что собой представляли 6% неугаданых фрагментов
Потерянные 6% фрагментов представляют собой неполные фрагменты или фрагменты, в которые попало лишнее слово или цифра.
Например, необходимо было выбрать фрагмент «3300 000 (три миллиона триста тысяч ) руб.», а нейронная сеть выбрала фрагмент «3300 000 (три миллиона триста тысяч ) руб. 2.2».
Обычная регулярка наверное будет быстрее и её так же можно дописать для 6% нераспознанных.
Перед нами стояла задача попробовать решить типовую задачу, решаемую регулярным выражением, с помощью нейронной сети. Была написана программа, которая отбирает необходимые фрагменты с помощью регулярного выражения, но и она не давала 100% точности.
При больших объемах данных нельзя сказать с уверенностью, что регулярное выражение будет работать быстрее, чем нейронная сеть.
Замечательно конечно, но кого вы тут собирались научить ? Если новичков то им будет не понятен смысл манипуляций как эта: "Следующим шагом нужно представить «слова» в виде чисел..."; а если старичков, то им будет не интересно т.к. этот материал в более подробных формах существует в изобилии. Извините если обижу, но именно по этой причине людей минусуют на хабрах, т.к. ничего нового не рассказывают.
Лучше бы для новичков разжевали разбив на микрозадачи и предоставив подробные значения до и после манипуляций.
При написании данной статьи не стояла цель обучить кого-то. Цель была рассказать, как можно подготовить данные для дальнейшей работы, и поделиться своим опытом. Простейшие преобразования данных были опущены при написании статьи, так как с ними может разобраться каждый. Мы учтем Ваш комментарий касательно подробности изложения информации на будущее.