Доброго времени суток всем. Это наш первый пост в блог стартапа «Meanotek», и наверное он будет больше ознакомительного характера. Чтобы не было совсем скучно читать, мы попробуем рассказать историю, о том как одна практическая задача привела нас к созданию полноценной системы «понимания» текста компьютером, и что из этого получилось.
Мысль научить компьютер общаться на человеческом языке у меня появилась еще в школе, когда у меня дома был один из первых советских аналогов IBM PC, с языком программирования GW BASIC. Понятно, что далеко эта задумка в то время не ушла, потом ее заслонили другие более важные дела, но совершенно неожиданно она всплыла вновь спустя много лет, уже в связи с конкретной потребностью.
Собственно идея пришла в голову во время работы над другим проектом — сайтом поиска отзывов reviewdot.ru. Идея reviewdot.ru была в следующем — пользователь вводит запрос, например «зеркальный фотоаппарат для начинающих» — и получает список ссылок на отзывы в интернете, которые касаются именно этого вопроса. Или к примеру, чтобы по запросу «что ломается в стиральной машине Indesit?” появлялись ссылки на отзыв пользователей марки Indesit, у которых что-то сломалось. Вопрос ценности данного ресурса для людей пока оставим за скобками, и поговорим немного о технической стороне реализации.
Ясно, что чтобы искать отзывы в интернете, надо сначала эти отзывы выделить с разных сайтов. Отзывы встречаются на очень разных сайтах (сайты отзовики, интернет-магазины, индивидуальные блоги и т. п.). Классический подход к данной проблеме — загружаем страницы, выделяем нужные блоки из разметки с помощью библиотеки парсера-HTML и заносим в базу данных. Однако, выяснилось, что нашими ограниченными ресурсами так много не сделать (мы работали вдвоем в свободное от работы и отдыха время). Потому как во-первых, добавление каждого нового сайта связано с необходимостью анализа его структуры вручную и прописывания правил для извлечения данных, что не всегда бывает тривиально, даже с помощью HTML-парсера и Xpath запросов. Во-вторых, сайты имеют тенденцию менять структуру. Когда работа идет с 5-6 сайтами это еще ничего, ведь капитальный редизайн случается не так часто. Но если счет источников идет на тысячи… короче, объем усилий, необходимый на поддержку решения в работоспособном состоянии растет пропорционально числу источников. А есть еще и категории товаров, которые на каждом сайте называются по-разному, и надо их сопоставлять, и поддерживать какое-то единое дерево категорий… Короче, объем тупого монотонного труда быстро и монотонно возрастает, что делает задачу для нас неподъемной.
Поэтому, помучившись некоторое время, мы плюнули и забили на проект, решили пойти другим путем и научить компьютер самостоятельно находить отзывы на любой веб-странице. Стандартных средств для этого не нашлось и после некоторых усилий мы сделали простой алгоритм, выделяющий текстовые блоки из веб-страниц и классифицирующий их на два типа — отзыв/не отзыв. Таким образом, программа приобрела рудиментарный интеллект, а мы избавились от зависимости затрат на поддержание системы от числа источников данных. Сколько сайтов-источников хотим, столько и добавляем, и трудозатраты при этом остаются константой. Правда при этом произошла некоторая потеря в качестве, т. к. около 15% текстов которые попадали в базу не были отзывами, и еще какой-то процент отзывов не находился вообще, но эти недостатки не шли ни в какое сравнение с достигнутой экономией усилий.
Из чего мы сделали следующие выводы:
- Элементы «понимания» компьютером текстов могут пригодится в самых разных и неожиданных местах, даже там, где вроде бы можно обойтись
- В условиях ограниченных ресурсов, лучше иметь одно универсальное решение, чем много специализированных
Вторая мысль достаточно тривиальна, но первое наблюдение нам показалось интересным. Мы добавили в программу автоматический «извлекатель» названий товаров и «присваиватель» категорий, так что теперь система сама могла «открывать» новые товары и категории товаров. Со временем таким образом «открылось» несколько сот категорий, в том числе такие, о которых мы вначале и не думали. Например, программа обнаружила, что «отель» это тоже в каком-то смысле товар, и начала добавлять в базу разные отели и отзывы про них, чего изначально вообще не предполагалось. В результате знания не только сами извлекаются, но и в определенной степени сами приобретают определенную структуру.
Это снова навело на мысль, что практическая ценность компьютерных анализаторов текстов недооценена. Ну конечно, сейчас есть всевозможные API анализа текстов, но число задач которые можно ими решить строго ограничено, обычно это извлечение каких-то заранее определенных сущностей, вроде названий компаний, товаров, имен людей, и оценка тональности (положительный/отрицательный/нейтральный). Это имеет очевидные практические приложения, но потенциально список того, что можно сделать намного больше.
К примеру:
- Голосовой интерфейс на естественном языке в каждое мобильное приложение (а не только для избранных)
- Новые виды приложений, отвечающие на вопросы (тот же подбор подходящего товара по требованиям на естественном языке)
- Анализ сообщений электронной почты, для выявления частых проблем обращающихся, с возможностью автоматического ответа с решением типовых проблем
Готовые API анализа текстов, как правило, не умеют «открывать» новые концепции в заданной предметной области и использовать их для улучшения качества анализа. Вообще до опыта с reviewdot, мы думали, что подобные самосовершенствующиеся системы недостаточно хорошо работают, чтобы быть практически полезными, но тут мы убедились совсем в обратном.
А это потенциально сотни специализированных задач, которые теоретически возможно сделать, но на практике еще не охвачены. Решать каждую прикладную задачу самостоятельно мы конечно не можем, и после некоторых размышлений родилась такая вот идея бизнес-схемы:
Клиент (часто разработчик ПО) имеет задачу или идею нового приложения → он обращается к нам, мы бесплатно делаем поддержку нужной именно ему функции и предоставляем ее через web-API или оффлайн → если приложение имеет успех, то разработчик получает доход и оплачивает из него доступ к веб-API.
Понятно, что тут тоже много трудностей. Например, чтобы система масштабировалась на новые задачи, надо сделать так, чтобы не нужно было писать отдельное решение на каждого пользователя. Гораздо лучше иметь ядро, которое потенциально умеет делать все — одна интеллектуальная архитектура на все задачи, которая просто обучается на некотором количестве тестовых примеров. Некий прототип у нас в результате работы на reviewdot уже имелся — дело в том, что нам было лень использовать стандартные методы обработки языка — всевозможные определители частей речи, морфологические анализаторы, синтаксические парсеры, строящие деревья, и тому подобные средства с (полу)-ручным подбором признаков для классификации требовали много монотонного труда, а это оказалось нашим слабым местом (см.выше). Поэтому изучив литературу мы обнаружили алгоритмы анализа текстов с помощью нейронных сетей, которые работали несколько хуже, но зато, написав одно ядро, можно было применять его почти везде, а когда оно куда-то не подходило мы искали способ расширить/изменить его, чтобы все-таки использовать. Такой подход порождал иногда жуткие решения, но тем не менее работал.
В осенью 2014 года мы обнаружили в сети открытое тестирование анализа систем анализа тональности на русском языке при конференции «Диалог» и решили принять в нем участие, чтобы проверить насколько наш «кустарный» подход к анализу языка в сравнении с профессиональными решениями. Это привело к нескольким циклам усовершенствований, и бессонных ночей (что есть тема отдельной статьи), но в итоге нам не только удалось подтвердить универсальность, но и занять несколько первых и вторых мест по разным дорожкам, что сделало нашу систему одной из лучших и по точности результатов.
Таким образом, идея наконец-то созрела, и мы начали работать, пока в тестовом режиме, выискивая людей с интересными задачами или проектами приложений, и предлагая им сделать анализатор. Пока в разработке только два таких проекта, но есть надежда, что появятся и другие.
Автор: Durham