Je viens de commiter une nouvelle méthode de popularité, basée sur mon
modèle mathématique exponentiel, sur l'idée d'Arno d'avoir un input des
visites et des referrers, etc, sur les commentaires d'Antoine côté
performances. J'espère que la synthèse vous plaira !
Les objectifs étaient :
1) on utilise des double pour avoir une discrimination partout
(par ex: select id_article,titre,popularite from spip_articles where
id_secteur=1)
2) Que ça ait du sens (si ce rythme se maintient votre popularité = nombre
de visiteurs (ip déifférentes) sur cet article en une journée)
3) Que ça se calcule facilement
4) Que ça donne rapidement une tendance (update souvent toutes les dix
minutes)
5) Notion de popularité totale du site et de popularité absolue
6) Que ça ne fasse pas un update à chaque hit
Mission accomplie ? Il reste à créer le tag #POPULARITE_TOTALE ; certains
pensent qu'on peut le mettre dans le backend...
Je viens de commiter une nouvelle méthode de popularité...
post-scriptum :
* pour la "période de demi-vie" des points attribués (un point par visiteur,
un point par referer) j'ai mis 3 jours, un peu au pif. Peut-être faut-il que
ça soit plus réactif (1 jour, 12 heures) ou plus lisse (1 semaine). Je ne
sais pas s'il est intéressant/pertinent de faire des essais autour de ça.
Pour tester il suffit de changer la variable $demivie = ... dans
inc_statistiques.php3
* il faudra peut-être renommer, et en tous cas documenter les deux nouveaux
tags #POPULARITE_ABS (est-ce qu'on l'appelle #POPULARITE_ABSOLUE ?) #POPULARITE_TOTALE (#POPULARITE_SITE ?), ainsi que le système de
popularité.
Oui ; en ayant un peu réfléchi (la matinée porte conseil) je crois qu'il
faut baisser $demivie pour avoir une sensibilité plus élevée aux variations
de la journée. Car sur le "long terme" on a le critère des visites totales,
et sur le "court terme" on n'a que la "popularite". Qui plus est, si on
choisit arbitrairement $demi-vie = 24 heures, les explications sont encore
plus simples, puisque tout est basé sur "la journée": le "nombre estimé de
visites sur cete article en vitesse de croisière" et "le temps qui fait
qu'une visite est comptée pour 0.5"...
Oui ; en ayant un peu réfléchi (la matinée porte conseil) je crois qu'il
faut baisser $demivie pour avoir une sensibilité plus élevée aux variations
de la journée. Car sur le "long terme" on a le critère des visites totales,
et sur le "court terme" on n'a que la "popularite". Qui plus est, si on
choisit arbitrairement $demi-vie = 24 heures, les explications sont encore
plus simples, puisque tout est basé sur "la journée": le "nombre estimé de
visites sur cete article en vitesse de croisière" et "le temps qui fait
qu'une visite est comptée pour 0.5"...
Au fait, ton calcul est franchement bizarre. Le $b = 60 * 24 n'est pas
homogène (durée au lieu de popularite)
- tu changes la signification de $a en 1-$a, c'est exprès pour nous
embrouiller Je note donc $A ce que tu as indiqué ci-dessus, $a restant
égal à 1-$A et conforme à mes explications. Je préfère $a, proche de 0, plutôt
que $A, qui est proche de 1. Personnellement je trouve ça plus parlant, mais
bon...
- avec $b = 1-$A la "popularite" limite si tu as une visite par minute sera
égale à 1 ; or pour le tag #POPULARITE_ABSOLUE le nb de visites par JOUR
sera plus parlant que PAR MINUTE. Donc il faut $b = (nb de visites par jour
si j'ai en continu une viste par minute) * (1-$A) ; ma formule était la
bonne.
- le calcul de $A avec pow() plutôt qu'avec exp(log()), pourquoi pas, c'est
kifkif.
- avec $b = 1-$A la "popularite" limite si tu as une visite par minute sera
égale à 1
Je ne comprends pas trop d'où sort cette histoire de minutes.... On a un nombre
de visites absolues, qui est égalisé sur une durée de $demivie. $b est homogène
à un nombre de visites et ne doit pas être multiplié par une durée.
A réfléchir on aurait plutôt :
$b = 1 - 2 puissance (- 24 * 3600 / demi-vie)
Cela répond à l'équation :
$b * N + N * $A = N quand durée = 1 journée
Non ?
(note : l'avantage de ma notation ($a, $b) est que les équations sont plus
simples à écrire ;-))
>- avec $b = 1-$A la "popularite" limite si tu as une visite par minute sera
>égale à 1
Je ne comprends pas trop d'où sort cette histoire de minutes.... On a un
nombre de visites absolues, qui est égalisé sur une durée de $demivie.
Oublie les minutes : c'était quand la formule s'appliquait à chauqe hit,
pour que MySQL n'ait pas des chiffres trop petits qui auraient dépassé sa
précision (truc que tu avais soulevé) ; mais maintenant que l'UPDATE se fait
en passant directement le facteur multiplicatif, to $A est le bon, et mieux
exprimé dans ton commit que dans ton mail.
$b est homogène à un nombre de visites et ne doit pas être multiplié par
une durée.
Certes ; mais à une visite par minute (mon hypothèse de base) c'est la même
chose. 24 * 60 c'est la popularité limite d'un article visité une fois par
minute.
A réfléchir on aurait plutôt :
$b = 1 - 2 puissance (- 24 * 3600 / demi-vie)
Cela répond à l'équation :
$b * N + N * $A = N quand durée = 1 journée
pas exactement : l'équation n'est pas celle que tu mentionnes, mais
$b * 10 + N * $A = N
où $A = 0.5 puissance (10 minutes/demi-vie)
N = 60 * 24;
D'où, avec la demi-vie d'une journée,
$b = (1-pow(0.5, 10 / (60*24))) * 60 * 24 /10
= 0.69148161;
(note : l'avantage de ma notation ($a, $b) est que les équations sont plus
simples à écrire ;-))
Je sais bien, il faudra juste réécrire les explications.
J'ai l'impression d'avoir un problème avec la fonction de surlignage :
L'affichage d'une page "recherchée" est hyper lent et j'obtiens en bas de ma
page :
Fatal error: Maximum execution time of 30 seconds exceeded in f:\program
files\easyphp\www\spip\ecrire\inc_surligne.php3 on line 52
Je regarde le code incriminé et j'arrive sur :
// supprimer tout ce qui est avant </head> ou <body>
if (eregi("(.*<\/head>)(.*)", $page, $exp))
list(,$debut,$page) = $exp;
else if (eregi("(.*<body[^>]*>)(.*)", $page, $exp))
list(,$debut,$page) = $exp;
else
$debut = '';
=> c'est un truc qui vient d'être ajouté ça, non ?
=> vous n'avez pas le même genre de problème ?
// supprimer tout ce qui est avant </head> ou <body>
if (eregi("(.*<\/head>)(.*)", $page, $exp))
list(,$debut,$page) = $exp;
else if (eregi("(.*<body[^>]*>)(.*)", $page, $exp))
list(,$debut,$page) = $exp;
else
$debut = '';
=> c'est un truc qui vient d'être ajouté ça, non ?
Dans le CVS les nouveaux tags de popularité, à utiliser comme suit :
<BOUCLE_pop(ARTICLES){id_article}{popularite>0}>
<h5>Popularité</h5>
Cet article a une popularité absolue égale à #POPULARITE_ABSOLUE, soit #POPULARITE % de #POPULARITE_MAX. Au total, ce site fait environ #POPULARITE_SITE visites par jour.
<hr>
</BOUCLE_pop>
NB : le rendu est toujours un entier, ce qui donnera, sur des sites peu
fréquentés ou à la popularité tout juste démarrée, des choses amusantes du
genre :
"Cet article a une popularité absolue égale à 1, soit 17 % de 2. Au total, ce
site fait environ 5 visites par jour."
Dans le tableau de bord, marge de gauche de statistiques_referers.php3, il y
a trois cases
* tout le site
articles récents
* articles populaires
* articles visités hier
Il y a bcp de répétitions entre les trois blocs.
A mon avis avec la nouvelle popu on peut se satisfaire d'un seul bloc {par
popularite}{inverse}{0,30} auquel on ajoute les 5 plus récents non
doublonnés. Pas d'objection ?