2009-06-06 6 views
9

Vorrei implementare Singular Value Decomposition (SVD) in PHP. So che ci sono diverse librerie esterne che potrebbero farlo per me. Ma ho due domande su PHP, però: 1) Pensi che sia possibile e/o ragionevole codificare il SVD in PHP? 2) Se (1) è si: puoi aiutarmi a codificarlo in PHP?Singular Value Decomposition (SVD) in PHP

Ho già codificato alcune parti di SVD da solo. Here's the code in cui ho inserito commenti sul corso dell'azione. Alcune parti di questo codice non sono completamente corrette.

Sarebbe bello se potessi aiutarmi. Grazie mille in anticipo!

+3

I tuoi commenti in tedesco sono molto utili. Perché è necessario implementare un algoritmo così complicato in PHP? –

+0

Se qualcuno ha bisogno dei commenti in inglese, posso tradurli, ovviamente. Devo implementarlo in PHP poiché non posso installare librerie esterne sul mio spazio web. – caw

+0

odora di compiti a casa – VVS

risposta

9

SVD-python È un'implementazione molto chiara e parsimoniosa della SVD. È praticamente psuedocode e dovrebbe essere abbastanza facile da capire e confrontare/attingere per l'implementazione php, anche se non si conosce molto python.

SVD-python

Detto questo, come altri hanno detto che non ci si aspetterebbe di essere in grado di fare LSA molto pesanti con implementazione php quello che suona come un web-host piuttosto limitata.

Acclamazioni

Edit: Il modulo di cui sopra non fa nulla da sola, ma c'è un esempio inclusi nei commenti di apertura . Dando per scontato che hai scaricato il modulo python, ed era accessibile (per esempio nella stessa cartella), si potrebbe implementare un esempio banale come segue,

#!/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 

Qui 'w' contiene l'elenco dei valori singolari.
Naturalmente questo ti porta solo a metà dell'analisi semantica latente e dei suoi parenti. In genere si desidera ridurre il numero di valori singolari, quindi utilizzare la metrica appropriata della distanza per misurare la somiglianza tra i documenti, o parole, documenti o parole, ecc. Il coseno dell'angolo tra i vettori risultanti è piuttosto popolare .

Latent Semantic Mapping (pdf)

è di gran lunga la più chiara della carta, più conciso e informativo che ho letto sui gradini rimanenti si bisogno di lavorare in seguito alla SVD.

Edit2: notare anche che se si sta lavorando con molto grandi matrici termine-documento (sto assumendo questo è quello che state facendo) si tratta quasi certamente sarà molto più efficiente per eseguire la decomposizione in una modalità offline, quindi eseguire solo i confronti in modo live in risposta alle richieste. mentre svd-python è ottimo per l'apprendimento, lo svdlibc è più ciò che si vorrebbe per un calcolo così pesante .

infine come accennato nel documento bellegarda sopra, ricorda che non è necessario ricalcolare lo svd ogni volta che si ottiene un nuovo documento o richiesta. a seconda di ciò che stai cercando di fare, potresti ottenere probabilmente eseguendo la svd una volta ogni settimana o giù di lì, in una modalità offline, una macchina locale, e poi caricando i risultati (nonostante le preoccupazioni sulla dimensione/larghezza di banda).

comunque buona fortuna!

+0

Grazie mille !!! :) Sarebbe bello se questo potesse funzionare in combinazione con la funzione passthru() di PHP (thx ljyanes). Ma questo script non dà alcun risultato. Cosa devo fare? Ho commentato questo: http://paste.bradleygill.com/index.php?paste_id=10389 – caw

+0

Ho aggiunto qualche altra informazione, incluso un esempio funzionante dai commenti nel modulo python. – si28719e

+0

Grazie ancora per la modifica. Il tuo codice è esattamente quello che ho fatto, non è vero? ;) Guarda il sito di codepaste in cui ho scritto il codice. Penso di aver appena preso il pacchetto sbagliato. Ho scaricato solo il file svd.py che hai linkato sopra. Devo caricare anche qualcos'altro? – caw

2

Riguardo alla domanda 1: è sicuramente possibile. Che sia ragionevole dipende dal tuo scenario: quanto sono grandi le tue matrici? Quanto spesso intendi eseguire il codice? È eseguito in un sito Web o dalla riga di comando? Se si preoccupa della velocità, suggerirei writing a simple extension che include le chiamate allo GNU Scientific Library.

+0

Grazie per questa risposta. Mi piacerebbe eseguirlo su un sito Web e lo script dovrebbe essere chiamato da un cronjob. Non mi interessa molto della velocità. Sarebbe sufficiente se lo script facesse sempre SVD per 1 singolo testo. L'enorme matrice di cui ho sempre bisogno potrebbe anche essere memorizzata nella cache. Scrivere un'estensione per GNU Scientific Library è un problema perché non riesco a installare le librerie sul mio spazio web tramite la riga di comando. – caw

+0

Se si ha accesso alla shell e si possono installare binari e usare cron, si dovrebbe probabilmente pensare di scrivere binari autonomi (probabilmente, collegati staticamente), non uno script PHP. Anche per lo stesso algoritmo, questo sarà più efficiente per la CPU e la memoria. – drdaeman

