2009-06-06 32 views
9

Je voudrais implémenter la décomposition de la valeur singulière (SVD) en PHP. Je sais qu'il existe plusieurs bibliothèques externes qui pourraient le faire pour moi. Mais j'ai deux questions concernant PHP, cependant: 1) Pensez-vous qu'il soit possible et/ou raisonnable de coder le SVD en PHP? 2) Si (1) est oui: Pouvez-vous m'aider à le coder en PHP?Décomposition de la valeur singulière (SVD) en PHP

J'ai déjà codé certaines parties de SVD par moi-même. Here's the code dans lequel j'ai fait des commentaires sur le cours de l'action. Certaines parties de ce code ne sont pas complètement correctes.

Ce serait génial si vous pouviez m'aider. Merci beaucoup d'avance!

+3

Vos commentaires en allemand sont très utiles. Pourquoi avez-vous besoin d'implémenter un algorithme aussi compliqué en PHP? –

+0

Si quelqu'un a besoin des commentaires en anglais, je peux les traduire, bien sûr. Je dois l'implémenter en PHP car je ne peux pas installer de librairies externes sur mon espace web. – caw

+0

sent les devoirs – VVS

Répondre

9

SVD-python Est une implémentation très claire et parcimonieuse du SVD. C'est pratiquement psuedocode et devrait être assez facile à comprendre et comparer/dessiner sur votre implémentation php, même si vous ne connaissez pas beaucoup python.

SVD-python

Cela dit, comme d'autres l'ont mentionné, je ne pense pouvoir faire très lourds LSA avec php ce qui ressemble à la mise en œuvre d'un web-hôte assez limité.

Vive

Edit: Le module ci-dessus ne fait rien par lui-même, mais il est un exemple inclus dans les commentaires d'ouverture. En supposant que vous avez téléchargé le module python, et il était accessible (par exemple dans le même dossier), vous pouvez mettre en œuvre un exemple trivial comme suit,

#!/usr/bin/python 
import svd 
import math 

a = [[22.,10., 2., 3., 7.], 
    [14., 7.,10., 0., 8.], 
    [-1.,13.,-1.,-11., 3.], 
    [-3.,-2.,13., -2., 4.], 
    [ 9., 8., 1., -2., 4.], 
    [ 9., 1.,-7., 5.,-1.], 
    [ 2.,-6., 6., 5., 1.], 
    [ 4., 5., 0., -2., 2.]] 

u,w,vt = svd.svd(a) 
print w 

Ici « w » contient votre liste de valeurs singulières.
Bien sûr, cela ne vous permet qu'une partie de l'analyse sémantique latente et de ses proches. Vous souhaitez généralement réduire le nombre de valeurs singulières, puis utiliser une distance appropriée pour mesurer la similarité entre vos documents, ou mots, ou documents et mots, etc. Le cosinus de l'angle entre vos vecteurs résultants est très populaire .

Latent Semantic Mapping (pdf)

est de loin la plus claire, le papier le plus concis et informatif, je l'ai lu sur les autres étapes que vous besoin de travailler à la suite du SVD.

Edit2: Notez également que si vous travaillez avec de très grandes matrices terme-documents (je suppose que ce est ce que vous faites), il est presque certainement va être beaucoup plus efficace pour effectuer la décomposition en un mode hors connexion, puis effectuez uniquement les comparaisons de façon dynamique en réponse aux demandes. alors que svd-python est idéal pour l'apprentissage, le svdlibc est plus ce que vous voulez pour un tel calcul .Enfin, comme mentionné dans le papier Bellegarda ci-dessus, rappelez-vous que vous n'avez pas besoin de recalculer le svd à chaque fois que vous recevez un nouveau document ou une nouvelle demande. en fonction de ce que vous essayez de faire, vous pouvez probablement sortir avec le lecteur une fois par semaine, en mode hors connexion, une machine locale, , puis en téléchargeant les résultats (malgré les problèmes de taille/bande passante).

de toute façon bonne chance!

+0

Merci beaucoup! :) Ce serait génial si cela fonctionnait en combinaison avec la fonction passthru() de PHP (thx ljyanes). Mais ce script ne donne aucune sortie. Que dois-je faire? J'ai commenté ceci: http://paste.bradleygill.com/index.php?paste_id=10389 – caw

+0

J'ai ajouté quelques informations supplémentaires, y compris un exemple de travail à partir des commentaires dans le module python. – si28719e

+0

Merci encore pour l'édition. Ton code est exactement ce que j'ai fait, n'est-ce pas? ;) Regardez le site de codepaste où j'ai écrit le code. Je pense que je viens de prendre le mauvais paquet. J'ai seulement téléchargé le fichier svd.py que vous avez lié ci-dessus. Dois-je charger quelque chose d'autre aussi? – caw

2

Concernant la question 1: C'est certainement possible. Que ce soit raisonnable dépend de votre scénario: Quelle est la taille de vos matrices? À quelle fréquence avez-vous l'intention d'exécuter le code? Est-il exécuté dans un site Web ou à partir de la ligne de commande? Si vous vous souciez de la vitesse, je suggère writing a simple extension qui encapsule les appels au GNU Scientific Library.

+0

Merci pour cette réponse. Je voudrais l'exécuter sur un site Web et le script devrait être appelé par un cronjob. Je me fiche de la vitesse. Il suffirait que le script fasse toujours la SVD pour un seul texte. L'immense matrice dont j'ai toujours besoin pourrait aussi être mise en cache. L'écriture d'une extension pour la bibliothèque scientifique de GNU est un problème car je ne peux pas installer les bibliothèques sur mon espace Web via la ligne de commande. – caw

