Ich möchte ein Ratensystem schreiben (ähnlich der imdb-Filmrate), das Ergebnismaximum beträgt 10, die mittlere Ausgabe kann eine Zahl zwischen 0 und 10 sein und sollte so angezeigt werden (2/10).

Der Benutzer kann zwischen 1 und 5 (Starts) bewerten, wobei jeder Benutzer einmal zugelassen ist.

Bedenken Sie also, dass dieses Array alle Benutzerraten enthält.

let rate = ['4', '5', '1', '2', '5', '5', '2', '1', '3', '3', '4']; // all users rates
let result = 0;

for (i = 0; rate.length > i; i++) {
  result += parseInt(rate[i]);
}

let av = result / 10;

Es funktioniert gut, aber das Problem ist, dass diese Ausgabe niemals eine hohe Rate erreicht, wie 9 oder 10. Also sollte ich ein Ziel festlegen, richtig? Mein Ceil-Ziel ist 1250, es ist gemein, wenn alle Benutzer insgesamt 1250 bewerten, sollte der Benutzer dies tun Rate 10/10 bekommen.

let av = 1250 / 10;

Aber diese Rückkehr ist natürlich selbstverständlich.

Ziel: Alle Benutzerraten wie diese anzeigen, 5/10 oder 7/10 wie die IMDB-Rate.

0
danny cavanagh 22 Feb. 2020 im 14:12

3 Antworten

Beste Antwort

Da Sie bereits durch 2 geteilt das erwartete Bewertungssystem 10 bis 5 Sterne - Sie müssen die Sterne mit 2 multiplizieren, um zum 10-System zurückzukehren.

// Convert 1-5 rating stars to 1-10 rating
const stars_to_ten = stars =>
   Math.round(stars.reduce((ten, star) => (ten += star * 2, ten), 0) / stars.length);

let result1 = stars_to_ten(['4', '5', '1', '2', '5', '5', '2', '1', '3', '3', '4']);
let result2 = stars_to_ten(['5', '5', '5', '5', '5']); 


console.log(result1); // 6
console.log(result2); // 10

Die IMDB gewichtet ihre Bewertung nach anderen nicht genannten Faktoren. Vielleicht handelt es sich also nicht um einen Mittelwert oder Median der abgegebenen Stimmen, sodass weiterhin ein gewichteter Algorithmus verwendet werden kann.

Gewichtete Bewertung nach wahrer Bayes'scher Schätzung

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

Wo:
R = Durchschnitt für den Film (Mittelwert) = (Bewertung)
v = Anzahl der Stimmen für den Film = (Stimmen)
m = Mindeststimmen, die erforderlich sind, um in den Top 250 (derzeit 25000) aufgeführt zu werden
C = die durchschnittliche Abstimmung über den gesamten Bericht (derzeit 7,0)

const bayesianWeighted = (avg, totVotes, minVotesTop = 10, mean = 7.0) =>
  (avg * totVotes + mean * minVotesTop) / (totVotes + minVotesTop);
  
const calcRating = stars => {
  const avg = stars.reduce((a, v) => (a += +v * 2, a), 0) / stars.length;
  return Number(bayesianWeighted(avg, stars.length).toFixed(1));
};



// TEST
[
  [4, 5, 1, 2, 5, 5, 2, 1, 3, 3, 4], // 6.7
  [1, 1, 1, 1, 1],                   // 5.3
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],    // 4.5
  [5, 5, 5, 5, 5],                   // 8
  [5, 5, 5, 5, 5, 5, 5, 5, 5, 5],    // 8.5
].forEach(r => console.log(calcRating(r)));
1
Roko C. Buljan 22 Feb. 2020 im 13:22
let rate = ['4', '5', '1', '2', '5', '5', '2', '1', '3', '3', '4']; // all users rates
let result = 0;

for (i = 0; rate.length > i; i++) {
  result += parseInt(rate[i]);
}

result = (result/rate.length)*2;
result = result.toFixed(2);

let rating = result+"/"+10;

console.log(rating);
0
Aman Tiwari 22 Feb. 2020 im 11:21

Sie müssen den richtigen Durchschnitt ermitteln und mit zwei multiplizieren, da 10 (gewünscht) durch 5 (Ihr Fünf-Sterne-System) geteilt wird und Sie den Durchschnitt eines Systems mit zehn erhalten.

let rate = ['4', '5', '1', '2', '5', '5', '2', '1', '3', '3', '4']; // all users rates
let result = 0;

for (i = 0; rate.length > i; i++) {
    result += parseInt(rate[i], 10);
}

let av = result / rate.length;

console.log('average', av);
console.log((av * 2).toFixed(2), 'of 10');
2
Nina Scholz 22 Feb. 2020 im 11:21