Domanda

Sto cercando di ordinare un gruppo di prodotti in base alle valutazioni dei clienti utilizzando un sistema a 5 stelle. Il sito per cui lo sto impostando non ha molte valutazioni e continua ad aggiungere nuovi prodotti, quindi di solito avrà alcuni prodotti con un basso numero di valutazioni.

Ho provato a usare la valutazione a stelle media ma quell'algoritmo fallisce quando c'è un numero limitato di valutazioni.

Esempio di un prodotto con 3 stelle a 5 stelle sarebbe meglio di un prodotto con 100 stelle a 5 stelle e 2 stelle a 2 stelle.

Il secondo prodotto non dovrebbe apparire più alto perché statisticamente più affidabile a causa del maggior numero di valutazioni?

È stato utile?

Soluzione

Prima del 2015, Internet Movie Database (IMDb) elencava pubblicamente la formula utilizzata per classificare i loro Top 250 elenco dei film. Per citare:

  

La formula per calcolare i 250 titoli più votati fornisce una vera stima bayesiana :

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

dove:

     
      
  • R = media per il film (media)
  •   
  • v = numero di voti per il film
  •   
  • m = voti minimi richiesti per essere elencati nella Top 250 (attualmente 25000)
  •   
  • C = il voto medio sull'intera relazione (attualmente 7.0)
  •   
     

Per la Top 250, vengono considerati solo i voti degli elettori regolari.

Non è così difficile da capire. La formula è:

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

Che può essere matematicamente semplificato in:

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

Le variabili sono:

  • R & # 8211; La valutazione dell'articolo. R è la media dei voti dell'articolo. (Ad esempio, se un oggetto non ha voti, la sua R è 0. Se qualcuno gli dà 5 stelle, R diventa 5. Se qualcun altro gli dà 1 stella, R diventa 3, la media di [1, 5] . E così via.)
  • C & # 8211; La valutazione media dell'articolo. Trova la R di ogni singolo elemento nel database, incluso quello corrente, e prendine la media; cioè C. (Supponiamo che ci siano 4 elementi nel database e che le loro valutazioni siano [2, 3, 5, 5] . C è 3.75, la media di quei numeri.)
  • v & # 8211; Il numero di voti per un elemento. (Per fare un altro esempio, se 5 persone hanno votato su un elemento, v è 5.)
  • m & # 8211; Il parametro sintonizzabile. La quantità di "smoothing" applicato al rating si basa sul numero di voti (v) in relazione a m. Regola m finché i risultati non ti soddisfano. E non fraintendere la descrizione di IMDb di m come "voti minimi richiesti per essere elencati" & # 8211; questo sistema è perfettamente in grado di classificare gli oggetti con meno voti di m.

Tutto ciò che fa la formula è: aggiungi m voti immaginari, ciascuno con un valore di C, prima di calcolare la media. All'inizio, quando non ci sono abbastanza dati (cioè il numero di voti è drammaticamente inferiore a m), questo fa riempire gli spazi vuoti con dati medi. Tuttavia, man mano che i voti si accumulano, alla fine i voti immaginari saranno annullati da quelli reali.

In questo sistema, i voti non fanno oscillare selvaggiamente la valutazione. Invece, semplicemente lo turbano un po 'in una certa direzione.

Quando ci sono zero voti, esistono solo voti immaginari e tutti sono C. Quindi, ogni elemento inizia con un punteggio di C.

Vedi anche:

  • Una demo . Fai clic su " Risolvi " ;.
  • Un'altra del sistema di IMDb.
  • Una spiegazione di un simile sistema bayesiano di classificazione a stelle.

Altri suggerimenti

Vedi questa pagina per una buona analisi della stella sistemi di valutazione basati su, e questo per una buona analisi dei sistemi basati su voti positivi / negativi.

Per il voto su e giù vuoi stimare la probabilità che, dati i voti che hai, il "reale" il punteggio (se hai un numero infinito di valutazioni) è maggiore di una quantità (come, diciamo, il numero simile per qualche altro oggetto con cui stai ordinando).

