Domanda

Vorrei implementare l'analisi semantica latente (LSA) in PHP al fine di scoprire argomenti / tag per i testi.

Ecco cosa penso di dover fare. È corretto? Come posso codificarlo in PHP? Come faccio a determinare quali parole scegliere?

Non voglio usare nessuna libreria esterna. Ho già un'implementazione per la decomposizione del valore singolare (SVD) .

  1. Estrai tutte le parole dal testo indicato.
  2. Pondera le parole / frasi, ad es. con tf – idf . Se la ponderazione è troppo complessa, basta prendere il numero di occorrenze.
  3. Costruisci una matrice: le colonne sono alcuni documenti del database (più meglio è?), le righe sono tutte parole uniche, i valori sono il numero di occorrenze o il peso.
  4. Esegui la decomposizione del valore singolare (SVD).
  5. Utilizzare i valori nella matrice S (SVD) per eseguire la riduzione dimensionale (come?).

Spero che tu mi possa aiutare. Grazie mille in anticipo!

È stato utile?

Soluzione

Collegamenti LSA:

Ecco l'algoritmo completo. Se hai SVD, sei quasi arrivato. I documenti sopra spiegano meglio di me.

Ipotesi:

  • la tua funzione SVD fornirà i valori e i vettori singolari in ordine decrescente. Altrimenti, devi fare più acrobazie.

M : matrice corpus, w (parole) per d (documenti) (w righe, d colonne). Questi possono essere conteggi grezzi, o tfidf o altro. Le parole d'ordine possono essere eliminate o meno, e può verificarsi la riduzione (Landauer dice di mantenere le parole d'ordine e non arginare, ma 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 :)

Quindi la riduzione ... il vero documento LSA suggerisce una buona approssimazione per la base è di mantenere un numero sufficiente di vettori in modo tale che i loro valori singolari siano più del 50% del totale dei valori singolari.

Più succintamente ... (pseudocodice)

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

Questo restituirà il rango della nuova base, che era min (d, w) prima, e ora approssimeremo con {ii}.

