Foros del Web » Programando para Internet » PHP »

Hashtags del momento

Estas en el tema de Hashtags del momento en el foro de PHP en Foros del Web. Hola a todos. Verán, estoy preparando un sistema de tendencias a través de hashtags en mi página web. Y mi problema es como hacerlo lo ...
  #1 (permalink)  
Antiguo 28/07/2014, 05:07
Avatar de iEnrique  
Fecha de Ingreso: abril-2013
Ubicación: España
Mensajes: 346
Antigüedad: 11 años, 7 meses
Puntos: 5
Hashtags del momento

Hola a todos.

Verán, estoy preparando un sistema de tendencias a través de hashtags en mi página web. Y mi problema es como hacerlo lo más real posible.

Si yo tengo una tabla en la que tengo los hashtags con el número de veces que se han enviado no sería útil porque al final algún día acabarían siempre los mismos porque se comentaron mucho en su momento.

Por lo que pensé en otra alternativa hacerlo por los últimos hashtags en las últimas 24 horas, pero claro, eso tiene un riesgo y es que si no comentan 5 hashtags diferentes en las últimas 24 horas quedaría una lista con dos hashtags :S.

La última alternativa que pensé fue en seleccionar los 50 últimos hashtags publicados y ordenarlos por los que más veces aparecen. Pero claro, esto no sería muy justo.

La mejor es la segunda y si me dan alguna solución al problema de que únicamente aparezcan dos cuando yo lo que quiero es que muestre los 5 más comentados.

Muchas gracias.

Última edición por iEnrique; 28/07/2014 a las 05:17
  #2 (permalink)  
Antiguo 28/07/2014, 14:42
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Hashtags del momento

Yo lo que aria seria un algoritmo de puntuaciones en base a 2 parámetros fijos, para luego ordenar por esa puntuación.

Me explico, supongamos que tienes estos datos en una tabla llamada publicaciones:
fecha_publicacion (datetime) | hashtag

en la cual vas registrando en que fecha, hora, minuto y segundo se publica un hashtag, esa tabla es a modo de historial y va creciendo y creciendo a medida que pasan los dias.

Ahora bien, el algoritmo de puntuacion deberia recibir 2 parametros:
inicio - Cantidad de dias desde los cuales quieres marcar tendencia, pueden ser 7 para la ultima semana, 30 para el ultimo mes, etc.
intervalo - Este parametro es la cantidad de minutos que te interesa tomar para calcular el puntaje, si pones 1, todos los hastag del mismo minuto tienen la misma puntuacion, si pones 10, todos los que esten en un rango de 10 minutos tienen la misma puntuacion, si pones 60 todos los de la ultima hora tienen la misma puntuacion, etc.

Entonces, que es lo que debe hacer el algoritmo con esa puntuacion?
1) Calcular las fecha de inicio - fin del rango, la de fin es la fecha actual, la de inicio, es la fecha actual menos la cantidad de dias pasados como parametro.
2) Calcular la cantidad de sub-rangos, esto se obtiene dividiendo la cantidad de minutos entre la fecha de inicio y fin por el parametro intervalo
3) Debe crear una tabal de puntuaciones por hashtag, luego, empieza a recorrer los hashtag del rango inicio fin estimado haciendo lo siguiente:
Código PHP:
Ver original
  1. $inicio // Contiene la fecha de inicio calculada previamente
  2. $intervalo // Contiene la cantidad de minutos definida previamente
  3. $cant_intervalos // Contiene la cantidad de sub-rangos calculada previamente
  4.  
  5. $puntuaciones = array(); // Array con las puntuaciones del hashtag
  6. while($hashtag = getHashtag()) // Recorrer de a uno en uno los registros.
  7. {
  8. $intervalo_actual = ceil(minutos_diff(hashtag["fecha_publicacion"], $inicio) / $intervalo); // Intervalo en el que esta.
  9. $puntuaciones[$hashtag["hashtag"]] += ($cant_intervalos/$intervalo_actual);
  10. }

Luego ordenas a $puntuaciones y las de valor mas alto son las que tienen mas tendecia o son mas populares.

