2011-11-02 9 views
7

Quello che sto cercando di implementare è un risultato piuttosto semplice "prendi i risultati della ricerca (come nel titolo & breve descrizione), raggruppali in un gruppo significativo di nomi" programma in PHP.Libreria PHP per il raggruppamento di parole/PNL?

Dopo ore di ricerca su google e innumerevoli ricerche su SO (ottenendo risultati interessanti come sempre, anche se nulla di veramente utile) non riesco ancora a trovare alcuna libreria PHP che possa aiutarmi a gestire il clustering.

  • Esiste una libreria PHP che potrei aver perso?
  • In caso contrario, c'è FOSS che gestisce il clustering e ha un'API decente?
+3

Raggrupparli in base a cosa? Qual è un gruppo significativo per te? – netcoder

+0

Si prega di definire "gruppi con nome significativi". – hakre

+0

@netcoder: in una libreria di clustering generica, ciò non dovrebbe avere importanza. La scelta delle caratteristiche dovrebbe determinare quale tipo di gruppi vengono prodotti. –

risposta

4

Ti piace questa:

usare un elenco di parole non significative, ottenere tutte le parole o frasi non nelle parole non significative, contare le occorrenze di ciascuno, specie in ordine decrescente.

Le parole chiave devono essere un elenco di tutti i termini inglesi comuni. Dovrebbe includere anche la punteggiatura e dovrai preg_replace che tutta la punteggiatura sia prima una parola separata, ad es. "Qualcosa come questo." -> "Qualcosa, come questo." O, puoi semplicemente rimuovere tutta la punteggiatura.

$content=preg_replace('/[^a-z\s]/', '', $content); // remove punctuation 

$stopwords='the|and|is|your|me|for|where|etc...'; 
$stopwords=explode('|',$stopwords); 
$stopwords=array_flip($stopwords); 

$result=array(); $temp=array(); 
foreach ($content as $s) 
if (isset($stopwords[$s]) OR strlen($s)<3) 
{ 
if (sizeof($temp)>0) 
    { 
    $result[]=implode(' ',$temp); 
    $temp=array(); 
    }    
} else $temp[]=$s; 
if (sizeof($temp)>0) $result[]=implode(' ',$temp); 

$phrases=array_count_values($result); 
arsort($phrases); 

Ora si dispone di un array associativo in base alla frequenza dei termini che si verificano nei dati di input.

Come si desidera eseguire le corrispondenze dipende da te e dipende in gran parte dalla lunghezza delle stringhe nei dati di input.

Vedrei se uno qualsiasi dei 3 principali tasti di matrice corrisponde a uno qualsiasi dei primi 3 di qualsiasi altro nei dati. Questi sono quindi i tuoi gruppi.

Fatemi sapere se avete qualche problema con questo.

+0

Ho dimenticato di menzionare prima strtolower(), anche se dovrebbe essere ovvio. – Alasdair

2

"... raggrupparli in gruppi significativi" è un po 'troppo vago, è necessario essere più specifici.

Per i principianti è possibile esaminare il clustering K-Means.

Date un'occhiata a questa pagina e il sito web:

PHP/irInformation Retrieval and other interesting topics

EDIT: Si potrebbe provare alcuni modelli di data mining voi stessi risultati di ricerca di riferimenti incrociati con qualcosa come la directory dmoz RDF dump dei dati aperti e poi enumerare le categorie corrispondenti.

EDIT2: Ed ecco una domanda su dmoz/categoria che menziona anche "Ricerca sfaccettata"!

Dmoz/Monster algorithme to calculate count of each category and sub category?

+0

Grazie, l'avevo già trovato ... Mentre una lettura interessante e un buon codice di esempio, è ben lungi dall'essere una libreria. Per quanto riguarda i "gruppi significativi", [questa ricerca di Yippy (guarda cosa chiamano "nuvole")] (http://search.yippy.com/search?input-form=clusty-simple&v%3Asources=webplus-ns-aaf&v% 3Aproject = clusty & query = sightseeing + munich) illustra ciò che sto cercando di implementare piuttosto bene. – vzwick

+0

@vzwick: vuoi dire ... sfaccettatura? – netcoder

+0

@vzwick Ah, il sito di esempio spiega tutto. La semplice risposta è no - non troverai una libreria che lo faccia automaticamente per te. – zaf

1

se si sta facendo questo per solo in inglese, è possibile utilizzare WordNet: http://wordnet.princeton.edu/. È un lessico ampiamente utilizzato nella ricerca che fornisce, tra le altre cose, serie di sinonimi per le parole inglesi. La distanza più breve tra due parole potrebbe quindi servire come parametro di somiglianza per raggruppare te stesso come proposto da zaf.

Apparentemente c'è un'interfaccia PHP per WordNet qui: http://www.foxsurfer.com/wordnet/. È venuto in questa domanda: How to use word Net with php, ma non l'ho provato. Tuttavia, anche l'interfacciamento con uno strumento da riga di comando di PHP è possibile.

1

Si potrebbe anche dare un'occhiata a Programming Collective Intelligence (capitolo 3: Discovering Groups) di Toby Segaran che utilizza solo questo caso d'uso con Python. Tuttavia, dovresti essere in grado di implementare le cose in PHP una volta capito come funziona.

Anche se non è PHP, il progetto Carrot2 offre diversi motori di clustering e può essere integrato con Solr.

0

Questo può essere spento ma controlla OpenCalais. Hanno un servizio web che ti permette di passare un blocco di testo e ti restituirà una risposta parsabile di cose che ha trovato nel testo, come luoghi, persone, fatti, ecc. Potresti usare queste categorie per costruire il tuo "nuvole" e anche scegliere quali risultati visualizzare.

Ho usato questa libreria alcune volte in PHP ed è sempre stato abbastanza facile lavorare con.

Anche in questo caso, potrebbe non essere pertinente a ciò che si sta tentando di fare. Forse potresti pubblicare un esempio di ciò che stai cercando di ottenere?

0

Se è possibile pre-definire i filtri per la ricerca sfaccettata (i gruppi con nome), sarà molto più semplice.

Piuttosto che fare affidamento su un algoritmo che utilizza l'input corrente del ricercatore e i relativi risultati per generare l'elenco di filtri, si utilizzerà un aggregato delle ricerche eseguite più comunemente da tutti gli utenti e quindi si codificano i risultati con esse se corrispondono.

Si finirebbe con una tabella (o qualcosa) di URL in un join molti-a-molti in una tabella di tag, quindi ogni URL risultato potrebbe avere diversi tag appropriati.

Quando l'utente esegue una ricerca, è sufficiente abbinare la ricerca all'indice completo. Ma per i filtri, prendi i risultati migliori tra quelli attuali.

Lavorerò sugli esempi di query se lo si desidera.