Pregunta

Estoy tratando de ordenar un grupo de productos según las calificaciones de los clientes utilizando un sistema de 5 estrellas. El sitio para el que estoy configurando esto no tiene muchas clasificaciones y continúa agregando nuevos productos, por lo que generalmente tendrá algunos productos con un bajo número de clasificaciones.

Intenté usar la calificación promedio de estrellas, pero el algoritmo falla cuando hay una pequeña cantidad de calificaciones.

Ejemplo: un producto que tiene calificaciones de 3x 5 estrellas se mostraría mejor que un producto que tiene calificaciones de 100x 5 estrellas y calificaciones de 2x 2 estrellas.

¿No debería aparecer el segundo producto más alto porque es estadísticamente más confiable debido al mayor número de clasificaciones?

¿Fue útil?

Solución

Antes de 2015, la base de datos de películas en Internet (IMDb) enumeraba públicamente la fórmula utilizada para clasificar su Lista de películas Top 250 . Para citar:

  

La fórmula para calcular los 250 títulos más valorados proporciona una estimación bayesiana verdadera :

weighted rating (WR) = (v ÷ (v+m)) × R + (m ÷ (v+m)) × C
     

donde:

     
      
  • R = promedio de la película (media)
  •   
  • v = número de votos para la película
  •   
  • m = votos mínimos requeridos para ser incluidos en el Top 250 (actualmente 25000)
  •   
  • C = el voto medio en todo el informe (actualmente 7.0)
  •   
     

Para los 250 principales, solo se consideran los votos de los votantes regulares.

No es tan difícil de entender. La fórmula es:

rating = (v / (v + m)) * R +
         (m / (v + m)) * C;

Que se puede simplificar matemáticamente para:

rating = (R * v + C * m) / (v + m);

Las variables son:

  • R & # 8211; El propio rating del artículo. R es el promedio de los votos del ítem. (Por ejemplo, si un elemento no tiene votos, su R es 0. Si alguien le da 5 estrellas, R se convierte en 5. Si alguien más le da 1 estrella, R se convierte en 3, el promedio de [1, 5] . Y así sucesivamente.)
  • C & # 8211; La calificación promedio del ítem. Encuentre la R de cada elemento en la base de datos, incluido el actual, y tome el promedio de ellos; eso es C. (Supongamos que hay 4 elementos en la base de datos, y sus calificaciones son [2, 3, 5, 5] . C es 3.75, el promedio de esos números).
  • v & # 8211; El número de votos para un artículo. (Para dar otro ejemplo, si 5 personas han emitido votos sobre un elemento, v es 5.)
  • m & # 8211; El parámetro sintonizable. La cantidad de " suavizado " aplicado a la calificación se basa en el número de votos (v) en relación con m. Ajusta m hasta que los resultados te satisfagan. Y no malinterprete la descripción que hace IMDb de m como " votos mínimos requeridos para ser listados " & # 8211; este sistema es perfectamente capaz de clasificar elementos con menos votos que m.

Todo lo que hace la fórmula es: sumar m votos imaginarios, cada uno con un valor de C, antes de calcular el promedio. Al principio, cuando no hay suficientes datos (es decir, el número de votos es dramáticamente menor que m), esto hace que los espacios en blanco se llenen con los datos promedio. Sin embargo, a medida que se acumulan los votos, eventualmente los votos imaginarios se ocultarán con los reales.

En este sistema, los votos no causan que la calificación fluctúe de manera salvaje. En su lugar, simplemente lo perturban un poco en alguna dirección.

Cuando hay cero votos, solo existen votos imaginarios, y todos son C. Por lo tanto, cada elemento comienza con una calificación de C.

Ver también:

Otros consejos

Consulte esta página para un buen análisis de la estrella basados ??en sistemas de clasificación, y éste para un buen análisis de los sistemas basados ??en upvote / downvote.