+0

Si vous avez un accès shell et que vous pouvez installer des binaires et utiliser cron, vous devriez probablement penser à écrire un binaire autonome (probablement lié statiquement), pas un script PHP. Même pour le même algorithme, cela sera plus efficace pour le processeur et la mémoire. – drdaeman

0
  1. Oui. ceci est parfaitement possible d'être implémenté en PHP. Je ne sais pas quel est le délai raisonnable pour l'exécution et combien il peut calculer. Je devrais probablement mettre en application l'algorithme pour obtenir une idée rought.

  2. Oui, je peux vous aider à le coder. Mais pourquoi avez-vous besoin d'aide? Le code que vous avez écrit ne fonctionne-t-il pas?

Juste comme une question de côté. Quelle version de PHP utilisez-vous?

+0

Merci beaucoup! Beaucoup de gens avec qui j'ai parlé m'ont dit que PHP est complètement inadapté à SVD. Je me fiche des limites de temps, je voudrais juste l'implémenter. Mon code ne fonctionne pas car il n'obtient pas les valeurs propres. J'ai essayé quelques procédures d'approximation mais elles n'ont pas bien fonctionné. Ce serait génial si vous pouviez m'aider. J'utilise PHP 5. – caw

5

Soyez prudent lorsque vous dites «Je me fiche des limites de temps». SVD est une opération O(N^3) (ou O(MN^2) s'il s'agit d'une matrice rectangulaire m*n) ce qui signifie que vous pourriez être très facilement dans une situation où votre problème peut prendre beaucoup de temps. Si le cas 100 * 100 prend une minute, le cas 1000 * 1000 serait 10^3 minutes, ou presque 17 heures (et probablement pire, de façon réaliste, car vous risquez d'être hors de la cache). Avec quelque chose comme PHP, le préfacteur - le nombre multipliant le N^3 afin de calculer le compte FLOP requis, pourrait être très, très grand. Cela dit, bien sûr, il est possible de le coder en PHP - la langue a les structures et les opérations de données requises.

+0

Merci beaucoup pour ça! Donc vous pensez qu'il est possible de le coder avec PHP mais PHP n'est pas très adapté, non? – caw

+0

Eh bien, PHP n'est pas idéal pour l'algèbre linéaire numérique, mais si vous pouvez le faire fonctionner dans votre cas dépend des détails. Quelle est la taille des matrices sur lesquelles vous allez l'exécuter? Que devez-vous faire exactement? Vous pouvez consulter un livre tel que Numerical Recipes pour plus d'informations sur les implémentations. –

+0

Je voudrais utiliser SVD pour l'analyse sémantique latente. Donc 100x100 ne suffira pas pour les matrices, elles seront énormes ... – caw

1

Oui, c'est possible, mais la mise en œuvre de SVD en PHP n'est pas l'approche optimale. Comme vous pouvez le voir ici PHP est plus lent que C et aussi plus lent que C++, alors peut-être que c'était mieux si vous pouviez le faire dans l'une de ces langues et les appeler comme une fonction pour obtenir vos résultats. Vous pouvez trouver une implémentation de l'algorithme here, pour que vous puissiez vous guider.

A propos de l'appel de fonction peut utiliser:

  • L'exec() Fonction

La fonction du système est très utile et puissant, mais l'un des plus gros problèmes avec c'est que tout le texte résultant du programme va directement dans le flux de sortie. Il y aura des situations où vous voudrez peut-être formater le texte résultant et l'afficher d'une manière différente, ou ne pas l'afficher du tout.

  • Le système() Fonction

La fonction du système en PHP prend un argument de chaîne avec la commande à exécuter ainsi que tous les arguments que vous souhaitez avoir passé à cette commande. Cette fonction exécute la commande spécifiée et transfère tout le texte résultant dans le flux de sortie (soit la sortie HTTP dans une situation de serveur Web, soit la console si vous utilisez PHP en tant qu'outil de ligne de commande). Le retour de cette fonction est la dernière ligne de sortie du programme, si elle émet une sortie de texte.

  • Le passthru() Fonction

Une fonction fascinante que PHP offre semblable à ceux que nous avons vu jusqu'à présent est la fonction de relais. Cette fonction, comme les autres, exécute le programme auquel vous le dites. Cependant, il continue à envoyer immédiatement la sortie brute de ce programme au flux de sortie avec lequel PHP travaille actuellement (à savoir soit HTTP dans un scénario de serveur Web, soit le shell dans une version de ligne de commande de PHP).

+0

Merci beaucoup! :) – caw

+0

Vous devez mentionner que vous avez copié les descriptions de fonctions directement à partir de [ChipmunkNinja] (http://chipmunkninja.com/Program-Execution-in-PHP%[email protected]). – TachyonVortex

2

Je sais c'est un vieux Q, mais voici mes 2 bits:

1) Un vrai SVD est beaucoup plus lent que les approximations inspiré calcul utilisées, par exemple, dans le prix Netflix. Voir: http://www.sifter.org/~simon/journal/20061211.html

Il y a une mise en œuvre (en C) ici: http://www.timelydevelopment.com/demos/NetflixPrize.aspx

2) C serait plus rapide mais PHP peut certainement le faire. Cal Evans: «PHP est un langage de script web ... [mais] j'ai utilisé PHP comme langage de script pour écrire l'équivalent DOS de fichiers BATCH ou l'équivalent Linux de scripts shell. J'ai trouvé que la plupart de ce que je devais faire peut être accompli depuis PHP, il y a même un projet pour vous permettre de créer des applications de bureau via PHP, le projet PHP-GTK.

+0

Merci beaucoup! Informations et liens intéressants – caw