La idea es que los mensajes nuevos pesan mas que los viejos, pero si hubo un hashtag hace un mes que tubo mucha repercucion, este no desaparece de la noche a la mañana sino que va bajando posiciones en el ranking
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #3 (permalink)  
Antiguo 29/07/2014, 14:22
Avatar de iEnrique  
Fecha de Ingreso: abril-2013
Ubicación: España
Mensajes: 346
Antigüedad: 11 años, 7 meses
Puntos: 5
Respuesta: Hashtags del momento

Hola NSD,

Lo primero, darte las gracias por tu gran trabajo, muchas, muchas gracias. He escrito el código y me gustaría que le echaras un vistazo para ver si tengo errores o es tal y como me lo has explicado, te lo agradecería mucho.

En la base de datos tengo esto:
Código SQL:
Ver original
  1. INSERT INTO `pruebas`.`publicaciones` (`id`, `fecha_publicacion`, `hashtag`) VALUES (NULL, '2014-07-01 18:30:00', '#Buenas'), (NULL, '2014-07-01 18:33:00', '#Buenas'), (NULL, '2014-07-29 18:30:00', '#Hola');

Y en mi archivo .PHP tengo lo siguiente:
Código PHP:
Ver original
  1. <?php
  2.     $mysqli = mysqli_connect('localhost', 'root', '', 'pruebas') or die(mysqli_error($mysqli));
  3.     $sql = mysqli_query($mysqli, "SELECT fecha_publicacion, hashtag FROM publicaciones") or die(mysqli_error($sql));
  4.    
  5.     function minutos_diff($inicio, $fin){
  6.         $diff = strtotime($fin) - strtotime($inicio);      
  7.         return intval($diff / (60 * 60 * 24));
  8.     }
  9.    
  10.     $inicio = 7; // Contiene la fecha de inicio calculada previamente
  11.     $intervalo = 60; // Contiene la cantidad de minutos definida previamente
  12.     $cant_intervalos = 5; // Contiene la cantidad de sub-rangos calculada previamente
  13.      
  14.     $puntuaciones = array(); // Array con las puntuaciones del hashtag
  15.     while($hashtag = mysqli_fetch_array($sql)) // Recorrer de a uno en uno los registros.
  16.     {
  17.         $intervalo_actual = ceil(minutos_diff($hashtag["fecha_publicacion"], $inicio) / $intervalo); // Intervalo en el que esta.
  18.         if(!isset($puntuaciones[$hashtag["hashtag"]])){
  19.             $puntuaciones[$hashtag["hashtag"]] = array("hashtag" => $hashtag["hashtag"], "puntuacion" => ($cant_intervalos/$intervalo_actual));
  20.         }else{
  21.             $puntuaciones[$hashtag["hashtag"]]["puntuacion"] += ($cant_intervalos/$intervalo_actual);
  22.         }
  23.     }
  24.    
  25.     arsort($puntuaciones);
  26.     foreach($puntuaciones as $hashtag => $dato){
  27.         echo $dato["hashtag"].' (Puntuación '.$dato["puntuacion"].')<br>';
  28.     }
  29. ?>

Para terminar, en agradecería mucho que me contestaras una duda. ¿Qué diferencia hay entre $inicio y $intervalo? ¿Qué significa $cant_intervalos? Si me lo explicara más detalladamente se lo agradecería muchísimo porque aún no he conseguido entenderlo completamente.

¡MUCHÍSIMAS, MUCHÍSIMAS GRACIAS!
  #4 (permalink)  
Antiguo 29/07/2014, 18:40
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Hashtags del momento

Hola! Me alegro de ver que te esforzaste en intentar algo, con gusto te respondere.

Primero que nada, el algoritmo esta bastante bien planteado solo tiene unas pequeñas falencias relacionadas con las preguntas que hiciste luego. Te voy a proponer otra forma de implemntarlo, solo con MySQL que te sera mas eficiente y facil de inplementar y mantener.

Para poblar la base de datos de prueba use el siguiente codigo (Para probar estas cosas hacen falta unos miles de registros, con solo 3 no se apreciara mucho):