Para la votación ascendente y descendente, desea estimar la probabilidad de que, dadas las calificaciones que tiene, el " real " la puntuación (si tuviste calificaciones infinitas) es mayor que cierta cantidad (como, por ejemplo, el número similar para algún otro elemento contra el que estás clasificando).

Vea el segundo artículo para la respuesta, pero la conclusión es que desea utilizar la confianza de Wilson. El artículo proporciona la ecuación y el código de muestra de Ruby (traducido fácilmente a otro idioma).

Evan Miller muestra un enfoque bayesiano para el ranking 5- calificaciones de estrellas: ingrese la descripción de la imagen aquí

donde

  • nk es el número de k -star ratings,
  • sk vale " vale " (en puntos) de k estrellas,
  • N es el número total de votos
  • K es el número máximo de estrellas (por ejemplo, K = 5, en un sistema de clasificación de 5 estrellas)
  • z_alpha / 2 es el cuantil 1 - alpha / 2 de una distribución normal. Si desea una confianza del 95% (según la distribución bayesiana posterior) de que el criterio de clasificación real es al menos tan grande como el criterio de clasificación calculado, elija z_alpha / 2 = 1.65.

En Python, el criterio de clasificación se puede calcular con

def starsort(ns):
    """
    http://www.evanmiller.org/ranking-items-with-star-ratings.html
    """
    N = sum(ns)
    K = len(ns)
    s = list(range(K,0,-1))
    s2 = [sk**2 for sk in s]
    z = 1.65
    def f(s, ns):
        N = sum(ns)
        K = len(ns)
        return sum(sk*(nk+1) for sk, nk in zip(s,ns)) / (N+K)
    fsns = f(s, ns)
    return fsns - z*math.sqrt((f(s2, ns)- fsns**2)/(N+K+1))

Por ejemplo, si un artículo tiene 60 estrellas de cinco, 80 de cuatro estrellas, 75 de tres estrellas, 20 de dos estrellas y 25 de una estrella, entonces su calificación general de estrellas sería de aproximadamente 3.4:

x = (60, 80, 75, 20, 25)
starsort(x)
# 3.3686975120774694

y puedes ordenar una lista de calificaciones de 5 estrellas con

sorted([(60, 80, 75, 20, 25), (10,0,0,0,0), (5,0,0,0,0)], key=starsort, reverse=True)
# [(10, 0, 0, 0, 0), (60, 80, 75, 20, 25), (5, 0, 0, 0, 0)]

Esto muestra el efecto que más calificaciones pueden tener sobre el valor total de la estrella.


Encontrará que esta fórmula tiende a dar una calificación general que es un poco inferior a la calificación general reportada por sitios como Amazon, Ebay o Wal-mart Particularmente cuando hay pocos votos (digamos, menos de 300). Esto refleja la Mayor incertidumbre que viene con menos votos. A medida que aumenta el número de votos. (en los miles) todas las fórmulas de calificación en general deben atender a la Calificación media ponderada.


Dado que la fórmula solo depende de la distribución de frecuencia de las calificaciones de 5 estrellas para el elemento en sí, es fácil combinar revisiones de múltiples fuentes (o, actualice la calificación general a la luz de los nuevos votos) simplemente agregando la frecuencia distribuciones juntas.


A diferencia de la fórmula de IMDb, esta fórmula no depende de la puntuación promedio en todos los ítems, ni un valor de corte de número mínimo de votos artificial.

Además, esta fórmula hace uso de la distribución de frecuencia completa, no solo El número medio de estrellas y el número de votos. Y tiene sentido que debe, ya que un artículo con diez 5 estrellas y diez estrellas 1 debe tratarse como tener más incertidumbre que (y, por lo tanto, no está tan calificado como) un artículo con Veinte clasificaciones de 3 estrellas:

In [78]: starsort((10,0,0,0,10))
Out[78]: 2.386028063783418

In [79]: starsort((0,0,20,0,0))
Out[79]: 2.795342687927806

La fórmula de IMDb no tiene esto en cuenta.