(qui, '- > prime, non trasporre)

Creiamo nuove matrici: U ', Sigma', V ', con dimensioni w x ii, ii x ii e ii x d.

Questa è l'essenza dell'algoritmo LSA.

Questa matrice risultante U '* Sigma' * V 'può essere utilizzata per una ricerca di somiglianza del coseno "migliorata", oppure è possibile selezionare le prime 3 parole per ciascun documento in essa contenuto, ad esempio. Se questo sia più di un semplice tf-idf è una questione di dibattito.

Per me, LSA si comporta male nei set di dati del mondo reale a causa della polisemia, e set di dati con troppi argomenti. La sua base matematica / probabilistica non è corretta (presuppone distribuzioni di tipo normale (gaussiano), il che non ha senso per il conteggio delle parole).

Il tuo chilometraggio varierà sicuramente.

Taggare usando LSA (un metodo!)

  1. Costruisci le matrici dimensionalmente ridotte di U 'Sigma' V 'usando SVD e una euristica di riduzione

  2. A mano, guarda sopra la matrice U 'e trova i termini che descrivono ogni "argomento". Ad esempio, se le parti più grandi di quel vettore fossero " Bronx, Yankees, Manhattan, " quindi "New York City" potrebbe essere un buon termine per questo. Conservali in un array o elenco associativo. Questo passaggio dovrebbe essere ragionevole poiché il numero di vettori sarà finito.

  3. Supponendo che tu abbia un vettore (v1) di parole per un documento, quindi v1 * t (U ') fornirà gli' argomenti 'più forti per quel documento. Seleziona il 3 più alto, quindi dai i loro "argomenti". come calcolato nel passaggio precedente.

Altri suggerimenti

Questa risposta non è direttamente alla domanda dei poster, ma alla meta domanda su come autoassegnare le notizie. L'OP menziona il riconoscimento dell'entità denominata, ma credo che significhino qualcosa di più lungo la linea della codifica automatica. Se significano davvero NER, questa risposta è hogwash :)

Dati questi vincoli (600 articoli / giorno, 100-200 caratteri / articolo) con fonti divergenti, ecco alcune opzioni di tagging:

  1. A mano. Un analista potrebbe facilmente eseguirne 600 al giorno, probabilmente in un paio d'ore. Qualcosa come il Turk meccanico di Amazon, o costringere gli utenti a farlo, potrebbe anche essere fattibile. Avere un certo numero di "quotati a mano", anche se sono solo 50 o 100, sarà una buona base per confrontare qualunque metodo autogenerato di seguito ti porti.

  2. Riduzioni della Dimentionalità, usando LSA, Topic-Models (Latent Dirichlet Allocation) e simili .... Ho avuto davvero poca fortuna con LSA su set di dati del mondo reale e non sono soddisfatto del suo base statistica. LDA trovo molto meglio e ho una mailing list incredibile che ha la migliore idea su come assegnare argomenti ai testi.

  3. Euristica semplice ... se disponi di notizie reali, sfrutta la struttura delle notizie . Concentrati sulla prima frase, elimina tutte le parole comuni (parole stop) e seleziona i 3 migliori nomi dalle prime due frasi. O diamine, prendi tutti i nomi nella prima frase e vedi dove ti porta. Se i testi sono tutti in inglese, fai parte dell'analisi del parlato sull'intero shebang e vedi cosa ti prende. Con elementi strutturati, come i notiziari, LSA e altri metodi indipendenti dall'ordine (tf-idf) generano molte informazioni.

Buona fortuna!

(se ti piace questa risposta, forse ricominciare la domanda per adattarla)

Sembra tutto a posto, fino all'ultimo passaggio. La solita notazione per SVD è che restituisce tre matrici A = USV *. S è una matrice diagonale (che significa tutto zero dalla diagonale) che, in questo caso, sostanzialmente fornisce una misura di quanto ogni dimensione acquisisce i dati originali. I numeri (" valori singolari ") scenderanno e puoi cercare un menu a discesa per quante dimensioni sono utili. Altrimenti, ti consigliamo di scegliere semplicemente un numero arbitrario N per quante dimensioni prendere.

Qui divento un po 'sfocato. Le coordinate dei termini (parole) nello spazio di dimensione ridotta sono in U o V, penso a seconda che si trovino nelle righe o nelle colonne della matrice di input. Fuori mano, penso che le coordinate per le parole saranno le righe di U. cioè la prima riga di U corrisponde alla prima riga della matrice di input, cioè la prima parola. Quindi prendi solo le prime N colonne di quella riga come coordinate della parola nello spazio ridotto.

HTH

Aggiornamento:

Questo processo finora non ti dice esattamente come scegliere i tag. Non ho mai sentito parlare di nessuno che utilizza LSI per scegliere i tag (un algoritmo di apprendimento automatico potrebbe essere più adatto al compito, come, ad esempio, alberi delle decisioni). LSI ti dice se due parole sono simili. È molto lontano dall'assegnare i tag.

Esistono due attività: a) quali sono le serie di tag da utilizzare? b) come scegliere i tre tag migliori ?. Non ho molta idea di come LSI ti aiuterà a rispondere (a). Puoi scegliere il set di tag a mano. Ma, se stai usando LSI, i tag probabilmente dovrebbero essere parole presenti nei documenti. Quindi per (b), si desidera selezionare i tag più vicini alle parole trovate nel documento. Potresti sperimentare alcuni modi per implementarlo. Scegli i tre tag più vicini alla qualsiasi parola nel documento, in cui la vicinanza è misurata dalla somiglianza del coseno (vedi Wikipedia) tra le coordinate del tag (la sua riga in U) e le coordinate della parola (la sua riga in U).

C'è un ulteriore thread SO sui pericoli di fare tutto questo in PHP all'indirizzo link testo .

In particolare, esiste un collegamento a questo documento su Mappatura semantica latente , che descrive come ottenere gli "argomenti" risultanti per un testo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top