2009-09-11 35 views
54

Estoy tratando de clasificar un grupo de productos por calificaciones de clientes usando un sistema de 5 estrellas. El sitio que estoy configurando no tiene muchas clasificaciones y continúa agregando nuevos productos, por lo que generalmente tendrá algunos productos con un número bajo de calificaciones.¿Cuál es una mejor manera de ordenar por una calificación de 5 estrellas?

He intentado utilizar la calificación promedio de estrellas, pero ese algoritmo falla cuando hay un pequeño número de calificaciones.

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

¿No debería aparecer el segundo producto más alto porque es estadísticamente más confiable debido a la mayor cantidad de calificaciones?

+0

La forma correcta de hacerlo es la media, y para los artículos que aún no han sido clasificados, tener un estado de "no clasificado". ¿Cómo lo intentaste? ¿Cómo falló? – David

Respuesta

61

Para su lista de 250 mejores películas, IMDB usa un . Esta es una buena forma de tener en cuenta el número de votantes.

De here:

La fórmula para el cálculo de los Top nominal 250 Títulos da una verdadera 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 el Top 250, solo se consideran los votos ordinarios de .

+0

El artículo de wiki answers sugiere que la fórmula es WR = (v * R + m * C)/(v + m) que parece más probable a medida que C se toma en cuenta y los valores que obtengo parecen mejores. –

+2

La fórmula es realmente la misma, debe poner la original incorrectamente como (v/(v + m)) * R + (m/(v + m)) * C es lo mismo que (v * R + m * C)/(v + m).Enlace: http://goo.gl/IW9s1A – ParoX

7

Puede ordenar por median 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 clasificación.

Puede usar un mode con el mismo efecto, pero la mediana es probablemente una mejor idea.

Si desea asignar peso adicional al producto con 100 calificaciones de 5 estrellas, es probable que desee ir con algún tipo de modo ponderado, asignando más peso a las calificaciones con la misma mediana, pero con más votos en general .

+0

Si tuviera que usar el método de la mediana, ¿cómo determinaría cuál debería ser calificado como una mejor calificación de 5 estrellas de 5 estrellas con 4x de 2 estrellas o 5 de 5 estrellas con 4 de 1 calificación de estrellas? Ambos obtendrían 5 para la calificación. – Vizjerai

+0

Eso depende de usted en ese momento. Depende de lo que pienses que es superior. Tal vez clasifique primero por mediana, luego por medio. O tal vez primero por mediana, luego por el número total de votos. – Welbog

+0

Medida ponderada: ordena primero por la mediana, luego por la media. El número total de votos mejora la confiabilidad (nivel de confianza) del puntaje, pero no dice nada sobre el puntaje en sí mismo. – richardtallent

0

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

Un elemento clave para mejorar la calidad de una calificación agregada es "calificar al evaluador", es decir, controlar las clasificaciones que cada "evaluador" ha proporcionado (en relación con los demás). Esto permite ponderar sus votos durante el proceso de agregación.

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

-1

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

+1

Aunque puedo recomendar ese libro a todos los interesados ​​en ese campo, su respuesta no proporciona una respuesta a la pregunta. –

6

Bueno, dependiendo de qué tan complejo quieras hacerlo, podrías tener calificaciones adicionales según la cantidad de calificaciones que haya hecho la persona y sus calificaciones.Si la persona solo ha hecho una calificación, podría ser una calificación de shill, y podría contar por 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 artificialmente abrumada por la puntuación promedio baja de este usuario, y debe ser ajustado.

Pero lo suficiente como para que sea complejo. Hagámoslo simple.

Suponiendo que estamos trabajando con solo dos valores, ReviewCount y AverageRating, para un elemento en particular, me parece lógico que considere que ReviewCount es esencialmente el valor de "fiabilidad". Pero no solo queremos reducir los puntajes de los artículos con bajo puntaje de ReviewCount: una calificación de una estrella es probablemente tan poco fiable como una calificación de 5 estrellas. Entonces, lo que queremos hacer es probablemente el promedio hacia el medio: 3.

Así que, básicamente, estoy pensando en una ecuación algo así como X * AverageRating + Y * 3 = the-rating-we-want. Para hacer que este valor salga bien, necesitamos que X + Y sea igual a 1. También necesitamos que X aumente de valor a medida que aumenta el valor de Revisión ... con un conteo de revisión de 0, x debe ser 0 (dándonos una ecuación de " 3 "), y con un recuento de revisión infinito X debe ser 1 (lo que hace que la ecuación sea igual a la media).

