Pregunta

Me gustaría implementar el Análisis Semántico Latente (LSA) en PHP para encontrar temas / etiquetas para textos.

Esto es lo que creo que tengo que hacer. ¿Es esto correcto? ¿Cómo puedo codificarlo en PHP? ¿Cómo determino qué palabras elegir?

No quiero usar ninguna biblioteca externa. Ya tengo una implementación para la Descomposición de valor singular (SVD) .

  1. Extrae todas las palabras del texto dado.
  2. Ponderar las palabras / frases, p. ej. con tf – idf . Si la ponderación es demasiado compleja, solo tome el número de ocurrencias.
  3. Cree una matriz: las columnas son algunos documentos de la base de datos (¿cuanto más, mejor?), las filas son todas palabras únicas, los valores son el número de ocurrencias o el peso.
  4. Realice la descomposición del valor singular (SVD).
  5. Use los valores en la matriz S (SVD) para hacer la reducción de dimensión (¿cómo?).

Espero que me puedan ayudar. ¡Muchas gracias de antemano!

¿Fue útil?

Solución

Enlaces LSA:

Aquí está el algoritmo completo. Si tienes SVD, estás casi todo el camino. Los documentos anteriores lo explican mejor que yo.

Suposiciones:

  • su función SVD le dará los valores singulares y los vectores singulares en orden descendente. Si no, debe hacer más acrobacias.

M : matriz de corpus, w (palabras) por d (documentos) (w filas, d columnas). Estos pueden ser recuentos sin procesar, o tfidf o lo que sea. Las palabras vacías pueden eliminarse o no, y la derivación puede suceder (Landauer dice que mantenga las palabras vacías y no contenga, pero sí a 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 :)

Entonces, la reduccionidad ... el documento LSA real sugiere que una buena aproximación para la base es mantener suficientes vectores para que sus valores singulares sean más del 50% del total de los valores singulares.

Más sucintamente ... (pseudocódigo)

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

Esto devolverá el rango de la nueva base, que antes era min (d, w), y ahora nos aproximaremos con {ii}.

