Известная утилита дистрибутивной семантики Word2Vec демонстрирует удивительные результаты и стабильно обеспечивает использующих её специалистов призовыми местами на конкурсах машинной лингвистики. Преимущество утилиты, как впрочем, и её аналогов – Glove и AdaGram, состоит в дешевизне процесса обучения и подготовки обучающих текстов. Но есть и недостатки – представление слов в виде векторов хорошо работает на словах, удовлетворительно на словосочетаниях, так-себе на фразах и вообще никак – на длинных текстах.

В данной статье предлагается к обсуждению подход, позволяющий представить текст любой длины в виде вектора, позволяющий проводить с текстами операции сравнения (вычисления дистанции), сложения и вычитания.

От векторных репрезентаций к семантическому вектору



Векторные репрезентации слов, полученных в результате работы Word2Vec, обладают следующим интересным свойством – смысл имеют только расстояния между векторами, а не сами вектора. Другими словами – разложить саму векторную репрезентацию конкретного слова на составляющие и изучить её представляется трудноразрешимой задачей. В первую очередь потому, что процесс обучения стартует с неких случайных начальных векторов и более того, сам процесс обучения случаен. Его случайность связана с принципом стохастического обучения, когда параллельно выполняющиеся потоки обучения не синхронизируют вносимые изменения друг с другом, реализуя в чистом виде гонку данных. Но качества обучения эта гонка существенно не снижает, тогда как скорость обучения увеличивается весьма заметно. Именно благодаря случайной структуре алгоритма и данных – векторная репрезентация слова не раскладываема на осмысленные составляющие и может использоваться только в целом.

Негативным эффектом указанного свойства векторной репрезентации является быстрая деградация векторов при операциях над ними. Сложение векторов двух слов обычно демонстрирует то общее, что есть между этими словами (если слова действительно связаны в реальном мире), но попытка увеличить количество слагаемых очень быстро приводит к потере какого-либо практически ценного результата. Сложить слова одной фразы – ещё можно, нескольких фраз – уже нет. Необходим иной подход.

С точки зрения обывательской логики, как можно описать какой-либо текст? Попытаться указать его тематику, может быть – сказать пару слов о стиле. Тексты, посвящённые автомобилям, очевидно, будут содержать достаточно большое количество слов “автомобиль” и близких к нему, могут содержать слово “спорт”, названия автомобильных марок и так далее. С другой стороны, тексты на другую тематику будут содержать подобных слов намного меньше или не содержать вовсе. Таким образом, перечислив достаточное количество возможных тематик текста, мы можем посчитать статистику наличия в тексте соответствующих каждой тематике слов и получить семантический вектор текста – вектор, каждый элемент которого обозначает отношение данного текста к тематике, кодированной этим элементом.

Стиль текста, в свою очередь тоже определяется статистическими методами – это характерные для автора слова паразиты и речевые обороты, специфика начала фраз и расстановки знаков пунктуации. Поскольку мы при обучении разделяем заглавные и прописные буквы и не убираем из текста знаки пунктуации, то словарь Word2Vec полон словами типа “текста,” – именно так, с запятой. И именно такие слова и могут использоваться для выделения авторского стиля. Разумеется, для устойчивого выделения стиля необходимы действительно громадные текстовые корпуса, или, как минимум, очень оригинальный авторский стиль, но, тем не менее, отличить газетную заметку от записи на форуме или твита несложно.

Таким образом, для построения семантического вектора текста необходимо описать достаточное количество устойчивых кластеров, отражающих тематику и стиль текста. В самой утилите Word2Vec есть встроенный кластеризатор на основе kMeans, им и воспользуемся. Кластеризатор поделит все слова из словаря на заданное число кластеров, и, если количество кластеров будет достаточно большим, можно ожидать, что каждый кластер будет указывать на достаточно узкую тематику текста, а точнее – на узкий признак тематики или стиля. В своей задаче я использовал две тысячи кластеров. То есть – длина семантического вектора текста составляет две тысячи элементов, и каждый элемент этого вектора может быть объяснён через соответствующие данному кластеру слова.

Относительная плотность слов из каждого кластера в исследуемом тексте хорошо описывает текст. Разумеется, каждое конкретное слово имеет отношение ко многим кластерам, к каким-то больше, к каким-то меньше. Поэтому, в первую очередь необходимо вычислить семантический вектор слова – как вектор, описывающий расстояние от слова до центра соответствующего кластера в векторном пространстве Word2Vec. После чего, складывая семантические вектора отдельных слов, составляющих текст, мы получаем семантический вектор всего текста.

Описанный алгоритм, основанный на вычислении относительной частоты слов, задающих соответствующие тематики, хорош тем, что подходит для текстов любой длины. От одного слова и до бесконечности. При этом, как мы знаем, трудно найти достаточно длинный текст одной тематики, часто тематика текста изменяется от его начала к концу. Короткий текст, или сообщение, наоборот, не может охватить множество тем именно за счёт своей кратости. Как итог, получается, что семантический вектор длинного текста отличается признаками нескольких тем от короткого текста, в которых признаков тем намного меньше, но они представлены намного сильнее. Длина текста явно не учитывается, тем не менее алгоритм надёжно разводит короткие и длинные тексты в векторном пространстве.

Как использовать семантический вектор текста?


