LSA - скрытый семантический анализ - как его кодировать в PHP? - PullRequest
9 голосов
/ 19 июня 2009

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

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

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

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

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

Ответы [ 4 ]

7 голосов
/ 24 июня 2009

LSA ссылки:

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

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

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

M : матрица корпуса, w (слова) на d (документы) (w строк, d столбцов). Это могут быть необработанные значения, или tfidf, или что-то еще. Стоп-слова могут или не могут быть устранены, и может произойти остановка (Ландауэр говорит, что держите стоп-слова и не ставьте, но да, 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 :)

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

Более кратко ... (псевдокод)

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}.

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

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

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

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

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

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

Пометка с использованием LSA (один метод!)

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

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

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

1 голос
/ 23 июня 2009

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

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

  1. От руки. Аналитик может легко выполнить 600 таких операций в день, возможно, за пару часов. Возможно, что-то вроде «Механического турка» Amazon или заставить пользователей делать это. Наличие некоторого числа «помеченных вручную», даже если это всего лишь 50 или 100, будет хорошей основой для сравнения того, что вам могут дать автоматически сгенерированные ниже методы.

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

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

Удачи!

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

0 голосов
/ 23 июня 2009

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

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

0 голосов
/ 20 июня 2009

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

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

НТН

Обновление:

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

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

...