0
  1. Sì. questo è perfettamente possibile essere implementato in PHP. Non so quale sia l'intervallo di tempo ragionevole per l'esecuzione e quanto grande possa essere calcolato. Probabilmente dovrei implementare l'algoritmo per ottenere un'idea rought.

  2. Sì, posso aiutarti a codificarlo. Ma perché hai bisogno di aiuto? Il codice che hai scritto non funziona?

Proprio come una domanda a parte. Quale versione di PHP usi?

+0

Grazie mille! Molte persone con cui ho parlato mi hanno detto che PHP è completamente inadatto per SVD. Non mi interessa quali sono i limiti di tempo, vorrei solo implementarlo. Il mio codice non funziona poiché non ottiene gli autovalori. Ho provato alcune procedure di approssimazione ma non hanno funzionato bene. Sarebbe bello se tu potessi aiutarmi. Io uso PHP 5. – caw

5

Fai attenzione quando dici "Non mi interessa quali sono i limiti di tempo". SVD è un'operazione O(N^3) (o O(MN^2) se è una matrice rettangolare m*n), il che significa che potresti facilmente trovarti in una situazione in cui il tuo problema può richiedere molto tempo. Se il caso 100 * 100 richiede un minuto, il caso 1000 * 1000 sarebbe 10^3 minuti, o quasi 17 ore (e probabilmente peggio, realisticamente, poiché è probabile che si stia esaurendo la cache). Con qualcosa come PHP, il prefactor - il numero che moltiplica il numero N^3 per calcolare il conteggio FLOP richiesto, potrebbe essere molto, molto grande.

Detto questo, ovviamente è possibile codificarlo in PHP: la lingua ha le strutture e le operazioni necessarie.

+0

Grazie mille per questo! Quindi pensi che sia possibile codificarlo con PHP, ma PHP non è molto adatto, giusto? – caw

+0

Bene, PHP non è l'ideale per l'algebra lineare numerica, ma se è possibile farlo funzionare nel tuo caso dipende dai dettagli. Quanto sono grandi le matrici su cui verrà eseguito? Cosa, esattamente, hai bisogno di fare? È possibile consultare un libro come Ricette numeriche per informazioni sulle implementazioni. –

+0

Vorrei utilizzare SVD per l'analisi semantica latente. Quindi 100x100 non sarà sufficiente per le matrici, saranno enormi ... – caw

1

Sì, è possibile, ma l'implementazione di SVD in PHP non è l'approccio ottimale. Come potete vedere qui PHP è più lento di C e anche più lento del C++, quindi forse era meglio se poteste farlo in una di queste lingue e chiamarle come una funzione per ottenere i risultati. Puoi trovare un'implementazione dell'algoritmo here, quindi puoi guidarti attraverso di esso.

Circa la funzione chiamante può usare:

  • L'exec() Funzione

La funzione di sistema è molto utile e potente, ma uno dei più grandi problemi con esso è che tutto il testo risultante dal programma va direttamente al flusso di output. Ci saranno situazioni in cui ti piacerebbe formattare il testo risultante e visualizzarlo in un modo diverso, o non visualizzarlo affatto.

  • Il sistema() Funzione

La funzione di sistema in PHP prende un argomento di tipo stringa con il comando da eseguire, nonché tutti gli argomenti che si desidera passato a quel comando. Questa funzione esegue il comando specificato e scarica qualsiasi testo risultante nel flusso di output (l'output HTTP in una situazione del server Web o la console se si esegue PHP come strumento a riga di comando). Il ritorno di questa funzione è l'ultima riga di output del programma, se emette l'output di testo.

  • Il passthru() Funzione

Una funzione affascinante che PHP fornisce simili a quelle che abbiamo visto finora è la funzione passante. Questa funzione, come le altre, esegue il programma a cui lo dici. Tuttavia, procede quindi a inviare immediatamente l'output non elaborato da questo programma al flusso di output con cui sta lavorando PHP (vale a dire HTTP in uno scenario di server Web o shell in una versione a riga di comando di PHP).

+0

Grazie mille! :) – caw

+0

Dovresti menzionare che hai copiato le descrizioni delle funzioni direttamente da [ChipmunkNinja] (http://chipmunkninja.com/Program-Execution-in-PHP%[email protected]). – TachyonVortex

2

So che questo è un vecchio Q, ma ecco il mio 2-bit:

1) Un vero SVD è molto più lento rispetto alle approssimazioni di calcolo di ispirazione utilizzati, ad esempio, nel premio Netflix. Vedi: http://www.sifter.org/~simon/journal/20061211.html

C'è un'implementazione (in C) qui: http://www.timelydevelopment.com/demos/NetflixPrize.aspx

2) C sarebbe più veloce, ma PHP può certamente farlo.

PHP Autore di architettura Cal Evans: "PHP è un linguaggio di scripting Web ... [ma] Ho usato PHP come linguaggio di scripting per scrivere l'equivalente DOS di file BATCH o l'equivalente Linux di script di shell. Ho scoperto che la maggior parte di ciò che ho bisogno di fare può essere realizzato da PHP. Esiste anche un progetto per permetterti di costruire applicazioni desktop tramite PHP, il progetto PHP-GTK. "

+0

Grazie mille! Interessanti informazioni e link. – caw