Puede clasificar mediana en lugar de la media aritmética. En este caso, ambos ejemplos tienen una mediana de 5, por lo que ambos tendrían el mismo peso en un algoritmo de clasificación.

Podría usar un modo para el mismo efecto, pero la mediana es probablemente una mejor idea.

Si desea asignar un peso adicional al producto con 100 clasificaciones de 5 estrellas, probablemente querrá usar algún tipo de modo ponderado, asignando más ponderación a las calificaciones con la misma mediana, pero con más votos en general.

Bueno, dependiendo de qué tan complejo lo desee, puede tener calificaciones adicionales que se ponderarán según la cantidad de calificaciones que haya obtenido la persona y cuáles son esas calificaciones. Si la persona solo ha hecho una calificación, podría ser una calificación mínima y podría contar menos. O si la persona ha calificado muchas cosas en la categoría a, pero pocas en la categoría b, y tiene una calificación promedio de 1.3 de 5 estrellas, parece que la categoría a puede verse afectada artificialmente por el bajo puntaje promedio de este usuario, y debe ser ajustado.

Pero basta de hacerlo complejo. Deje que & # 8217; s sea simple.

Suponiendo que estamos trabajando con solo dos valores, ReviewCount y AverageRating, para un artículo en particular, tendría sentido para mí considerar que ReviewCount es esencialmente el & # 8220; fiabilidad & # 8221; valor. Pero no solo queremos reducir los puntajes de los artículos de ReviewCount bajos: es probable que una única calificación de una estrella sea tan poco confiable como una única calificación de 5 estrellas. Entonces, lo que queremos hacer es probablemente el promedio hacia el medio: 3.

