¿Cuál es una mejor manera de ordenar por una calificación de 5 estrellas?


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

Traté de usar la calificación promedio de estrellas, pero ese algoritmo falla cuando hay un pequeño número 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 2x 2 clasificación por estrellas.

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

Author: Mechanical snail, 2009-09-11

10 answers

Para su lista de las 250 mejores películas IMDB utiliza una estimación bayesiana . Esta es una buena manera de tener en cuenta el número de votantes.

De aquí:

La fórmula para calcular la Parte superior Clasificado 250 Títulos da un verdadero bayesiano estimación:

Calificación ponderada (WR) = (v ÷ (v+m)) × R +(m ÷ (v+m)) × C

Donde:

* R = average for the movie (mean) = (Rating)
* v = number of votes for the movie = (votes)
* m = minimum votes required to be listed in the Top 250 (currently 1300)
* C = the mean vote across the whole report (currently 6.8)

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

 64
Author: Martin Harris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-11 14:33:29

Puede mirar esta página para obtener un buen análisis de la clasificación por estrellas:

Http://www.evanmiller.org/ranking-items-with-star-ratings.html

Y puedes mirar esta página para obtener un buen análisis para votar arriba y abajo:

Http://www.evanmiller.org/how-not-to-sort-by-average-rating.html

Para votar arriba y abajo, desea estimar la probabilidad de que, dadas las calificaciones que tiene, la puntuación "real" (si tenía calificaciones infinitas) sea mayor que alguna cantidad(como, por ejemplo, el número similar para algún otro artículo que estás clasificando.)

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

 16
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-22 09:05:59

Evan Miller muestra un enfoque bayesiano para clasificar calificaciones de 5 estrellas: introduzca la descripción de la imagen aquí

Donde

  • nk es el número de k-calificaciones por estrellas,
  • sk es el "valor" (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 95% de confianza (basado en la Distribución posterior bayesiana) que el criterio de ordenación real es al menos tan grande como el criterio de ordenación calculado, elija z_alpha/2 = 1.65.

En Python, el criterio de ordenació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 cinco estrellas, 80 cuatro estrellas, 75 tres estrellas, 20 dos estrellas y 25 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 puede 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.


Usted 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) en general, estas fórmulas de calificación deben tender a la promedio (ponderado) clasificación.


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


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

Además, esta fórmula hace uso de la distribución de frecuencia completa not no solo el número medio de estrellas y el número de votos. Y tiene sentido que si desde un elemento con diez 5 estrellas y diez 1 estrellas debe ser tratado como tener más incertidumbre que (y por lo tanto no calificado tan alto como) un elemento con veinte calificaciones 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.

 9
Author: unutbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-08 23:50:18

Se puede ordenar por mediana en lugar de 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 ordenación.

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

Si desea asignar peso adicional al producto con 100 calificaciones de 5 estrellas, probablemente querrá ir con algún tipo de modo ponderado, asignando más peso a las calificaciones con la misma mediana, pero con más votos generales.

 7
Author: Welbog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-11 14:29:13

Bueno, dependiendo de lo complejo que quieras hacerlo, podrías tener calificaciones, además, ponderadas en función de cuántas calificaciones ha hecho la persona, y cuáles son esas calificaciones. Si la persona solo ha hecho una calificación, podría ser una calificación de shill, y podría contar para 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 estar sobrecargada artificialmente por la baja puntuación promedio de esto usuario, y debe ser ajustado.

Pero basta de complicarlo. Hagámoslo simple.

Suponiendo que estamos trabajando con solo dos valores, ReviewCount y AverageRating, para un elemento en particular, tendría sentido para mí mirar ReviewCount como esencialmente siendo el valor de "confiabilidad". Pero no solo queremos reducir los puntajes para artículos de bajo valor de revisión: una calificación de una sola estrella probablemente sea tan poco confiable como una calificación de 5 estrellas. Así que lo que queremos hacer es probablemente promedio hacia el centro: 3.

Así que, básicamente, estoy pensando en una ecuación algo como X * Promediando + Y * 3 = la-calificación-que-queremos. Para que este valor salga bien necesitamos X + Y igual a 1. También necesitamos X para aumentar en valor como ReviewCount aumenta...con un recuento de revisión de 0, x debe ser 0 (nos da una ecuación de "3"), y con un recuento de revisión infinito X debe ser 1 (que hace que la ecuación = promedio).

Entonces, ¿qué son las ecuaciones X e Y? Para la X la ecuación quiere que la variable dependiente se acerque asintóticamente a 1 como 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 - (1 / (factor^RatingCount)

Entonces podemos ajustar "factor" para que se ajuste al rango que estamos buscando.

Usé 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();

Así que no te molestes en copiarlo, da esto 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ía ajustar el valor del "factor" según sea necesario para obtener el tipo de ponderación que desea.

 6
Author: Beska,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-11 16:06:16

Si solo necesita una solución rápida y barata que funcione principalmente sin usar muchos cálculos, aquí hay una opción (suponiendo una escala de calificación de 1-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 agregar 25 y dividir por las calificaciones totales + 20, básicamente estás agregando 10 peores puntuaciones y 10 mejores puntuaciones a las calificaciones totales y luego clasificando en consecuencia.

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

Este gráfico muestra lo que sucede con las 5 calificaciones de más de 1-1000 calificaciones: 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 clasificaciones 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 se deja caer una canica en la mayoría de los lugares de este gráfico, se desplazará automáticamente hacia los productos con puntuaciones más altas y calificaciones más altas.

 3
Author: Jordan Reiter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-12 16:33:08

Obviamente, el bajo número de calificaciones pone 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 un registro de las calificaciones que cada "evaluador" en particular ha proporcionado (en relación con otros). Esto permite pesar sus votos durante el proceso de agregación.

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

 0
Author: mjv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-11 14:34:13

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

 0
Author: Yuliy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-12 17:03:48

Después de mirar por un tiempo, elijo el sistema bayesiano. Si alguien está usando Ruby, aquí una gema para ello:

Https://github.com/wbotelhos/rating

 0
Author: Washington Botelho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-11 22:10:05

Recomiendo encarecidamente el libro Programming Collective Intelligence de 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.

 -1
Author: Andiih,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-11 15:01:56