Как я за нейронными сетями для C# ходил
Неожиданное задание
Однажды, когда я получал первое высшее образование, у нас был предмет про искусственный интеллект и нейронные сети. Тогда я не стал делать выбор в сторону полноценного Data Science, а пошёл в backend разработку, где дошёл до уровня архитектора (Юду) и руководителя онлайн курсов (ОТУС). Но тема с ИИ меня явно зацепила и время от времени я слушал аудиокниги Айзека Азимова про роботов и искусственный интеллект, читал статьи, смотрел записи лекций американских университетов и даже проходил курсы, но применить эти знания на практике всё никак не получалось.
И тут неожиданно на работе для нового функционала появляется необходимость понимать положительный отзыв заказчик исполнителю написал или отрицательный. В YouDo, как и во многих крупных компаниях, есть специальный отдел датасаентистов, чьи нейронные сети определяют рекомендованную цену для задания, подбирают наиболее подходящих исполнителей, и так далее. Поэтому я начинаю прекрасно понимать, что если не потороплюсь, то задача уйдёт к ним! Начинаю экстренно разбираться как это реализовать на C#. Выяснил, что pandas, numpy, scikit и прочие популярные библиотеки, которые я использовал на питоне, уже имеют аналоги для шарпа. Но, что больше всего поразило, в экосистеме дотнета есть свой собственный инструмент, который является настоящим сокровищем!
Да это просто Волшебный Инструмент!
Оказывается, в Майкрософт долгое время разрабатывали библиотеку для быстрого обучения нейронных сетей, а три года назад, под названием ML.NET, они открыли её для всех желающих. С её помощью очень быстро создаю программу, которая обучает нейронную сеть и понимаю, что это Любовь. Всего 4 строчки потребовалось, чтобы с нуля создать нейронную сеть и ещё 3 строчки, чтобы прогнать тестовый отзыв через нейронную сеть и вывести на экран результат!
MLContext mlContext = new MLContext();
IDataView data = mlContext.Data.LoadFromTextFile("d:\\Reviews.tsv");
var pipeline = mlContext.Transforms.Text
.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(Review.Text))
.Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression());
ITransformer model = pipeline.Fit(data);
var predictionEngine = mlContext.Model.CreatePredictionEngine(model);
var testReview = new Review { Text = "Всё было отлично!" };
predictionEngine.Predict(testReview).Dump();
После этого я ещё долго не мог прийти в себя. А как же изучение особенностей работы Word2Vec, примеры с King-Queen-Man-Woman, функции обратного распространения ошибки, расчёты количества скрытых слоёв и количества нейронов в этих слоях? С ML.NET это всё становится необязательным. Безусловно, в таком подходе есть и свои минусы, всё же полезно понимать внутреннюю реализацию, но теперь стало возможным создавать нейронные сети и не изучая всего этого. Не нужны также ни сверхкомпьютеры, ни расчёты на видеокартах, всё считается на обычном ЦПУ и работает очень быстро.
А не такой уж он и волшебный…
Звучит слишком хорошо, чтобы оказаться правдой, да? Так и вышло, нейронка, которую я таким образом натренировал, вышла не очень качественной и из 10 отзывов правильно распознавала только 6–7. Но это уже был отличный результат, чтобы с чего-то начать. Дальше я начал разбираться в том, почему могло так произойти и наткнулся на некоторые сложности. Во-первых, информации об использовании ML.NET для работы с текстами на русском языке не нашлось вообще. Во-вторых, часть даже англоязычной документации библиотеки была просто сгенерированной автоматически и не содержала никаких описаний и примеров использования, приходилось разбираться с помощью IntelliSense, исходного кода и метода научного тыка.
Время было потрачено не зря, разобрался, сделал всё, что нужно было и даже больше — дошло до того, что я автоматизировал процесс подбора алгоритма и создания нейронной сети с помощью инструмента AutoML. Но нейронная сеть продолжала работать на не очень хорошем уровне. Пришлось ещё глубже закопаться в исходники, статьи в интернете, даже начал пытаться смотреть значения весов нейронов, понимаю, что бессмысленно, но вдруг удалось бы наткнуться на какую-то закономерность и получить озарение. Я уже почти отчаялся и был готов отдать задачу другому отделу…
Выход из тупика
В этот момент на глаза случайно попалась фраза »sh*t in, sh*t out» и я понял, что возможно, слишком сильно доверял своим исходным данным. Стал их проверять и впрямь, нашлись очень любопытные примеры. Например, некоторые пользователи могли поставить за качество работы исполнителя и все остальные пункты одни пятёрки, а текстом написать настолько разгромный комментарий, что даже мне было стыдно его читать, не говоря уже об исполнителе, которому посчастливилось так не угодить заказчику. Также находились и совсем некорректные, например, состоящие из одних восклицательных знаков.
Обратите внимание на цифры справа, 0 — негативный отзыв, 1 — позитивный отзыв. Не говоря уже о том, что отзыв из одних символов неадекватен, так ещё и в одном случае человек поставил хорошие оценки, а в другом — плохие. К такому ни одна статья и ни один курс меня не готовили. Что поделать, это реальные отзывы и люди порой пишут очень странные вещи. Написал отдельную программу для чистки данных, в очередной раз обучил сеть и наконец-то результаты распознавания стали 8–9/10! Затем убрал из обучающих данных все отзывы от исполнителей (по условиям задачи нужны только отзывы заказчиков) и точность распознавания стала 9–10/10!
Вероятность | Отзыв |
99.9999% | Массaж отличный! Анжeлика — мастер своего дела! Рекомендую |