¿Cuáles son las ecuaciones X e Y? Para la ecuación X, la variable dependiente se aproxima asintóticamente a 1 cuando la variable independiente se aproxima al infinito. Un buen conjunto de ecuaciones es algo así 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 adaptarse a la gama que estamos buscando

he utilizado este sencillo programa en C# para tratar 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 se molestan copia en, 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, puede ajustar el valor de "factor" según sea necesario para obtener el tipo de ponderación que desea.

16

Usted puede mirar en esta página para obtener un buen análisis para la categoría:

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

Y se puede ver en esta página para obtener un buen análisis para un máximo y votantes abajo:

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

Para votar arriba y abajo, quiere estimar la probabilidad de que teniendo en cuenta las calificaciones que tiene, la puntuación "real" (si tiene clasificaciones infinitas) es mayor que alguna cantidad (como, por ejemplo, el simil número de ar para otro artículo que está ordenando.)

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

+4

Los intervalos de confianza de Wilson solo funcionan para distribuciones binomiales (p. Ej., Clasificaciones de estilo + 1/-1); no está claro qué enfoque tomar para algo así como un esquema de calificación de 5 estrellas. – Alec

+0

Aquí está su artículo para los sistemas de clasificación por estrellas: http://www.evanmiller.org/ranking-items-with-star-ratings.html –

3

Si sólo necesita una solución rápida y barata que la mayoría va a funcionar sin necesidad de utilizar una gran cantidad de cálculo que aquí está una opción (suponiendo una escala de calificación 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 

Mediante la adición de 25 y dividiendo por el las calificaciones totales + 20 básicamente están agregando 10 puntajes más desfavorables y 10 mejores puntajes a las clasificaciones totales y luego ordenando en consecuencia.

Esto tiene problemas conocidos. Por ejemplo, recompensa injustamente a los productos de baja calificación con pocas calificaciones (como this graph demuestra, los 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 + califican más cerca de 1.05). También podría argumentar que castiga injustamente productos de alta calidad con pocas calificaciones.

Esta gráfica muestra lo que sucede durante los 5 clasificaciones sobre 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

se puede ver la caída hacia arriba en las puntuaciones muy inferiores, pero en general es una clasificación justa, creo. También puede ver 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 deja caer una canica en la mayoría de lugares en este gráfico, se va a rodar de forma automática hacia productos de ambas puntuaciones más altas y las calificaciones más altas.

0

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.

7

Evan Miller shows un enfoque bayesiano para la clasificación de 5 clasificaciones de estrellas: enter image description here

donde

  • nk es el número de clasificaciones k -STAR,
  • sk es el "valor" (en puntos) de k estrellas,
  • N es el número total de votos de
  • K es la cantidad máxima de estrellas (p. Ej. 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 un 95% de confianza (basado en la distribución posterior bayesiana) 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 elemento tiene más de 60 cinco estrellas, 80 de cuatro estrellas, 75 de tres estrellas, 20 dos-estrellas y 25 estrellas, luego su calificación global de estrellas sería de aproximadamente 3.4:

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

y se 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 pueden tener más calificaciones en el valor global estrellas.


Usted encontrará que esta fórmula tiende a dar una calificación general que es un poco más baja que la calificación global informado por sitios como Amazon, Ebay o Wal-Mart particularmente cuando hay pocos votos (decir, menos de 300). Esto refleja la mayor incertidumbre que viene con menos votos. A medida que el número de votos aumente (en miles), todas estas fórmulas de clasificación deberían tener una calificación promedio de (ponderada).


Puesto que la fórmula solo depende de la distribución de frecuencias de calificaciones de 5 estrellas para el artículo en sí mismo, es fácil combinar opiniones de múltiples fuentes (o, actualización la calificación global a la luz de nuevos votos) simplemente agregando las distribuciones de frecuencia juntas.


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

Además, esta fórmula hace uso de la distribución de frecuencias completa, no solo de el número promedio de estrellas y el número de votos. Y tiene sentido que sea dado que un artículo con diez estrellas y diez estrellas debería tratarse como con más incertidumbre que (y por lo tanto no tan alta como) un elemento 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.

Cuestiones relacionadas