Vedi il secondo articolo per la risposta, ma la conclusione è che vuoi usare la fiducia di Wilson. L'articolo fornisce l'equazione e il codice di esempio di Ruby (facilmente traducibile in un'altra lingua).

Evan Miller mostra un approccio bayesiano alla classifica 5- stelle: inserisci qui la descrizione dell'immagine

dove

  • nk è il numero di k -star rating,
  • sk è il valore di "quotazione" (in punti) di k stelle,
  • N è il numero totale di voti
  • K è il numero massimo di stelle (ad es. K = 5, in un sistema di valutazione a 5 stelle)
  • z_alpha / 2 è il quantile 1 - alpha / 2 di una distribuzione normale. Se vuoi il 95% di fiducia (basato sulla distribuzione posteriore bayesiana) che il criterio di ordinamento effettivo sia almeno pari al criterio di ordinamento calcolato, scegli z_alpha / 2 = 1.65.

In Python, il criterio di ordinamento può essere calcolato 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))

Ad esempio, se un articolo ha 60 cinque stelle, 80 quattro stelle, 75 tre stelle, 20 due stelle e 25 una stella, la sua valutazione complessiva in stelle sarebbe circa 3,4:

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

e puoi ordinare un elenco di valutazioni a 5 stelle 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)]

Questo mostra l'effetto che più valutazioni possono avere sul valore complessivo della stella.


Scoprirai che questa formula tende a dare un punteggio complessivo che è un po ' inferiore alla valutazione complessiva riportata da siti come Amazon, Ebay o Wal-mart in particolare quando ci sono pochi voti (diciamo, meno di 300). Questo riflette il maggiore incertezza che arriva con meno voti. All'aumentare del numero di voti (in migliaia) nel complesso tutte queste formule di rating dovrebbero tendere al valutazione media (ponderata).


Poiché la formula dipende solo dalla distribuzione di frequenza delle classificazioni a 5 stelle per l'articolo stesso, è facile combinare recensioni da più fonti (o, aggiorna la valutazione complessiva alla luce dei nuovi voti) semplicemente aggiungendo la frequenza distribuzioni insieme.


A differenza della formula di IMDb, questa formula non dipende dal punteggio medio in tutti gli articoli, né un numero minimo artificiale di voti per il voto.

Inoltre, questa formula si avvale della distribuzione della frequenza completa, non solo il numero medio di stelle e il numero di voti. E ha senso che dovrebbe poiché un oggetto con dieci 5 stelle e dieci 1 stella dovrebbe essere trattato come avere più incertezza rispetto a (e quindi non valutato come) un oggetto con venti valutazioni a 3 stelle:

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 formula di IMDb non ne tiene conto.

Puoi ordinare per mediana invece della media aritmetica. In questo caso entrambi gli esempi hanno una mediana di 5, quindi entrambi avrebbero lo stesso peso in un algoritmo di ordinamento.

Puoi usare una mode con lo stesso effetto, ma la mediana è probabilmente una idea migliore.

Se si desidera assegnare un peso aggiuntivo al prodotto con 100 valutazioni a 5 stelle, è probabile che si desideri utilizzare una sorta di modalità ponderata, assegnando più peso alle valutazioni con la stessa mediana, ma con più voti complessivi.

Bene, a seconda di quanto tu voglia renderlo complesso, potresti avere anche le valutazioni ponderate in base a quante valutazioni ha fatto la persona e quali sono quelle valutazioni. Se la persona ha solo una valutazione, potrebbe essere una valutazione shill e potrebbe contare per meno. Oppure, se la persona ha valutato molte cose nella categoria a, ma poche nella categoria b, e ha una valutazione media di 1,3 su 5 stelle, sembra che la categoria a possa essere appesantita artificialmente dal punteggio medio basso di questo utente, e dovrebbe essere adattato.

Ma abbastanza per renderlo complesso. Rendiamolo semplice.

