Пирожки в Go

В продолжение эпопеи с дистрибутивно-семантическими пирожками (и в погоне за модными тенденциями) решил переписать веб-сервис с лапидарного Питона на прогрессивный Go. Заодно был вынужден перенести и всю «интеллектуальную» часть (благо, не бином Ньютона). Сделать это оказалось куда проще и приятней, чем предполагал в начале. Впрочем, на медово-синтаксическом празднике жизни не обошлось без ложки дёгтя — самая быстрая гошная «числодробилка», какую смог найти (mat из gonum) таки уступила по скорости питоновской связке numba + numpy.

Чтобы осуществить задуманное, надо было:

  • загрузить word2vec модель из бинарника ;
  • прочитать модель с пирожками;
  • подключить морфологический анализатор ;
  • пристегнуть простенький фронтэнд к нехитрому бэкеэнду.

 

Загрузка word2vec модели

Здесь всё просто — читаем из бинарника словарь и вектора к нему с попутной нормализацией векторов и формированием отображения (map) слово — индекс вектора. Отображение даёт быстрое вытаскивание вектора по слову. Нормализация экономит время при вычислении косинусной близости — сравнение слов сводится к скалярному произведению, а сравнение «мешков» (bag of words) к умножению матриц.

Код

 

Чтение «поэтической» модели

Тут ещё проще — вчитать заблаговременно созданный в Питоне JSON-файл в структуры и слайсы Go — легче лёгкого, главное не забывать про заглавные буквы в именах полей. А чтобы всё просчитывалось быстрей, штампуем матрицы из мешков-пирожков не отходя от кассы.

Код

 

Морфологический анализатор

Мир не без добрых людей — нашёлся хороший человек, который перевёл pymorphy2 на Go. Пришлось, правда, подрихтовать пару строк в исходниках, ибо устанавливать морфологические словари пакетным менеджером питона, а потом их же через питон искать — идея, мягко выражаясь, не комильфо. От греха подальше закинул словари (вместе с подрихтованным анализатором) к себе в проект.

«Интеллектуальная» часть

Токенизатор — осуществляет перевод слов в нормальную форму (лемматизация), добавляет к ним соответствующие (word2vec модели) грамматические суффкисы (NOUN, VERB, ADJ и т.п.) и отсеивает стоп-слова (всякие местоимения, предлоги, частицы).

Код

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

Код

 

Веб-сервис

Для реализации веб-части воспользовался пакетом gin-gonic — роутер, статика, CORS — все дела.

Проект на Github