2010-10-13 6 views
6

Estoy configurando un cuadro de "temas de tendencia" al estilo de Twitter para mi foro. Tengo las/palabras más populares /, pero ni siquiera puedo empezar a pensar cómo obtendré frases populares, como lo hace Twitter.¿Cómo puedo obtener las frases más populares de mucho texto?

Tal como está, simplemente obtengo todo el contenido de los últimos 200 mensajes en una cadena y los divido en palabras, luego selecciono por qué palabras se usan más. ¿Cómo puedo convertir esto de las palabras más populares en las frases más populares?

+0

Realmente depende de lo que va a definir como una "frase" –

+0

¿Qué tal pegar dos/tres/cuatro palabras juntas en una? Todavía sería O (n). –

+0

no creo que encuentres tu respuesta en algunas líneas de código en stackoverflow ... este problema es un tema de tesis probablemente relacionado con la semántica web – pleasedontbelong

Respuesta

2

Una técnica que puede considerar es el uso de ZSET en Redis para algo como esto. Si usted tiene muy grandes conjuntos de datos, usted encontrará que usted puede hacer algo como esto:

$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)); 

Para recuperar las frases principales, que tendría que utilizar esto:

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

$trending_phrases será una matriz de las diez mejores frases de tendencia. Para hacer cosas como frases de tendencias recientes (a diferencia de un conjunto persistente de frases globales), duplique todas las interacciones de Redis anteriores. Para cada interacción, use una clave que sea indicativa de, por ejemplo, la marca de tiempo de hoy y la marca de tiempo de mañana (es decir, días desde el 1 de enero de 1970). Al recuperar los resultados con $trending_phrases, solo recupere las claves de hoy y de mañana (o de ayer) y use array_merge y array_unique para encontrar la unión.

Espero que esto ayude!

1

En lugar de dividir palabras individuales, dividir frases individuales, es así de simple.

$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>'; 

que va a ser mucho más lento si se tiene en cuenta una frase como una agregación de n palabras consecutivas.

+0

Como una cuestión de rendimiento, 'array_key_exists ($ sentence, $ popular)! == true' es un orden de magnitud mucho más lento que'! Isset ($ popular [$ sentence]) '. En esta situación, las diferencias funcionales no son importantes. – mattbasta

+0

@mattbasta: De hecho. Pero, ¿un orden de magnitud más lento? Como en 10 veces más lento? ¿Tiene algún punto de referencia que muestre estos resultados? –

+0

No tengo ninguna utilidad, pero he tenido experiencia con matrices más grandes (más de 1000 elementos) que 'isset' tomará dentro de 50ms,' array_key_exists' puede tomar hasta 300-400ms. – mattbasta

1

No estoy seguro de qué tipo de respuesta que estabas buscando, pero Laconica:

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

es un clon de Twitter de código abierto (una versión mucho más simple).

¿Tal vez podría usar parte del código para hacer sus propias frases populares?

¡Buena suerte!

Cuestiones relacionadas