LSA-скрытый семантический анализ - как его закодировать на PHP?

Я хотел бы реализовать скрытый семантический анализ (LSA) в PHP, чтобы узнать темы/теги для текстов.

вот что я думаю. это правильно? Как я могу кодировать его на PHP? Как определить, какие слова выбрать?

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

  1. извлечь все слова из данного текст.
  2. вес слова / фразы, например, с tf-idf. Если взвешивание слишком сложное, просто возьмите количество вхождений.
  3. создайте матрицу: столбцы-это некоторые документы из базы данных (чем больше, тем лучше?), строки-это все уникальные слова, значения-это числа вхождений или вес.
  4. выполните разложение сингулярного значения (SVD).
  5. используйте значения в матрице S (SVD) для уменьшения размера (как?).

надеюсь, вы сможете мне помочь. Большое спасибо заранее!

4 ответов


ссылки LSA:

вот полный алгоритм. Если у вас есть SVD, вы большую часть пути туда. Вышеприведенные документы объясняют это лучше, чем я.

предположения:

  • ваша функция SVD даст сингулярные значения и сингулярные векторы в порядке убывания. если нет, то вы придется больше заниматься акробатикой.

M: матрица корпуса, w (слова) по D (документы) (W строк, D столбцов). Это могут быть необработанные графы или tfidf или что-то еще. Стоп-слова могут быть или не могут быть устранены, и может произойти stemming (Ландауэр говорит держать стоп-слова и не stem, но да tfidf).

U,Sigma,V = singular_value_decomposition(M)

U:  w x w
Sigma:  min(w,d) length vector, or w * d matrix with diagonal filled in the first min(w,d) spots with the singular values
V:  d x d matrix

Thus U * Sigma * V = M  
#  you might have to do some transposes depending on how your SVD code 
#  returns U and V.  verify this so that you don't go crazy :)

затем reductionality.... фактическая статья LSA предлагает хорошее приближение для базиса, чтобы сохранить достаточное количество векторов, так что их сингулярные значения более 50% от общего числа сингулярных значений.

более succintly... (псевдокод)

Let s1 = sum(Sigma).  
total = 0
for ii in range(len(Sigma)):
    val = Sigma[ii]
    total += val
    if total > .5 * s1:
        return ii

это вернет ранг нового базиса,который был min(d, w) раньше, и теперь мы приблизимся к {ii}.