Código PHP:
Ver original
  1. <?php
  2.     set_time_limit(0);
  3.     $mysqli = mysqli_connect('localhost', 'root', '', 'pruebas') or die(mysqli_error($mysqli));
  4.  
  5.         $fecha_desde = "2014-07-01 00:00:00";
  6.         $fecha_hasta = date("Y-m-d H:i:s");
  7.         $palabras_hashtags = array(
  8.                                 'photooftheday'
  9.                                 ,'love'
  10.                                 ,'igers'
  11.                                 ,'cute'
  12.                                 ,'me'
  13.                                 ,'picoftheday'
  14.                                 ,'sky'
  15.                                 ,'bestoftheday'
  16.                                 ,'girl'
  17.                                 ,'igdaily'
  18.                                 ,'beautiful'
  19.                                 ,'food'
  20.                                 ,'dog'
  21.                                 ,'nature');
  22.                                
  23.         for($fecha=$fecha_desde; $fecha<=$fecha_hasta; $fecha=date("Y-m-d H:i:s", strtotime($fecha ." +30 second")))
  24.         {  
  25.             mysqli_query($mysqli, "INSERT INTO `pruebas`.`publicaciones` (`fecha_publicacion`, `hashtag`) VALUES ('$fecha', '".($palabras_hashtags[rand(0, count($palabras_hashtags)-1)])."');") or die("Error en consulta.");        
  26.         }
  27.         die("listo");

Luego de casi 3 minutos de ejecucion, la tabla quedo poblada con 1 hashtag cada 30 segundos (~83,297 registros)

El algoritmo que te propongo es este:

Código PHP:
Ver original
  1. /*
  2.      *  Cantidad de dias que tendras en cuenta en el ranking.
  3.      *  Los dias se cuentan de la fecha actual, hacia atras.
  4.      *  En este caso son 7, es decir, la ultima semana.
  5.      */
  6.     $reporte_ultimos_dias = 7;
  7.  
  8.     /*
  9.      *  Cantidad de minutos de los sub-intervalos de la puntuacion.
  10.      *  Esto es con que frecuencia consideras que una aparicion de hashtag vale mas que otra.
  11.      *  En este caso son 5, es decir, los que esten en los mismos 5 minutos, tendran el mismo indice de puntuacion.
  12.      */
  13.     $lapso_de_intervalo = 5;
  14.  
  15.     $mysqli = mysqli_connect('localhost', 'root', '', 'pruebas') or die(mysqli_error($mysqli));
  16.     $sql = mysqli_query($mysqli, "SELECT info.hashtag, SUM(info.cantidad) menciones, ( (CEIL( ( TIMESTAMPDIFF (  MINUTE,
  17.                                                        DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
  18.                                                        NOW()
  19.                                                      ) / $lapso_de_intervalo)
  20.                                                ) / info.intervalo_actual) * info.cantidad) puntuacion
  21.                                    FROM (
  22.                                        SELECT
  23.                                            hashtag,
  24.                                             CEIL(   ( TIMESTAMPDIFF(  MINUTE,
  25.                                                        DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
  26.                                                        fecha_publicacion
  27.                                                       ) / $lapso_de_intervalo)
  28.                                                ) intervalo_actual,
  29.                                            COUNT(DISTINCT id) cantidad
  30.                                        FROM publicaciones
  31.                                        WHERE ( fecha_publicacion >= DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY) )
  32.                                        GROUP BY intervalo_actual, hashtag
  33.                                        HAVING intervalo_actual > 0
  34.                                     ) info 
  35.                                    GROUP BY info.hashtag
  36.                                    ORDER BY puntuacion DESC") or die(mysqli_error($sql));                                    
  37.     echo("<table>
  38.            <tr>
  39.                <th colspan=\"3\">Tendencias de los ultimos $reporte_ultimos_dias dias</th>
  40.            </tr>
  41.            <tr>
  42.                <th>#Hashtag</th>
  43.                <th>Menciones</th>
  44.                <th>Popularidad</th>
  45.            </tr>");
  46.     while($hashtag = mysqli_fetch_array($sql))
  47.         echo("<tr><td>#".$hashtag["hashtag"]."</td><td>".$hashtag["menciones"]."</td><td>".$hashtag["puntuacion"]."<td></tr>");
  48.     echo("</table>");

Para mis datos obtube esto:

Tendencias de los ultimos 7 dias
#Hashtag Menciones Popularidad
#bestoftheday 1453 4032.0000
#sky 1465 4032.0000
#photooftheday 1455 3024.0000
#beautiful 1410 2016.0000
#cute 1444 2016.0000
#love 1456 2016.0000
#picoftheday 1419 2016.0000
#girl 1434 2016.0000
#me 1444 2016.0000
#igers 1457 1344.0000
#food 1422 672.0000
#nature 1395 672.0000
#igdaily 1410 672.0000
#dog 1443 504.0000

Como puedes observar, la cantidad de menciones no es determinante, es importante que se lo mencione mucho, pero tambien es importante que se lo halla mencionado recientemente.

No es lo mismo lo mas mencionado que lo que esta de moda, puedes comparar esto con las visitas de un video de youtube, el video con mas visitas NO tiene porque ser el mas visitado, el de mas visitas es que fue visto mas veces, no importa cuando, el mas visitado es el que mas gente esta viendo ultimamente.

Seria cuestion de que ajustes los dos parametros para afinar el resultado tanto como quieras.

Cita:
¿Qué diferencia hay entre $inicio y $intervalo? ¿Qué significa $cant_intervalos?
La diferencia esta explicada en los comentarios del codigo que te acabo de pasar, les puse unos nombres mas claros a cada uno, la cantidad de intervalos es un valor calculado, no es un valor que debas porner tu, sino que se calcula solo en funcion de los dos valores anteriores.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #5 (permalink)  
Antiguo 30/07/2014, 08:31
Avatar de iEnrique  
Fecha de Ingreso: abril-2013
Ubicación: España
Mensajes: 346
Antigüedad: 11 años, 7 meses
Puntos: 5
Respuesta: Hashtags del momento

¡Muchas gracias de nuevo por contestar!

Lo primero, has conseguido solucionar por una parte mis dudas, que te planteé antes y que me respondiste en los comentarios.

He seguido los pasos de tu algoritmo y he estado enredando un poco pero me salen dos dudas nuevas :

- ¿Por qué no funciona con pocos registros? No es ningún problema porque seguramente haya muchos en una tabla así de hashtags pero probé a hacerlo con pocos registros y la tabla se quedaba en blanco, no importa pero si pudieras contestarme a la duda te lo agradecería muchísimo igual que con las otras.

- ¿Por qué al recargar la página los hashtags cambian de lugar? Si esperas un poco y recargas cada vez te van saliendo distintos resultados cuando no se ha realizado ningún cambio en los hashtags.

¡Muchas gracias por resolver mis dudas! Espero no ser muy pesado .
  #6 (permalink)  
Antiguo 30/07/2014, 20:28
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Hashtags del momento

Debe haber al menos 2 registros en dos intervalos diferentes, es decir que no esten en el mismo bloque de 5 minutos, la causa es el HAVING intervalo_actual > 0 pero no se me ocurre una forma directa de solucionarlo.

Si pasado un rato recargas la pagina los hashtag cambian de lugar, y es correcto que sea asi, ya que si te fijas, el periodo es de la fecha actual 7 dias hacia atras, al dejar pasar un rato varios hashtag dejan de entrar en la cuenta ya que son antiguos y eso afecta a las puntuaciones, se supone que en ese tiempo tambien se incorporan nuevos hashtag a la base, aunque en un entorno de pueba eso no es tan simple de simular
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #7 (permalink)  
Antiguo 31/07/2014, 06:16
Avatar de iEnrique  
Fecha de Ingreso: abril-2013
Ubicación: España
Mensajes: 346
Antigüedad: 11 años, 7 meses
Puntos: 5
Respuesta: Hashtags del momento

¡Muchas gracias! He estado enredando y lo mejor es ajustarlo cuando abra la web y saber que cantidad de mensajes por minuto hay para adaptarlo a las tendencias.

Muchisimas gracias de verdad.
  #8 (permalink)  
Antiguo 04/08/2014, 16:02
Avatar de iEnrique  
Fecha de Ingreso: abril-2013
Ubicación: España
Mensajes: 346
Antigüedad: 11 años, 7 meses
Puntos: 5
Respuesta: Hashtags del momento

Hola,

Siento tener que recurrir a ti de nuevo para el tema de las tendencias. He estado probando tu código y al principio funciona bien pero después comienza a fallar. Como puedes ver aquí, tengo estos hashtags de prueba (aunque empiece por la id 22 no hay más hashtags atrás ni más por delante de 36):



Y sorprendentemente en la lista de tendencias aparece esto, Cena debería estar en lo primero de ella muy por delante:

#mundialito - 1.0938 - 2
#Cena - 1.0938 - 9
#mayorquemundialito - 1.0936 - 2
#maquinaria - 1.0921 - 1
#buenas - 1.0921 - 1

Otra cosa de la que me doy cuenta es que si esperas un poco la que va primera va creciendo su numero y nunca baja por lo que si la gente escribe en ese hashtag y ningún otro hashtag le supera en mensajes nunca baja. Lo bueno sería que fuera bajando poco a poco cuando vaya pasando el tiempo, este es el código que me diste y que he pasado a mysqli con sentencias preparadas:

Código PHP:
Ver original
  1. <?php $reporte_ultimos_dias = 7;
  2.                     $lapso_de_intervalo = 1;
  3.                     $sql = $mysqli->prepare("SELECT info.hashtag_content, SUM(info.cantidad) menciones, ( (CEIL( ( TIMESTAMPDIFF (  MINUTE,
  4.                                                        DATE_SUB(NOW(), INTERVAL ? DAY),
  5.                                                        NOW()
  6.                                                      ) / ?)
  7.                                                ) / info.intervalo_actual) * info.cantidad) puntuacion
  8.                                    FROM (
  9.                                        SELECT
  10.                                            hashtag_content,
  11.                                            CEIL(   ( TIMESTAMPDIFF(  MINUTE,
  12.                                                        DATE_SUB(NOW(), INTERVAL ? DAY),
  13.                                                        hashtag_date
  14.                                                       ) / ?)
  15.                                                ) intervalo_actual,
  16.                                            COUNT(DISTINCT hashtag_id) cantidad
  17.                                        FROM hashtags
  18.                                        WHERE ( hashtag_date >= DATE_SUB(NOW(), INTERVAL ? DAY) )
  19.                                        GROUP BY intervalo_actual, hashtag_content
  20.                                        HAVING intervalo_actual > 0
  21.                                    ) info  
  22.                                    GROUP BY info.hashtag_content
  23.                                    ORDER BY puntuacion DESC");
  24.                     $sql->bind_param('iiiii', $reporte_ultimos_dias, $lapso_de_intervalo, $reporte_ultimos_dias, $lapso_de_intervalo, $reporte_ultimos_dias);
  25.                     $sql->execute();
  26.                     $sql_r = $sql->get_result();
  27.                     while($hashtag = $sql_r->fetch_array())
  28.                         echo '<div><a href="/i/hashtag/'.$hashtag['hashtag_content'].'" class="hcolor">#'.$hashtag['hashtag_content'].' - '.$hashtag['puntuacion'].' - '.$hashtag['menciones'].'</a></div>'; ?>
  #9 (permalink)  
