Actualización noviembre 4, 2012: Se modifica el punto 4, con la explicación del nuevo algoritmo de afinidad.

Actualización mayo 7, 2009: En la pestaña log de cada noticia se puede observar en qué momento se hicieron los reajustes de karma y las notas informativas del algoritmo.

Siempre que una noticia controvertida con varios votos negativos  (y/o que algunos piensen que no «queremos que salga» aunque le hayamos votado positivo o dado publicidad en nuestros blogs) no sale publicada surgen sospechas o conspiranoias de que «hay manipulación», aunque el algoritmo de promoción es público, como así también los cálculos que realiza.

Suele pasar porque hay parámetros que ajustan el valor del karma de la noticia y hay poca gente capaz o con tiempo para tomarse el trabajo de leer el código y  de seguir la evolución del karma de cada noticia. Para esas personas intentaré explicar el funcionamiento básico del promote, y porqué lo hemos implementado de esa forma.

Los parámetros que más afectan al karma son los siguientes, ordenados más o menos de los que más influyen a los que menos:

  1. Bonus temporal a las nuevas noticias
  2. Coeficiente por metacategorías
  3. Añejamiento de noticias antiguas
  4. Control de diversidad de votos (o de afinidad)
    Bonus y penalizaciones por análisis de densidad de grafos
  5. Control de media de votos

(Recalco lo de «más o menos», ya que depende de varios factores, por ejemplo si la media de votos de una noticia es muy baja, afectará más que los demás, pero está al último porque no se suele llegar a esos extremos, salvo casos de intento de spam con muchos usuarios nuevos o inactivos por mucho tiempo, por ejemplo)

1. Bonus temporal a las nuevas noticias

El objetivo es publicar rápidamente aquellas noticias que reciben muchos votos apenas se envió la noticia. Este algoritmo funciona desde el primer día. Básicamente multiplica el karma de la noticia por un coeficiente decreciente tempral entre 2 y 1 1.5 a 1. A las dos horas el coeficiente se hace igual a uno por lo que deja de influenciar. Este coeficiente es visible en el promote, la columna COEF. La explicación más completa.

2. Coeficiente por metacategorías

En Menéame hay cuatro metacategorías: ocio, cultura, actualidad y tecnología. El objetivo es intentar tender a un balance entre número de enviadas y publicadas en cada categoría. De esta forma también se evita que el Menéame sea monotemático –o dominado por unas pocas categorías–.

Basado en el número de enviadas / número de publicadas de cada metacategoría se calcula un coeficiente. Los coeficientes de cada una son visibles en el promote. Por ejemplo ahora mismo:

Karma coefficient for tecnología: 1.31632555175
Karma coefficient for cultura: 0.982548801982
Karma coefficient for actualidad: 0.93282154627
Karma coefficient for ocio: 0.872050062752

Los números anteriores significan que a las noticia de tecnología se multiplica por 1.31 mientras que a las de actualidad 0.92. Esos coeficientes son medias entre las enviadas y publicadas de cada una en los últimos 2 días. Están también disponibles justo arriba de los coeficientes anteriores:

2 days stats for tecnología (queued/published/total): 157/13/98 -> 0.0679107630313
2 days stats for cultura (queued/published/total): 175/19/98 -> 0.0905408163265
2 days stats for actualidad (queued/published/total): 455/44/98 -> 0.10136577708
2 days stats for ocio (queued/published/total): 176/22/98 -> 0.104336734694

Los tres números de cada meta significan respectivamente: número de enviadas, número de publicadas y publicadas totales.

3. Añejamiento de noticias antiguas

El objetivo del algoritmo es quitar progresivamente la relevancia de las noticias después de varias horas (nueve). Se hace así para evitar que salgan publicadas siempre noticias de hace varios días, ya que por razones lógicas –el tiempo que están en pendientes– las más antiguas tienen más posibilidades y probabilidad de tener más votos que una noticia reciente.

El coeficiente varía progresivamente desde 1 a 0.4 una vez que han pasado nueve horas desde que se envió la noticia. Este coeficiente es visible también en la columna COEF del promote.

La parte del código que lo calcula es:

// Aged karma
$diff = max(0, $now - ($link->date + 9*3600)); // 9 hours without decreasing
$oldd = 1 - $diff/(3600*60);
$oldd = max(0.4, $oldd);
$oldd = min(1, $oldd);
$link->new_coef = $oldd;