Поскольку каждому тексту поставлен соответствие вектор в семантическом пространстве, мы можем вычислить расстояние между любыми двумя текстами как косинусную меру между ними. Имея расстояние между текстами, можно использовать алгоритм kMeans для проведения кластеризации или классификации. Только в этот раз – уже в векторном пространстве текстов, а не отдельных слов. Например, если у нас стоит задача отфильтровать из потока текстов (новости, форумы, твиты и т.д.) только имеющие интересующую нас тематику, можно подготовить базу заранее размеченных текстов, а для каждого исследуемого текста вычислять класс, к которому он тяготеет более всего (максимум усреднённой косинусной меры по нескольким лучшим вхождениям каждого класса – kMeans в чистом виде).

Указанным способом была успешно решена довольно сложная задача классификации текстов на большое (несколько сотен) число классов, при значительном различии текстов по стилю (разные источники, длина, даже языки сообщений) и при наличии тематической связанности классов (один текст часто может иметь отношение к нескольким классам). К сожалению, конкретные цифры полученных результатов находятся под NDA, но общая результативность подхода следующая – 90% точности на 9% классов, 99% точности на 44% классов, 76% точности на 3% классов. Эти результаты следует интерпретировать следующим образом – классификатор сортирует все несколько сотен целевых классов по оценке степени соответствия текста данному классу, после чего, если мы возьмём топ 3% классов, то целевой класс окажется в этом списке с 76% вероятностью, а на 9% классов вероятность уже превысит 90%. Без преувеличения, это удивительный по силе результат, имеющий большую практическую пользу для заказчика.

Более подробный доклад с детальным описанием алгоритма, формулами, графиком и результатами я приглашаю вас послушать на ближайшем Диалоге.

Как ещё использовать семантический вектор?

Семантический вектор текста, как уже упоминалось, состоит из осмысляемых (никто не будет осмыслять все две тысячи элементов вектора, но это возможно) элементов. Да, они не являются независимыми, но, тем не менее, являются готовым к использованию вектором признаков, который можно загрузить в ваш любимый универсальный классификатор – SVM, деревья или глубокие сетки.

Выводы


Метод превращения текста произвольной длины в вектор с опорой на векторные репрезентации слов Word2Vec действительно работает и даёт хорошие результаты в задачах кластеризации и классификации текстов. Признаки текста, кодируемые семантическим вектором, не деградируют с увеличением длины текста, а наоборот – позволяют более тонко дифференцировать длинные тексты друг от друга и сильно разводят тексты с существенно разной длиной. Общий объём вычислений скромный – один месяц на нормальном сервере.

С радостью отвечу на ваши вопросы в комментариях.

Комментарии (4)


  1. zodiak
    20.02.2016 02:05
    +2

    По вашему алгоритму есть пара вопросов. Вот как его понял/не понял я:

    1. Бьем словарь W2V на кластеры. Длина вектора для текста = количество кластеров.
    2. Для каждого кластера вычисляем центр // mean(всех слов кластера) или как?
    3. Вычисляем семантический вектор каждого слова в тексте // Какая операция применяется к слову и центру кластера в котором оно находится?
    4. Складываем семантические вектора всех слов текста // Обычное суммирование векторов?

    Буду благодарен если ответите на вопросы после "//"


    1. ServPonomarev
      20.02.2016 07:53
      +1

      Приветствую.

      Да, бьём весь словарь на кластеры встроенными средствами. Да, вычисляем центр кластера усреднением всех слов, принадлежащих кластеру. Потом вычисляем косинусную меру от каждого слова до центра каждого кластера. Обнуляем все значения косинусных мер ниже заданного порога. Складываем вектора всех слов текста, осредняем. По всем текстам вычисляем мат. ожидание и СКО элементов семантического вектора. Из вектора текста вычитаем вектор мат. ожиданий, делим на СКО и нормируем к единице. Такие вектора можно сравнивать между собой косинусной мерой. Можно обойтись и без мат. ожидания и СКО, но тогда результат будет смазанным.


  1. elingur
    20.02.2016 11:00

    Интересный метод. Я правильно понимаю, что эту технологию получения весов можно использовать взамен разных TFiDF, дабы не мучиться с разряженными матрицами и большими объемами? В том смысле, что для получения семантического вектора, представляющего кластер, разумнее использовать что-то типа TFiDF, но при больших объемах этот метод загибается.
    Классификация скорее всего будет хорошо работать. А вот кластеризация — не уверен: при таком подходе привязка к начальному разбиению на кластеры (точнее выбору количества кластеров) сильно будет влиять на результат. Хотя это болезнь практически всех методов кластеризации.


    1. ServPonomarev
      20.02.2016 11:28

      Если не брать в расчёт всякие нюансы, но Word2Vec — это и есть TFiDF + снижение размерности. Так что да, результаты при использовании TFiDF и Word2Vec должны быть приблизительно одинаковыми, чего нельзя сказать о потребных вычислительных ресурсах. К примеру, если использовать две тысячи элементов вектора на слово, то на словаре в 4-ре миллиона слов, по 8 Кб на слово, имеем уже 32 Гб таблицу векторов. К счастью, её нет необходимости держать в памяти, более того — обращаться к ней часто тоже не требуется — сначала считаются частоты слов в тексте, а потом частота домножается на семантический вектор один раз, в конце обработки всего текста.

      Выбранное количество кластеров — краеугольный вопрос. Малое число кластеров даст в большей степени разделение при общеупотребительной лексике (худ. литература, например, или новости) а большое число кластеров необходимо, если в тексте присутствуют термины, марки, коды и прочие относительно редко встречающиеся слова, но очень важные для как признаки. Именно за счёт того, что кластеров довольно много, и требуется высчитывать отношения слова ко всем кластерам, а не брать для слова только один — его собственный, кластер. В противном случае вектора текстов по многим позициям семантического вектора были-бы ортогональны друг другу и высчитывать между ними дистанцию было-бы бесполезно.