Antiguo 05/08/2014, 11:06
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Hashtags del momento

mmm se me hace que lo que esta mal este cociente:
Código MySQL:
Ver original
  1.                                                        DATE_SUB(NOW(), INTERVAL ? DAY),
  2.                                                        NOW()
  3.                                                      ) / ?)
  4.                                                ) / info.intervalo_actual)

deberia ser al revez:
Código MySQL:
Ver original
  1. (CEIL(  info.intervalo_actual / ( TIMESTAMPDIFF (  MINUTE,
  2.                                                        DATE_SUB(NOW(), INTERVAL ? DAY),
  3.                                                        NOW()
  4.                                                      ) / ?)
  5.                                                ) )

No lo probe podrias pasarme el dump de los insert en la base asi tenemos los mismos datos? porque copiar de a 1 manualmente segun la imagen es muy molesto
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #10 (permalink)  
Antiguo 10/08/2014, 08:50
Avatar de iEnrique  
Fecha de Ingreso: abril-2013
Ubicación: España
Mensajes: 346
Antigüedad: 11 años, 7 meses
Puntos: 5
Respuesta: Hashtags del momento

Perdón por no contestar antes, tenía visita en casa y no podía dejar de atenderlos ni un segundo para contestar a tu respuesta. De nuevo muchas gracias de antemano por el interés.