(aquí, '- > prime, no transponer)

Creamos nuevas matrices: U ', Sigma', V ', con tamaños w x ii, ii x ii y ii x d.

Esa es la esencia del algoritmo LSA.

Esta matriz resultante U '* Sigma' * V 'puede usarse para una búsqueda de similitud de coseno' mejorada ', o puede elegir las 3 palabras principales para cada documento, por ejemplo. Si esto produce más que un simple tf-idf es un tema de debate.

Para mí, LSA funciona mal en los conjuntos de datos del mundo real debido a la polisemia, y los conjuntos de datos con demasiados temas. Su base matemática / probabilística no es sólida (supone distribuciones normales-ish (gaussianas), lo que no tiene sentido para el recuento de palabras).

Su millaje definitivamente variará.

Etiquetado usando LSA (¡un método!)

  1. Construya las matrices U 'Sigma' V 'reducidas dimensionalmente usando SVD y una heurística de reducción

  2. A mano, mire por encima de la matriz U 'y encuentre términos que describan cada "tema". Por ejemplo, si las partes más grandes de ese vector fueran "Bronx, Yankees, Manhattan". entonces " Ciudad de Nueva York " podría ser un buen término para ello. Guárdelos en una matriz asociativa o lista. Este paso debe ser razonable ya que el número de vectores será finito.

  3. Suponiendo que tiene un vector (v1) de palabras para un documento, entonces v1 * t (U ') le dará los' temas 'más fuertes para ese documento. Seleccione los 3 más altos, luego dé sus "temas". como se calculó en el paso anterior.

Otros consejos

Esta respuesta no es directamente a la pregunta de los carteles, sino a la meta pregunta de cómo etiquetar automáticamente las noticias. El OP menciona el reconocimiento de entidad con nombre, pero creo que significan algo más en la línea de etiquetado automático. Si realmente significan NER, entonces esta respuesta es una tontería :)

Dadas estas restricciones (600 artículos / día, 100-200 caracteres / artículo) con fuentes divergentes, aquí hay algunas opciones de etiquetado:

  1. A mano. Un analista podría hacer fácilmente 600 de estos por día, probablemente en un par de horas. Algo como Mechanical Turk de Amazon, o hacer que los usuarios lo hagan, también podría ser factible. Tener un cierto número de `` etiquetado a mano '', incluso si son solo 50 o 100, será una buena base para comparar los métodos autogenerados a continuación.

  2. Reducciones de dimensionalidad, usando LSA, Modelos de tema (asignación de Dirichlet latente) y similares ... He tenido muy mala suerte con LSA en conjuntos de datos del mundo real y no estoy satisfecho con su base estadística LDA me parece mucho mejor, y tiene una increíble lista de correo que tiene Las mejores ideas sobre cómo asignar temas a los textos.

  3. Heurística simple ... si tiene noticias reales, entonces explote la estructura de las noticias . Concéntrese en la primera oración, deseche todas las palabras comunes (palabras de detención) y seleccione los mejores 3 sustantivos de las dos primeras oraciones. O diablos, toma todos los sustantivos en la primera oración y mira a dónde te lleva eso. Si todos los textos están en inglés, haga parte del análisis del discurso en todo el shebang y vea qué le pasa. Con elementos estructurados, como informes de noticias, LSA y otros métodos independientes del orden (tf-idf) arrojan mucha información.

¡Buena suerte!

(si le gusta esta respuesta, tal vez vuelva a plantear la pregunta para que encaje)

Todo parece correcto, hasta el último paso. La notación habitual para SVD es que devuelve tres matrices A = USV *. S es una matriz diagonal (es decir, todo cero fuera de la diagonal) que, en este caso, básicamente da una medida de cuánto captura cada dimensión de los datos originales. Los números (" valores singulares ") bajarán, y puede buscar una caída de cuántas dimensiones son útiles. De lo contrario, solo tendrá que elegir un número arbitrario N para cuántas dimensiones tomar.

Aquí me pongo un poco borroso. Las coordenadas de los términos (palabras) en el espacio de dimensión reducida están en U o V, creo que dependen de si están en las filas o columnas de la matriz de entrada. Por otro lado, creo que las coordenadas de las palabras serán las filas de U, es decir, la primera fila de U corresponde a la primera fila de la matriz de entrada, es decir, la primera palabra. Luego simplemente toma las primeras N columnas de esa fila como la coordenada de la palabra en el espacio reducido.

HTH

Actualización:

Este proceso hasta ahora no le dice exactamente cómo seleccionar las etiquetas. Nunca he oído hablar de alguien que use LSI para elegir etiquetas (un algoritmo de aprendizaje automático podría ser más adecuado para la tarea, como, por ejemplo, los árboles de decisión). LSI te dice si dos palabras son similares. Eso está muy lejos de asignar etiquetas.

Hay dos tareas: a) ¿cuál es el conjunto de etiquetas a utilizar? b) ¿Cómo elegir las mejores tres etiquetas? No tengo mucho sentido de cómo LSI te ayudará a responder (a). Puede elegir el conjunto de etiquetas a mano. Pero, si está utilizando LSI, las etiquetas probablemente deberían ser palabras que aparecen en los documentos. Luego, para (b), desea seleccionar las etiquetas más cercanas a las palabras que se encuentran en el documento. Podrías experimentar con algunas formas de implementar eso. Elija las tres etiquetas más cercanas a cualquier palabra en el documento, donde la cercanía se mide por la similitud del coseno (consulte Wikipedia) entre la coordenada de la etiqueta (su fila en U) y la coordenada de la palabra (su fila en U).

Hay un hilo SO adicional sobre los peligros de hacer todo esto en PHP en enlace texto .

Específicamente, hay un enlace a este documento sobre Mapeo semántico latente , que describe cómo obtener los "temas" resultantes para un texto

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top