2009-06-18 6 views
9

Je voudrais implémenter l'analyse sémantique latente (LSA) en PHP afin de trouver des sujets/tags pour les textes.LSA - Analyse sémantique latente - Comment coder en PHP?

Voici ce que je pense devoir faire. Est-ce correct? Comment puis-je le coder en PHP? Comment puis-je déterminer quels mots choisir?

Je ne souhaite utiliser aucune bibliothèque externe. I've already an implementation for the Singular Value Decomposition (SVD).

  1. Extraire tous les mots d'un texte donné.
  2. Pondérer les mots/phrases, par ex. avec tf–idf. Si la pondération est trop complexe, il suffit de prendre le nombre d'occurrences.
  3. Construire une matrice: Les colonnes sont des documents de la base de données (le plus est le mieux?), Les lignes sont tous des mots uniques, les valeurs sont les nombres d'occurrences ou le poids.
  4. Faire la décomposition de la valeur singulière (SVD).
  5. Utilisez les valeurs de la matrice S (SVD) pour effectuer la réduction de dimension (comment?).

J'espère que vous pouvez m'aider. Merci beaucoup d'avance!

+1

« Je l'ai déjà une mise en œuvre pour la Décomposition en Valeurs Singulières » http://stackoverflow.com/questions/960060/singular-value-decomposition-svd-in-php – Ben

+0

Désolé, j'ai ajouté le lien maintenant. – caw

+0

Qu'est-ce que cela a à voir avec PHP? – Novelocrat

Répondre

7

liens LSA:

Voici l'algorithme complet. Si vous avez une maladie vésiculeuse du porc, vous êtes là pour la plupart. Les papiers ci-dessus l'expliquent mieux que moi.

Hypothèses:

  • votre fonction SVD donnera les valeurs singulières et des vecteurs singuliers dans l'ordre décroissant. Sinon, vous devez faire plus d'acrobaties.