Pues verás te pongo un ejemplo que te muestro, pongamos una tabla como esta:
Código SQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `hashtags` (
  2.   `hashtag_id` INT(11) NOT NULL AUTO_INCREMENT,
  3.   `hashtag_content` VARCHAR(139) NOT NULL,
  4.   `hashtag_date` datetime NOT NULL,
  5.   `hashtag_language` VARCHAR(5) NOT NULL,
  6.   `hashtag_message` INT(11) NOT NULL,
  7.   PRIMARY KEY (`hashtag_id`)
  8. ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=61 ;
  9.  
  10. INSERT INTO `hashtags` (`hashtag_id`, `hashtag_content`, `hashtag_date`, `hashtag_language`, `hashtag_message`) VALUES
  11. (1, 'cerveza', '2014-08-05 04:44:27', 'es', 1),
  12. (2, 'hello', '2014-08-10 01:22:13', 'es', 2),
  13. (3, 'miedo', '2014-08-10 01:22:34', 'es', 3),
  14. (4, 'miedo', '2014-08-10 01:44:35', 'es', 4),
  15. (5, 'hello', '2014-08-10 02:17:54', 'es', 5),
  16. (6, 'jajaja', '2014-08-10 02:30:08', 'es', 6),
  17. (7, 'hashtags', '2014-08-10 02:30:23', 'es', 7),
  18. (8, 'hashtags', '2014-08-10 02:30:45', 'es', 8);

Y en este caso, este código:
Código PHP:
Ver original
  1. <?php $reporte_ultimos_dias = 7;
  2.     $lapso_de_intervalo = 30;
  3.     $sql = mysqli_query($mysqli, "SELECT info.hashtag_content, SUM(info.cantidad) menciones, ( (CEIL( info.intervalo_actual / ( TIMESTAMPDIFF (  MINUTE,
  4.                                                        DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
  5.                                                        NOW()
  6.                                                      ) / $lapso_de_intervalo)
  7.                                                ) ) * info.cantidad) puntuacion
  8.                                    FROM (
  9.                                        SELECT
  10.                                            hashtag_content,
  11.                                            CEIL(   ( TIMESTAMPDIFF(  MINUTE,
  12.                                                        DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
  13.                                                        hashtag_date
  14.                                                       ) / $lapso_de_intervalo)
  15.                                                ) intervalo_actual,
  16.                                            COUNT(DISTINCT hashtag_id) cantidad
  17.                                        FROM hashtags
  18.                                        WHERE ( hashtag_date >= DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY) )
  19.                                        GROUP BY intervalo_actual, hashtag_content
  20.                                        HAVING intervalo_actual > 0
  21.                                    ) info  
  22.                                    GROUP BY info.hashtag_content
  23.                                    ORDER BY puntuacion DESC");
  24.     while($hashtag = mysqli_fetch_array($sql))
  25.         echo '<div><a href="/i/hashtag/'.$hashtag['hashtag_content'].'" class="hcolor">#'.$hashtag['hashtag_content'].'</a></div>'; ?>

Lo he pasado a MySqli con sentencias no preparadas para que sea más fácil de controlar. Bueno, una vez tengas esto, ponlo en funcionamiento. Verás como #cerveza que es el primer hashtag que se creó y también el más antiguo, se encuentra en segundo lugar o tercero, cuando hay otros más recientes con la misma o igual cantidad de veces que aparece.

La verdad es que he realizado el cambio que me has dicho y el funcionamiento a mejorado ligeramente.

Gracias por todo .
  #11 (permalink)  
Antiguo 10/08/2014, 11:17
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Hashtags del momento

Prueba este:

Código PHP:
Ver original
  1. $reporte_ultimos_dias = 7;
  2.     $lapso_de_intervalo = 2;
  3.     $sql = mysqli_query($mysqli, "SELECT    
  4.                                    info.hashtag_content,
  5.                                    SUM(info.cantidad) menciones,
  6.                                    SUM( (info.intervalo_actual / ( TIMESTAMPDIFF(  MINUTE,
  7.                                                                      DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
  8.                                                                      NOW()
  9.                                                                    ) / $lapso_de_intervalo
  10.                                                                  )
  11.                                         ) * info.cantidad
  12.                                       ) puntuacion
  13.                                   FROM (
  14.                                       SELECT
  15.                                           hashtag_content,
  16.                                           CEIL( ( TIMESTAMPDIFF(  MINUTE,
  17.                                                       DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
  18.                                                       hashtag_date
  19.                                                      ) / $lapso_de_intervalo)
  20.                                               ) intervalo_actual,
  21.                                           COUNT(DISTINCT hashtag_id) cantidad
  22.                                       FROM hashtags
  23.                                       WHERE ( hashtag_date >= DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY) )
  24.                                       GROUP BY intervalo_actual, hashtag_content
  25.                                       HAVING intervalo_actual > 0
  26.                                   ) info  
  27.                                   GROUP BY info.hashtag_content
  28.                                   ORDER BY puntuacion DESC, menciones DESC, intervalo_actual DESC");
  29.     while($hashtag = mysqli_fetch_array($sql))
  30.         echo '<div><a href="/i/hashtag/'.$hashtag['hashtag_content'].'" class="hcolor">#'.$hashtag['hashtag_content'].' -> '.$hashtag['puntuacion'].'</a></div>'; ?>