Supponendo che stiamo lavorando con solo due valori, ReviewCount e AverageRating, per un particolare articolo, sarebbe logico per me considerare ReviewCount essenzialmente come & # 8220; affidabilità & # 8221; valore. Ma non vogliamo solo abbassare i punteggi per gli articoli ReviewCount bassi: una singola valutazione a una stella è probabilmente inaffidabile come una singola valutazione a 5 stelle. Quindi quello che vogliamo fare è probabilmente nella media verso il centro: 3.

Quindi, fondamentalmente, sto pensando a un'equazione simile a X * AverageRating + Y * 3 = the-rating-we-want. Per far emergere questo valore, abbiamo bisogno che X + Y sia uguale a 1. Inoltre abbiamo bisogno che X aumenti di valore all'aumentare di ReviewCount ... con un conteggio delle recensioni di 0, x dovrebbe essere 0 (dandoci un'equazione di & # 8220; 3 & # 8221;) e con una recensione infinita il conteggio X dovrebbe essere 1 (il che rende l'equazione = AverageRating).

Quindi quali sono le equazioni X e Y? Perché l'equazione X vuole che la variabile dipendente si avvicini asintoticamente 1 mentre la variabile indipendente si avvicina all'infinito. Una buona serie di equazioni è qualcosa di simile: Y = 1 / (fattore ^ RatingCount) e (utilizzando il fatto che X deve essere uguale a 1-Y) X = 1 & # 8211; (1 / (fattore ^ RatingCount)

Quindi possiamo regolare il "fattore" per adattarsi alla gamma che stiamo cercando.

Ho usato questo semplice programma C # per provare alcuni fattori:

        // 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();

Quindi non ti preoccupi di copiarlo, dà questo risultato:

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

Qualcosa del genere? Ovviamente puoi regolare il "fattore" valore secondo necessità per ottenere il tipo di ponderazione desiderata.

Se hai solo bisogno di una soluzione veloce ed economica che funzionerà principalmente senza usare molti calcoli, ecco un'opzione (supponendo una scala di valutazione 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

Aggiungendo 25 e dividendo per le valutazioni totali + 20 in pratica si aggiungono 10 punteggi peggiori e 10 punteggi migliori alle valutazioni totali e si ordina quindi di conseguenza.

Questo ha problemi noti. Ad esempio, premia ingiustamente prodotti a basso punteggio con poche valutazioni (come questo grafico dimostra, i prodotti con un punteggio medio di 1 e un solo punteggio a 1.2 mentre i prodotti con un punteggio medio di 1 e 1k + hanno un punteggio più vicino a 1,05). Si potrebbe anche sostenere che punisce ingiustamente prodotti di alta qualità con poche valutazioni.

Questo grafico mostra cosa succede per tutte e 5 le valutazioni oltre 1-1000 valutazioni: 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

Puoi vedere il calo verso l'alto con le valutazioni più basse, ma nel complesso è una classifica giusta, penso. Puoi anche guardarlo in questo modo:

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

Se lasci cadere un marmo nella maggior parte dei punti in questo grafico, verrà automaticamente spostato verso i prodotti con punteggi sia più alti che più alti.

Ovviamente, il basso numero di valutazioni pone questo problema in un ostacolo statistico. Mai meno ...

Un elemento chiave per migliorare la qualità di un rating aggregato è quello di "valutare il valutatore", vale a dire di tenere sotto controllo i rating di ciascun particolare "valutatore". ha fornito (rispetto ad altri). Ciò consente di soppesare i voti durante il processo di aggregazione.

Un'altra soluzione, più che altro da fare, è fornire agli utenti finali un conteggio (o una sua indicazione di intervallo) di voti per l'elemento sottostante.

Un'opzione è qualcosa come il sistema TrueSkill di Microsoft, in cui il punteggio è dato da mean - 3 * stddev , in cui è possibile modificare le costanti.

Dopo aver cercato per un po ', ho scelto il sistema bayesiano. Se qualcuno sta usando Ruby, ecco un gioiello per questo:

https://github.com/wbotelhos/rating

Consiglio vivamente il libro Programming Collective Intelligence di Toby Segaran (OReilly) ISBN 978-0-596-52932-1 che discute su come estrarre dati significativi dal comportamento della folla. Gli esempi sono in Python, ma è abbastanza facile da convertire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top