2010-10-13 7 views
6

Sto configurando una casella "Argomenti di tendenza" in stile Twitter per il mio forum. Ho le parole più popolari /, ma non riesco nemmeno a pensare a come otterrò frasi popolari, come Twitter.Come posso ottenere le frasi più popolari da un sacco di testo?

Così com'è, ho appena ottenuto tutto il contenuto degli ultimi 200 post in una stringa e li divido in parole, quindi ordina in base a quali parole vengono utilizzate di più. Come posso trasformare questo dalle parole più popolari nelle frasi più popolari?

+0

Dipende davvero da cosa si intende definire una "frase" –

+0

Come si fa a incollare due/tre/quattro parole insieme a una? Sarebbe ancora O (n). –

+0

non penso che troverai la tua risposta su poche righe di codice su StackOverflow .. questo problema è un argomento di tesi probabilmente correlato alla semantica web – pleasedontbelong

risposta

2

Una tecnica che si potrebbe considerare è l'uso di ZSET in Redis per qualcosa di simile. Se hai molto grandi insiemi di dati, ci si accorge che si può fare qualcosa di simile:

$words = explode(" ", $input); // Pseudo-code for breaking a block of data into individual words. 
$word_count = count($words); 

$r = new Redis(); // Owlient's PHPRedis PECL extension 
$r->connect("127.0.0.1", 6379); 

function process_phrase($phrase) { 
    global $r; 
    $phrase = implode(" ", $phrase); 
    $r->zIncrBy("trending_phrases", 1, $phrase); 
} 

for($i=0;$i<$word_count;$i++) 
    for($j=1;$j<$word_count - $i;$j++) 
     process_phrase(array_slice($words, $i, $j)); 

Per recuperare le frasi migliori, devi usare questo:

// Assume $r is instantiated like it is above 
$trending_phrases = $r->zReverseRange("trending_phrases", 0, 10); 

$trending_phrases sarà una matrice delle prime dieci frasi di tendenza. Per fare cose come le frasi di tendenza recenti (al contrario di un insieme di frasi persistenti e globali), duplica tutte le interazioni di Redis qui sopra. Per ogni interazione, utilizza una chiave indicativa, ad esempio, del timestamp di oggi e del timestamp di domani (cioè giorni dal 1 ° gennaio 1970). Quando recuperi i risultati con $trending_phrases, recupera solo la chiave di oggi e di domani (o di ieri) e usa array_merge e array_unique per trovare l'unione.

Spero che questo aiuti!

1

Invece di dividere singole parole separare singole frasi, è semplice.

$popular = array(); 

foreach ($tweets as $tweet) 
{ 
    // split by common punctuation chars 
    $sentences = preg_split('~[.!?]+~', $string); 

    foreach ($sentences as $sentence) 
    { 
     $sentence = strtolower(trim($sentence)); // normalize sentences 

     if (isset($popular[$sentence]) === false) 
     //if (array_key_exists($sentence, $popular) === false) 
     { 
      $popular[$sentence] = 0; 
     } 

     $popular[$sentence]++; 
    } 
} 

arsort($popular); 

echo '<pre>'; 
print_r($popular); 
echo '</pre>'; 

sarà molto più lento se si considera una frase come aggregazione di n parole consecutive.

+0

Per quanto riguarda le prestazioni, 'array_key_exists ($ sentence, $ popular)! == true' è un intero ordine di grandezza più lento di'! Isset ($ popular [$ sentence]) '. In questa situazione, le differenze funzionali non sono importanti. – mattbasta

+0

@mattbasta: Infatti. Ma un ordine di grandezza più lento? Come in 10 volte più lento? Hai qualche benchmark che mostri questi risultati? –

+0

Non ho alcuna utilità, ma ho avuto esperienza con array più grandi (più di 1000 elementi) che "isset" impiegherà 50 ms, "array_key_exists" può richiedere fino a 300-400 ms. – mattbasta

1

Im non sicuro che tipo di risposta che stavate cercando, ma Laconica:

http://status.net/?source=laconica

è una fonte Twitter clone open (una versione molto più semplice).

Forse potresti usare parte del codice per creare le tue preferite?

Buona fortuna!

Problemi correlati