Bon, maintenant que vous m'avez donné à réfléchir aux "popularités", j'ai
aussi mon idée. J'explique : à chaque visite d'un article, on lui ajoute un
certain nombre de points ; ces points ont une période de demi-vie donnée. Et
c'est tout.
* on passe le champ popularite en "double" ; le fait de se fixer sur des
entiers est contre-productif, puisque ça implique des concepts comme
l'"efficacité de la discrimination" et des coupages de cheveux en 4.
* on affecte 1 point si le referer est dans le site ou vide, 2 sinon (par
exemple) ;
* la formule est super simple, à chaque hit sur un article on fait
if (referer extérieur)
$points = 2;
else
$points = 1;
UPDATE spip_articles
SET popularite = popularite * POWER ((1-a), (NOW()-maj)) + b * $points
WHERE id_article = $id_article;
* reste à trouver la valeur de a et b pour que, dans un scénario uniforme,
la "popularité" ait une signification intelligible... je détaille un peu
pour être clair et pour ceux qui n'auraient plus trop de souvenirs de maths.
Supposons donc qu'on ait de façon régulière un hit par minute valant 1
point. On veut avoir au final popularite = 1/minute, qu'on notera 60 * 24
(nombre "estimé si ce rythme est maintenu de points par jour").
"NOW()-maj" vaut donc toujours 60 secondes. L'équation est alors
(60 * 24) * (1 - (1-a)^60) = b * 1
* Il faut donc fixer la période de demi-vie (qui donne a) et en déduire b.
Si la demi-vie est de 3 jours, on part avec (1-a)^(3*24*60*60) = 1/2
D'où, sortez vos calculettes, et si je ne me suis pas trompé,
a = 1 - (1/2)^(-3*24*60*60) = 2,67418 E-06;
b = 0,231030525;
[Si on veut quelque chose de plus "réactif", on peut partir sur
(1-a)^(12*60*60) = 1/2 ; soit une demi-vie d'une demi-journée]
Avec ça on a le système de popularité permet tous les classements, est mis à
jour **en continu**, et a une signification "absolue" (le nombre de hits
dans la journée si "ce rythme de consultation se maintient", sachant qu'un
accès direct vaut deux hits) et, par rebond, une signification relative
(puisqu'on travaille sur des double et pas sur des entiers, on peut même
classer entre eux des articles pas lus depuis un mois !).
Si on veut conserver la notion de pourcentage (idiote mais pour garder la
compatibilité), il suffit de faire, une fois par heure par exemple,
ecrire_meta('max_popularite') = "SELECT MAX(popularite) FROM
spip_articles"...
et donner #POPULARITE = MAX(100, popularite/lire_meta('max_popularite'));
et #POPULARITE_PARJOUR = popularite
à quoi on peut ajouter #POPULARITE_SITE = SOMME(popularite); ce dernier
concept a aussi une signification absolue, qui pourrait se mettre dans un
champ du "backend" (sans tricher!) et qu'un "hit parade des spip" pourrait
aller chercher automatiquement.
-- Fil