Entonces, básicamente, estoy pensando en una ecuación algo como X * AverageRating + Y * 3 = the-rating-we-want. Para que este valor salga bien necesitamos que X + Y sea igual a 1. También necesitamos que X aumente de valor a medida que ReviewCount aumenta ... con un recuento de 0, x debe ser 0 (lo que nos da una ecuación de & # 8220; 3 & # 8221;), y con un recuento de revisiones infinito, X debe ser 1 (lo que hace que la ecuación = Calificación promedio).

Entonces, ¿qué son las ecuaciones de X e Y? Para la ecuación X, desee que la variable dependiente se aproxime asintóticamente a medida que la variable independiente se acerca al infinito. Un buen conjunto de ecuaciones es algo como: Y = 1 / (factor ^ RatingCount) y (utilizando el hecho de que X debe ser igual a 1-Y) X = 1 & # 8211; (1 / (factor ^ RatingCount)

Luego podemos ajustar el " factor " para encajar en el rango que estamos buscando.

Utilicé este sencillo programa de C # para probar algunos factores:

        // We can adjust this factor to adjust our curve.
        double factor = 1.5;  

        // Here's some sample data
        double RatingAverage1 = 5;
        double RatingCount1 = 1;

        double RatingAverage2 = 4.5;
        double RatingCount2 = 5;

        double RatingAverage3 = 3.5;
        double RatingCount3 = 50000; // 50000 is not infinite, but it's probably plenty to closely simulate it.

        // Do the calculations
        double modfactor = Math.Pow(factor, RatingCount1);
        double modRating1 = (3 / modfactor)
            + (RatingAverage1 * (1 - 1 / modfactor));

        double modfactor2 = Math.Pow(factor, RatingCount2);
        double modRating2 = (3 / modfactor2)
            + (RatingAverage2 * (1 - 1 / modfactor2));

        double modfactor3 = Math.Pow(factor, RatingCount3);
        double modRating3 = (3 / modfactor3)
            + (RatingAverage3 * (1 - 1 / modfactor3));

        Console.WriteLine(String.Format("RatingAverage: {0}, RatingCount: {1}, Adjusted Rating: {2:0.00}", 
            RatingAverage1, RatingCount1, modRating1));
        Console.WriteLine(String.Format("RatingAverage: {0}, RatingCount: {1}, Adjusted Rating: {2:0.00}",
            RatingAverage2, RatingCount2, modRating2));
        Console.WriteLine(String.Format("RatingAverage: {0}, RatingCount: {1}, Adjusted Rating: {2:0.00}",
            RatingAverage3, RatingCount3, modRating3));

        // Hold up for the user to read the data.
        Console.ReadLine();

Para no molestarte en copiarlo, da esta salida:

RatingAverage: 5, RatingCount: 1, Adjusted Rating: 3.67
RatingAverage: 4.5, RatingCount: 5, Adjusted Rating: 4.30
RatingAverage: 3.5, RatingCount: 50000, Adjusted Rating: 3.50

¿Algo así? Obviamente, podrías ajustar el " factor " valore según sea necesario para obtener el tipo de ponderación que desea.

Si solo necesita una solución rápida y barata que funcione en su mayoría sin utilizar muchos cálculos, aquí hay una opción (suponiendo una escala de calificación de 1 a 5)

SELECT Products.id, Products.title, avg(Ratings.score), etc
FROM
Products INNER JOIN Ratings ON Products.id=Ratings.product_id
GROUP BY 
Products.id, Products.title
ORDER BY (SUM(Ratings.score)+25.0)/(COUNT(Ratings.id)+20.0) DESC, COUNT(Ratings.id) DESC

Al sumar 25 y al dividir por las calificaciones totales + 20, básicamente estás sumando las 10 peores puntuaciones y las 10 mejores puntuaciones a las calificaciones totales y luego las clasificas en consecuencia.

Esto tiene problemas conocidos. Por ejemplo, premia injustamente los productos de baja puntuación con pocas calificaciones (como este gráfico demuestra, productos con un puntaje promedio de 1 y solo un puntaje de calificación un 1.2, mientras que los productos con un puntaje promedio de 1 y 1k + puntajes más cercanos a 1,05). También podría argumentar que castiga injustamente los productos de alta calidad con pocas calificaciones.

Esta tabla muestra lo que sucede con las 5 clasificaciones sobre 1-1000 clasificaciones: http://www.wolframalpha.com/input/?i=Plot3D%5B%2825%2Bxy%29/%2820%2Bx%29%2C%7Bx % 2C1% 2C1000% 7D% 2C% 7By% 2C0% 2C6% 7D% 5D

Puedes ver la caída hacia arriba en las calificaciones más bajas, pero en general es un ranking justo, creo. También puedes verlo de esta manera:

http://www.wolframalpha.com/input/?i=Plot3D%5B6-%28%2825%2Bxy%29 /% 2820% 2Bx% 29% 29% 2C% 7Bx% 2C1% 2C1000% 7D% 2C% 7By% 2C0% 2C6% 7D% 5D

Si sueltas una canica en la mayoría de los lugares de este gráfico, se desplazará automáticamente hacia productos con puntajes más altos y puntajes más altos.

Obviamente, el bajo número de calificaciones pone a este problema en una desventaja estadística. Nunca menos ...

Un elemento clave para mejorar la calidad de una calificación agregada es calificar al evaluador, es decir, mantener las pestañas de las clasificaciones de cada evaluador en particular " ha suministrado (en relación a otros). Esto permite sopesar sus votos durante el proceso de agregación.

Otra solución, más bien una solución, es proporcionar a los usuarios finales un recuento (o una indicación de rango) de votos para el elemento subyacente.

Una opción es algo así como el sistema TrueSkill de Microsoft, donde la puntuación está dada por mean - 3 * stddev , donde las constantes se pueden ajustar.

Después de mirar un rato, elijo el sistema Bayesiano. Si alguien está usando Ruby, aquí hay una joya para ello:

https://github.com/wbotelhos/rating

Recomiendo altamente el libro Programming Collective Intelligence por Toby Segaran (OReilly) ISBN 978-0-596-52932-1 que analiza cómo extraer datos significativos del comportamiento de la multitud. Los ejemplos están en Python, pero es bastante fácil de convertir.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top