retorna acertadamente los resultados en base a la prueba, habria que tener mas datos en la base como para probarlo mejor, la clave esta aca:

Código MySQL:
Ver original
  1. SUM( (info.intervalo_actual / ( TIMESTAMPDIFF(  MINUTE,
  2.                                                                       DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
  3.                                                                       NOW()
  4.                                                                     ) / $lapso_de_intervalo
  5.                                                                   )
  6.                                          ) * info.cantidad
  7.                                        ) puntuacion

esa suma es la quedes ir modificando para pulir al calculo lo mas posible, por ejemplo, si en vez de:

Código MySQL:
Ver original
  1. ) * info.cantidad
pones:
Código MySQL:
Ver original
  1. ) * (info.cantidad-1)

estaras diciendo que para entrar en el ranking, un hastag debe tener como minimo dos menciones (2-1 > 0) por supuesto esto podrias parametrizarlo a una variable php, que para el script tal como esta ahora, valdria 0.

es cuestion de que cuando lo implementes, le hagas durante 1 o 2 semanas un seguimiento y lo vallas puliendo con detalles como el que te mencione.

La idea es que cuando el programa te retorne algo que no es lo esperado, mires los datos y te preguntes ¿Porque este elemento no debe tener (tanta|tan poca) puntuacion? y cuando encuentres esa respuesta, por ejemplo en el caso del ejemplo anterior seria: porque aun se lo menciono muy pocas veces vallas y hagas el retoque.

Puede pasar que una resta tan directa sea un metodo un poco agresivo, ya que aquellos que solo se los menciona menos de 2 veces por intervalo dejaran de figurar, asi que podrias suavizar esa penalizacion haciendo algo asi:
Código MySQL:
Ver original
  1. ) * (info.cantidad-(0.1*(IF(info.cantidad = 1, 0.1, (1 / (info.cantidad-1))))))

con lo cual ya tienes 2 parametros mas, el minimo de menciones (1) y el factor de penalizacion (0.1) donde aquellos que no alcancen el minimo de menciones reciben una penalizacion acorde al factor de penalizacion.

Las empresas que se dedican a estas cosas, llevan mucho tiempo realizando un seguimiento de los datos, comparando lo que sus programas devuelven con lo que deberian devolver y luego puliendo y mejorando algoritmos como este, dibujando los numeros de los informes y agregando decenas de parametros para torcer el ranking hacia donde ellos creen o consideran que es correcto.
(Por algo en twitter Obama mide mas que musicos o artistas famosos a nivel mundial, no es porque a la mayor parte del mundo le importe la politica y lo que Twitea el presidente de estados unidos, sino porque las empresas que arman los ranking "consideran..." que eso es lo que deberia ocurrir, y llevan meses perfeccionando sus codigos para que reflejen sus criterios.)

tu debes hacer lo mismo, de a poco ir agregando pequeños cambios y torciendo el informe hacia lo que tu consideres los resultados correctos, no tengas ninguna duda que si juntas a 10 personas, le muestras los mismos datos, tendras no menos de 5 opiniones diferentes de como deberian ordenarse
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #12 (permalink)  
Antiguo 25/08/2014, 16:43
Avatar de iEnrique  
Fecha de Ingreso: abril-2013
Ubicación: España
Mensajes: 346
Antigüedad: 11 años, 7 meses
Puntos: 5
Respuesta: Hashtags del momento

Perdón de nuevo por tardar en contestar, he estado fuera de casa todo este tiempo y no he podido meterme al foro.

¡No se hable más! Me pondré manos a la obra a hacer mis retoques según los datos, etc. Doy este tema como zanjado y te doy mil gracias por todo lo que me has ayudado, eres genial de verdad.

¡Un saludo!

Etiquetas: momento, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 12:55.