Retour : Page Principale > sommaire applications botaniques > Détermination en ligne

Mode de calcul des notations (votes)


Comment calculer le score d'une image dans Pictoflora ? En voilà une bonne question ! Différentes méthodes ont été examinées; en voici un aperçu.

Attention : Pictoflora a changé tellement souvent qu'il faut toujours vérifier le vrai code en prod pour savoir comment les calculs sont faits.

Vocabulaire:
  • note : nombre de points, de 1 à 5, attribué à une image (0 est une non-note, on ne peut pas voter "0")
  • vote : attribution par une personne d'une note à une image
  • consensus : note qui semble être attribuée par la majorité des votants (s'il y a lieu)
  • score : nombre représentant la synthèse des votes, peut être calculé de différentes manières

Moyenne arithmétique


C'est le mode de calcul bateau, utilisé actuellement. On additionne les notes et on divise par les votes.
Exemple:
  • notes : 1, 3, 3, 1, 2, 5, 1, 2, 1, 4, 3, 1
  • votes : 12
  • consensus : 1 (voté 5 ×)
  • score : (1+3+3+1+2+5+1+2+1+4+3+1) / 12 = 27/12 = 2.25

Cette moyenne est peu représentative du consensus, et ne favorise aucune note par rapport à une autre.

Moyenne pondérée par note


Chaque note est élevée par un coefficient qui s'élève avec la valeur de la note. Ainsi les notes les plus hautes (4, 5) sont plus influentes que les notes les plus basses (1, 2). On peut par exemple élever la note au carré et diviser par la somme des notes.
Exemple:
  • notes : 1, 3, 3, 1, 2, 5, 1, 2, 1, 4, 3, 1
  • somme des notes : 27
  • score : (1²+3²+3²+1²+2²+5²+1²+2²+1²+4²+3²+1²) / (27) = 81/27 = 3

Cette moyenne donne plus de poids aux notes élevées.

Moyenne pondérée par nombre de votes


Les notes sont groupées par nombre de votes. Chaque note est multipliée par son nombre d'occurrences au carré. Le total est divisé par la somme des carrés des occurrences.

Exemple:
  • notes : 1, 3, 3, 1, 2, 5, 1, 2, 1, 4, 3, 1
  • somme des carrés des occurrences : 40
  • score : (1*5²+2*2²+3*3²+4*1²+5*1²) / (40) = 69/40 = 1.725

Cette moyenne rapproche le score du consensus.

Médiane


La médiane est la note telle que 50% des votants ont donné une note inférieure et 50% des votants ont donné une note supérieure. On la trouve en triant les notes par ordre croissant et en choisissant "celle du milieu" (ou la moyenne arithmétique des "deux du milieu" en cas de nombre de votes pair).

Exemple:
  • notes : 1, 3, 3, 1, 2, 5, 1, 2, 1, 4, 3, 1
  • notes triées : 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 5
  • score : (2+2) / (2) = 2

La médiane rapproche aussi le score du consensus, mais produit des résultats entiers (ou au mieux demi entiers) qui ne facilitent pas le tri par la suite.

Nombre de points


Le nombre de points est une valeur qui n'est pas ramenée à un nombre entre 0 et 5. Il peut augmenter indéfiniment et est ainsi représentatif de l'activité autour de l'image. L'inconvénient est qu'une image ayant reçu un grand nombre de fois une note basse (1) accumulera beaucoup de point : cette méthode est quantitative et non qualitative.

Afin de faciliter le tri dans une optique qualitative, on peut employer trois méthodes.

Pondération des notes

De la même façon que la moyenne pondérée par note , on peut élever à l'aide d'un coefficient grandissant avec la note (au carré par exemple) afin de favoriser les notes élevées.

Exemple:
  • notes : 1, 3, 3, 1, 2, 5, 1, 2, 1, 4, 3, 1
  • score : (1²+3²+3²+1²+2²+5²+1²+2²+1²+4²+3²+1²) = 81

Inconvénient : cette méthode est très peu représentative du consensus, si celui-ci est faible

Échelle arbitraire

Chaque note est également pondérée, mais selon une échelle arbitraire, afin d'accentuer ou réduire les rapports de pondération entre deux notes successives. Cela permet de favoriser à l'extrême certaines notes (5 et 4 pour le défi photo par exemple).

Exemple:
  • notes : 1, 3, 3, 1, 2, 5, 1, 2, 1, 4, 3, 1
  • échelle : 1 => -2, 2 => -1, 3 => 1, 4 => 10, 5 => 100
  • score : (-2 + 1 + 1 + -2 + -1 + 100 + -2 + -1 + -2 + 10 + 1 + -2) = 101

Inconvénient : cette méthode est encore moins représentative du consensus.

Décalage du centre

C'est quand Bayrou se rallie à Borloo pour les municipales
Il s'agit de soustraire de chaque note un nombre fixé, afin de considérer une note intermédiaire comme "neutre", une note basse comme "négative" et une note haute comme "positive".

Exemple:
  • notes : 1, 3, 3, 1, 2, 5, 1, 2, 1, 4, 3, 1
  • décalage : -3
  • score : (1-3 + 3-3 + 3-3 + 1-3 + 2-3 + 5-3 + 1-3 + 2-3 + 1-3 + 4-3 + 3-3 + 1-3) = -9

Nombre de votes


Le nombre de votants est un indicateur de la fiabilité du score. Il est toujours utile de l'afficher en complément du score.

Exemple de code (PHP)


<?php

$fichier = file_get_contents('php://stdin');

$debug = false;

$paquetsDeVotes = explode("\n", $fichier);
array_pop($paquetsDeVotes);
//echo "PAQUETS DE VOTES:" . PHP_EOL;
//print_r($paquetsDeVotes);
$resultats = array();

$id = 1;
foreach ($paquetsDeVotes as $paquet) {

	// 1) méthode ringarde
	//$votes = explode("\n", $paquet);
	//array_pop($votes);

	// 2) méthode rapidos
	$clauses = explode(",", $paquet);
	$votes = array();
	$valNote = 5;
	foreach ($clauses as $nbocc) {
		for ($i=0; $i<$nbocc; $i++) {
			$votes[] = $valNote;
		}
		$valNote--;
	}

	if ($debug) {
		echo "VOTES:" . PHP_EOL;
		print_r($votes);
	}

	$res = array(
		'id' => $id,
		'nv' => count($votes),
		'np' => points($votes),
		'p2' => pointsCarre($votes),
		'p3' => pointsCube($votes),
		'pa' => pointsArbitraires($votes),
		'pd' => pointsDecalage($votes),
		'mn' => moyenne($votes),
		'mpn' => moyennePonderee($votes),
		'mpo' => moyennePPNV($votes),
		'me' => mediane($votes)
	);
	$resultats[] = $res;
	++$id;

	if ($debug) {
		echo "Nombre de votants : \t\t\t" . $res['nv'] . PHP_EOL;
		echo "Points : \t\t\t\t" . $res['np'] . PHP_EOL;
		echo "Points pondérés au carré : \t\t" . $res['p2'] . PHP_EOL;
		echo "Points pondérés au cube : \t\t" . $res['p3'] . PHP_EOL;
		echo "Points pondérés arbitrairement : \t" . $res['pa'] . PHP_EOL;
		echo "Points décalés (-3) : \t\t\t" . $res['pd'] . PHP_EOL;
		echo "Moyenne (actuelle) : \t\t\t" . $res['mn'] . PHP_EOL;
		echo "Moyenne pondérée par note : \t\t" . $res['mpn'] . PHP_EOL;
		echo "Moyenne pondérée par nombre de votes : \t" . $res['mpo'] . PHP_EOL;
		echo "Médiane : \t\t\t\t" . $res['me'] . PHP_EOL;
	}

}

usort($resultats, function($a, $b) {
	// clef de tri
	$ct = 'pa';
	return $b[$ct] - $a[$ct];
});

echo "CLASSEMENT!" . PHP_EOL;
foreach ($resultats as $r) {
	echo $r['id'] . "\t" . $r['pa'] . PHP_EOL;
}
echo PHP_EOL;


// Moyenne arithmétique à la con
function moyenne(array &$vs) {
	$m = 0;
	$nb = 0;
	foreach ($vs as $v) {
		$m += $v;
		++$nb;
	}
	if ($nb > 0) {
		$m = $m / $nb;
	}
	return $m;
}

// Les notes sont élevées au carré
function moyennePonderee(array &$vs) {
	$m = 0;
	$nb = 0;
	foreach ($vs as $v) {
		$m += $v*$v;
		$nb += $v;
	}
	if ($nb > 0) {
		$m = $m / $nb;
	}
	return $m;
}

// Les votes sont triés par note
// Chaque note est multipliée par le carré de ses occurrences
function moyennePPNV(array &$vs) {
	$m = 0;
	$nb = 0;
	$ts = array();
	foreach ($vs as $v) {
		if (array_key_exists($v, $ts)) {
			$ts[$v]++;
		} else {
			$ts[$v] = 1;
		}
	}
	foreach ($ts as $n => $t) {
		$m += $n * $t * $t;
		$nb += $t * $t;
	}
	if ($nb > 0) {
		$m = $m / $nb;
	}
	return $m;
}

// Médiane simple
function mediane(array $vs) {
	sort($vs);
	$c = count($vs);
	if ($c % 2 == 0) {
		$imin = $c / 2 - 1;
		$imax = $c / 2;
		$m = ($vs[$imin] + $vs[$imax]) / 2;
	} else {
		$imed = intval($c / 2);
		$m = $vs[$imed];
	}
	return $m;
}

// Somme des notes
function points(array &$vs) {
	$p = 0;
	foreach ($vs as $v) {
		$p += $v;
	}
	return $p;
}

// Raymond si tu nous regarde
function pointsCarre(array &$vs) {
	$p = 0;
	foreach ($vs as $v) {
		$p += $v * $v;
	}
	return $p;
}

// Points élevés au cube
function pointsCube(array &$vs) {
	$p = 0;
	foreach ($vs as $v) {
		$p += $v * $v * $v;
	}
	return $p;
}



// Points élevés à une valeur arbitraire
function pointsArbitraires(array &$vs) {
	$corres = array(
		1 => -2,
		2 => -1,
		3 => 1,
		4 => 10,
		5 => 100
	);
	$p = 0;
	foreach ($vs as $v) {
		$p += $corres[$v];
	}
	return $p;
}

// Somme des notes avec en additionnant $decalage à chacune (par défaut -3)
function pointsDecalage(array &$vs, $decalage = -3) {
	$p = 0;
	foreach ($vs as $v) {
		$p += $v + $decalage;
	}
	return $p;
}

?>