(здесь, ' - > prime, не переносить)

мы создаем новые матрицы: U', Sigma', V', с размерами w x ii, ii x ii и ii x d.

в этом суть алгоритма LSA.

эта результирующая матрица U' * Сигма "* V "может использоваться для поиска "улучшенного" косинусного сходства, или вы можете выбрать верхние 3 слова для каждого документа в нем, например. Является ли это чем-то большим, чем просто tf-idf, является предметом некоторых дебатов.

для меня LSA плохо работает в реальных наборах данных из-за полисемии и наборов данных со слишком большим количеством тем. Это математический / вероятностный базис является необоснованным (он предполагает нормальные (Гауссовские) распределения, которые не имеют смысла для подсчета слов).

ваш пробег определенно будет отличаться.

пометка с помощью LSA (один метод!)

  1. построить размерно уменьшенные матрицы U 'Sigma' V ' с использованием SVD и эвристической редукции

  2. вручную просмотрите матрицу U и придумайте термины, описывающие каждую "тему". Например, если самые большие части этого вектора были "Бронкс, Янки, Манхэттен", то "Нью-Йорк" может быть хорошим термином для него. Храните их в ассоциативном массиве или списке. Этот шаг должен быть разумным, так как число векторов будет конечным.

  3. предполагая, что у вас есть вектор (v1) слов для документа, то v1 * t(U') даст самые сильные "темы" для этого документа. Выберите 3 самых высоких, затем дайте их "темы", как вычислено на предыдущем шаге.


этот ответ не напрямую с плакатами' вопрос, но до мета вопрос о том, как autotag новостей. В OP упоминается распознавание именованных сущностей, но я считаю, что они означают нечто большее по линии автотегирования. Если они действительно означают NER, то этот ответ-фигня:)

учитывая эти ограничения (600 элементов / день, 100-200 символов / элемент) с расходящимися источниками, вот несколько вариантов тегов:

  1. вручную. Аналитик может легко делайте 600 таких в день, возможно, через пару часов. Что-то вроде механического турка Amazon или заставить пользователей делать это также может быть осуществимо. Имея некоторое количество "рук-тегами", даже если это всего лишь 50 или 100, станет хорошей основой для сравнения независимо от методов автогенерируемые ниже вас.

  2. сокращения Dimentionality, используя LSA, тематические модели (скрытое распределение Дирихле) и тому подобное.... Мне очень не повезло с LSA в реальных наборах данных, и я неудовлетворен своей статистической базой. LDA я нахожу намного лучше, и имеет невероятный список рассылки это имеет лучшее мышление о том, как назначить темы для текстов.

  3. простые эвристики... если у вас есть актуальные новости, то использовать структуру новости. Сосредоточьтесь на первом предложении, выбросьте все общие слова (стоп-слова) и выберите лучшие 3 существительные из первых двух предложений. Или, черт возьми, возьмите все существительные в первое предложение, и посмотрим, к чему это приведет. Если все тексты на английском языке, тогда сделайте часть анализа речи в целом и посмотрите, что это вам даст. Со структурированными элементами, такими как новостные отчеты, LSA и другие независимые от порядка методы (TF-idf) выбрасывают много информации.

удачи!

(Если вам нравится этот ответ, возможно, повторите вопрос, чтобы соответствовать ему)


что все выглядит правильно, до последнего шага. Обычная нотация для SVD заключается в том, что она возвращает три матрицы A = USV*. S-диагональная матрица (то есть все нули от диагонали), которая в этом случае в основном дает меру того, насколько каждое измерение захватывает исходные данные. Числа ("сингулярные значения") будут снижаться, и вы можете искать падение для того, сколько измерений полезно. В противном случае вы захотите просто выбрать произвольное число N для того, сколько измерений брать.

здесь я становлюсь немного нечетким. Координаты терминов (слов) в пространстве с уменьшенной размерностью находятся либо в U, либо в V, я думаю, в зависимости от того, находятся ли они в строках или столбцах входной матрицы. Я думаю, что координаты для слов будут строками U. т. е. первая строка U соответствует первой строке входной матрицы, т. е. первому слову. Затем вы просто берете первые N столбцов этой строки в качестве координаты слова в уменьшенном пространство.

HTH

обновление:

этот процесс до сих пор не скажет вам точно, как выбрать теги. Я никогда не слышал, чтобы кто-то использовал LSI для выбора тегов (алгоритм машинного обучения может быть более подходящим для задачи, например, деревья решений). LSI говорит вам, похожи ли два слова. Это очень далеко от присвоения тегов.

есть две задачи-a) какой набор тегов использовать? b) Как выбрать самые лучшие 3 бирки?. Я нет ощущение того, как LSI поможет вам ответить (a). Вы можете выбрать набор тегов вручную. Но, если вы используете LSI, теги, вероятно, должны быть словами, которые встречаются в документах. Затем для (b) вы хотите выбрать теги, которые ближе всего к словам, найденным в документе. Вы можете поэкспериментировать с несколькими способами реализации этого. Выберите три тега, которые ближе всего к любой word в документе, где близость измеряется косинусным сходством (см. Википедию) между координата тега (его строка в U) и координата слова (его строка в U).


существует дополнительный поток SO на опасности делать это все в PHP на текст ссылки.

в частности, есть ссылка на эту статью на Скрытое Семантическое Отображение, который описывает, как получить результирующие "темы" для текста.