El añejamiento de cada noticia también funciona desde el principio del Menéame.

4. Control de diversidad de votos (o de afinidad)

El objetivo de este control es evitar que grupos de usuarios se voten las noticias entre ellos y logren publicarlas (eso que algunos dicen que existen y llaman «mafias»).

El algoritmo calcula un porcentaje de afinidad entre usuarios y decrementa el karma que «aportan» a la noticia dependiendo de la afinidad con el usuario que le envió: a mayor afinidad menor es su influencia final (aunque el voto siempre suma). Con esto se asegura que para que una noticia salga publicada tiene que haber un mínimo de diversidad de votos.

El algoritmo está explicado en detalle en otro apunte. Está activo desde principios de setiembre de este año (2008).

La parte esencial del código que calcula el coeficiente de afinidad es el siguiente:

foreach ($votes as $vote) {
	if ($vote->id > 0 &&
			$vote->id != $uid &&
			abs($vote->count) > max(1, $nlinks/10) ) {
		$c = $vote->count/$nlinks * 0.75;
		if ($vote->count > 0) {
			$affinity[$vote->id] = round((1 - $c)*100);
		} else {
			$affinity[$vote->id] = round((-1 - $c)*100);
		}
	}
}

4. Bonus y penalizaciones por análisis de densidad de grafos

El algoritmo antes de afinidad está deshabilitado desde el 5 de octubre de 2012. En su reemplazo se usan algoritmos más genéticos que permiten un mejor control. La explicación completa del nuevo algortimo.

5. Control de media de votos

El objetivo de este control es evitar que se creen usuarios nuevos –o se tengan usuarios «inactivos»– con el único objetivo de publicar noticias de un determinado sitio. Por ejemplo que se pongan de acuerdo en un foro, o que haya grupos o empresas con muchos usuarios los intenten «vender» para promocionar sitios.

El promote analiza las medias de votos en los últimos días y usa esa media para controlar que no haya desvíos importantes. La media es visible en el promote:

Karma average for each link: 9.15856554197

Esto significar que la media ponderada de los votos a cada noticia en los últimos días es igual a 9.16.

Para cada noticia se calcula cuál es la media de sus votos. Si la diferencia de la media de un enlace es inferior al 3% de la global –para permitir variaciones hacia abajo–, entonces no toma en cuenta votos inferiores a la media para hacerla como mínimo igual a 9.16 * 0.97 (el -3%) aproximadamente.

Este control funciona desde el primer semestre de 2007.

Tuvimos que hacerlo cuando empezamos a detectar los intentos de spams mediante la creación de decenas de usuarios, especialmente cuando se acercaban fechas electorales o campus parties (ademas incluimos más controles de frecuencia de registros que se pueden hacer por IP y subred).

// Make sure we don't deviate too much from the average
// (it avoids vote spams and abuses)
// Allowed difference up to 3%
$karma_pos_user = (int) $karma_pos_user_high +
                  (int) min($karma_pos_user_high * 1.07, $karma_pos_user_low);

El karma es fundamental

Espero que esta breve explicación elimine algunas dudas sobre el funcionamiento del algoritmo de promoción y que de más tranquilidad, ya que está claro que se intenta asegurar que no haya abusos y grupos que tengan más influencia –llámese mafias o fanboys— capaces de publicar noticias sólo con sus votos.

En toda la explicación de las diferentes técnicas, el parámetro fundamental que evoluciona con el tiempo es el karma –en este caso el de las noticias, pero también el de cada usuario–. Ojalá que aclare mejor lo que comentábamos hace tiempo sobre la potencia y utilidad de ese numerito que llamamos «karma» [*]:

Lo anterior creo que explica más o menos los fundamentos de tener un karma: es un sistema básico de protección “anti abusos” que evita tener que tomar medidas más “drásticas”, además hace posible el voto anónimo.

[…]

Sí, admitimos que no es perfecto, ni de lejos, pero el karma ha sido fundamental para controlar y evitar abusos sin tener que recurrir a medidas extremas y un coste de administración que hubiese sido prohibitivo para nosotros.

(y permite publicar todo, el algoritmo y sus cálculos)

[*] Es decir, la potencia de las matemáticas de nivel de ESO para hacer cálculos y controles complejos y a la vez resumirlos en un número que todos podemos entender para darnos una idea de la «situación» 🙂