M: matrice corpus, w (mots) d (documents) (w lignes, colonnes d). Ceux-ci peuvent être des comptes bruts, ou tfidf ou autre. Les mots d'ordre peuvent ou non être éliminés, et l'arrêt peut arriver (Landauer dit garder les mots vides et ne pas s'arrêter, mais oui à 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 :) 

Puis le reductionality .... le papier LSA réelle suggère une bonne approximation de la base est de garder des vecteurs assez de sorte que leurs valeurs singulières sont plus de 50% du total des valeurs singulières.

Plus ... succintement (pseudocode)

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

Cela renverra le rang de la nouvelle base, qui était min (d, w) avant, et nous allons maintenant environ avec {ii}.

(ici, '-> prime, pas transposé)

Nous créons de nouvelles matrices: U', Sigma 'V', avec des tailles w x ii, ii x ii, et ii x d.

C'est l'essence de l'algorithme LSA. Cette matrice résultante U '* Sigma' * V 'peut être utilisée pour une recherche de similitude de cosinus «améliorée», ou vous pouvez choisir les 3 premiers mots de chaque document, par exemple. Que ce soit plus qu'un simple tf-idf est un sujet de débat.

Pour moi, LSA fonctionne mal dans les ensembles de données du monde réel en raison de la polysémie, et les ensembles de données avec trop de sujets. Sa base mathématique/probabiliste est non fondée (elle suppose des distributions normales-gaussiennes, ce qui n'a pas de sens pour le nombre de mots).

Votre kilométrage va certainement varier.

Balisage en utilisant LSA (une méthode!)

  1. Construire U 'Sigma' V » matrices de dimensions réduites en utilisant SVD et une réduction heuristique

  2. la main, regarder par-dessus l'U «matrice, et de trouver des termes qui décrivent chaque« sujet ». Par exemple, si les plus grandes parties de ce vecteur étaient "Bronx, Yankees, Manhattan", alors "New York City" pourrait être un bon terme pour cela. Conservez-les dans un tableau ou une liste associative. Cette étape devrait être raisonnable puisque le nombre de vecteurs sera fini.

  3. En supposant que vous avez un vecteur (v1) de mots pour un document, alors v1 * t (U ') donnera les «sujets» les plus forts pour ce document. Sélectionnez les 3 plus élevés, puis donnez leur "sujets" comme calculé à l'étape précédente.

+0

Certainement, c'est à propos de ce que je voulais savoir. Mais j'ai encore quelques questions: ai-je besoin de V ou VT (transpose)? J'utilise http://stitchpanorama.sourceforge.net/Python/svd.py qui vous donne V. Comme vous pouvez le voir, les valeurs singulières ne sont pas dans l'ordre décroissant. Est-ce votre fonction de pseudo-code en PHP? http://paste.bradleygill.com/index.php?paste_id=10532 Que fait-il? – caw

+0

Le test facile pour savoir si vous avez besoin de V ou Vt est de savoir si USV = M ou USVt = M. Cette fonction est une manière heuristique de déterminer la dimension à réduire. Dans cette fonction, il dit, "réduire la base de telle sorte que les vecteurs ont 50% ou plus du total des valeurs singulières". Vous pouvez aussi simplement dire «gardez le k le plus grand, pour une valeur de k, comme 50». Essentiellement, déterminez combien de catégories il y a vraiment, ce qui est tout le point de la LSA. –

+0

Y avait-il jamais une solution à ce LSA dans la question PHP. Je comprends l'algorithme mais j'ai aussi du mal à l'implémenter en PHP. – privateace

0

Tout va bien, jusqu'à la dernière étape. La notation habituelle pour SVD est qu'elle renvoie trois matrices A = USV *. S est une matrice diagonale (c'est-à-dire tout le zéro de la diagonale) qui, dans ce cas, donne essentiellement une mesure de combien chaque dimension capture des données originales. Les nombres («valeurs singulières») vont baisser, et vous pouvez chercher une baisse pour combien de dimensions sont utiles. Sinon, vous voudrez simplement choisir un nombre arbitraire N pour le nombre de dimensions à prendre.

Ici, je suis un peu flou. Les coordonnées des termes (mots) dans l'espace de dimension réduite sont soit en U soit en V, je pense selon qu'ils se trouvent dans les lignes ou les colonnes de la matrice d'entrée. D'un autre côté, je pense que les coordonnées des mots seront les rangées de U., c'est-à-dire que la première rangée de U correspond à la première rangée de la matrice d'entrée, c'est-à-dire le premier mot. Ensuite, vous prenez juste les N premières colonnes de cette rangée comme les coordonnées du mot dans l'espace réduit.

HTH

Mise à jour:

Ce processus jusqu'à présent ne vous dit pas exactement comment choisir les mots clés. Je n'ai jamais entendu parler de quelqu'un utilisant LSI pour choisir les tags (un algorithme d'apprentissage automatique pourrait être plus adapté à la tâche, comme, par exemple, les arbres de décision). LSI vous indique si deux mots sont similaires. C'est loin d'attribuer des tags.

Il y a deux tâches: a) quels sont les balises à utiliser? b) comment choisir les trois meilleures étiquettes? Je n'ai pas vraiment une idée de la façon dont LSI va vous aider à répondre (a). Vous pouvez choisir l'ensemble des étiquettes à la main. Mais, si vous utilisez LSI, les tags devraient probablement être des mots qui apparaissent dans les documents. Ensuite, pour (b), vous voulez choisir les étiquettes les plus proches des mots trouvés dans le document. Vous pourriez expérimenter quelques façons de l'implémenter. Choisissez les trois étiquettes les plus proches de mot dans le document, où la proximité est mesurée par la similitude cosinus (voir Wikipedia) entre la coordonnée de l'étiquette (sa rangée en U) et la coordonnée du mot (sa rangée en U).

+0

Merci. Mon problème principal est: Comment puis-je déterminer quels mots je devrais choisir? En supposant que je veux toujours avoir 3 balises: Que dois-je faire? – caw

+0

Merci. Peut-être que j'ai mal compris quelque chose et LSA n'est pas utilisé pour trouver des étiquettes. Mais si j'ai un ensemble de tags, par ex. "Sports, Politics, World", alors vous pouvez sûrement utiliser LSA pour trouver le meilleur tag correspondant, non? – caw

+0

"Mais si j'ai une série de tags, par exemple" Sports, Politics, World "," ... Non. Ce n'est pas du tout ce que LSA est vraiment. Si vous aviez ces étiquettes, et un corpus d'articles sur ces sujets, il serait plus logique d'utiliser un classeur bayésien. Qu'est-ce que LSA est de dire, "les mots: baseball, yankees, A-Rod ont tendance à co-produire, et reflètent probablement une structure sous-jacente, donc d'autres articles ayant baseball en eux pourraient être liés aux mêmes sujets sous-jacents". LSA est juste l'analyse factorielle. –

1

Cette réponse ne concerne pas directement la question des affiches, mais la question méta de la façon d'autotaguer les nouvelles.Le PO mentionne la reconnaissance d'entité nommée, mais je crois qu'ils signifient quelque chose de plus sur la ligne de l'autotagging. S'ils veulent vraiment dire NER, cette réponse est foutaise :)

Compte tenu de ces contraintes (600 articles/jour, 100-200 caractères/item) avec des sources divergentes, voici quelques options de marquage:

  1. Par la main. Un analyste pourrait facilement en faire 600 par jour, probablement dans quelques heures. Quelque chose comme le turc mécanique d'Amazon, ou faire en sorte que les utilisateurs le fassent, pourrait aussi être réalisable. Avoir un certain nombre de "marqués à la main", même si ce n'est que 50 ou 100, sera une bonne base pour comparer ce que les méthodes autogénérées ci-dessous vous obtenez. Réductions de dimentionality, en utilisant LSA, Topic-Models (Allocation de Dirichlet Latent), et similaires .... J'ai eu vraiment pas de chance avec LSA sur les ensembles de données du monde réel et je suis insatisfait de ses statistiques base. LDA Je trouve beaucoup mieux, et a un incredible mailing list qui a la meilleure réflexion sur la façon d'attribuer des sujets aux textes. Heuristiques simples ... si vous avez des nouvelles réelles, alors exploite la structure de la nouvelle. Concentrez-vous sur la première phrase, lancez tous les mots communs (mots d'arrêt) et sélectionnez les 3 meilleurs noms parmi les deux premières phrases. Ou diable, prenez tous les noms dans la première phrase, et voyez où cela vous mène. Si les textes sont tous en anglais, faites une partie de l'analyse de la parole sur tout le shebang, et voyez ce que cela vous apporte. Avec les éléments structurés, comme les rapports de nouvelles, LSA et d'autres méthodes indépendantes de l'ordre (tf-idf) jette beaucoup d'informations.

Bonne chance!

(si vous aimez cette réponse, peut-être ReTAG la question de l'adapter)

+0

Merci beaucoup. Vous avez raison, je voulais dire autotagging. Mais je ne veux définitivement pas marquer manuellement les articles (1). L'approche 3 est trop simple et donne des résultats trop médiocres (déjà essayé). Mais l'approche 2 semble bonne et c'est ce que ma question concerne. ;) Je veux autotag (je n'ai pas utilisé ce mot, mais d'autres mots qui sont faux, peut-être) articles de nouvelles avec LSA. LDA sonne aussi bien, mais c'est une méthode de classification, pas de marquage je pense. – caw

+0

LDA fonctionne aussi pour le marquage. Toutes ces techniques sont des tentatives pour réduire la dimensionnalité (la base) de l'espace de document. –

0

Il y a un Thread sur les périls de faire tout cela en PHP à link text.

Plus précisément, il existe un lien vers cet article sur Latent Semantic Mapping, qui décrit comment obtenir les «rubriques» résultantes pour un texte.

+0

La question que vous avez liée (le premier lien) est l'une de mes questions. ;) Je l'ai également lié à ma question en haut de cette page. Mais celui-ci concerne SVD, celui-ci concerne LSA ... – caw

+0

SVD fait partie de LSA, et dans cette discussion SO. Regardez la réponse de Blackkettles. Vous faites la SVD, réduisez la matrice de valeurs propres, puis recombinez. Lisez le papier LSM, il a les étapes. Je pense que vous accordez beaucoup plus de confiance à LSM pour résoudre ce problème que ce qui est vraiment justifié pour votre projet d'autotagging. –