Подтвердить что ты не робот

Какой лучший способ сортировать по 5-звездочному рейтингу?

Я пытаюсь сортировать кучу продуктов по отзывам клиентов, используя 5-звездную систему. Сайт, для которого я настроен, не имеет большого количества рейтингов и продолжает добавлять новые продукты, поэтому у него, как правило, будет несколько продуктов с низким рейтингом.

Я пробовал использовать средний рейтинг звезд, но этот алгоритм терпит неудачу, когда есть небольшое количество рейтингов.

Пример продукта, который имеет рейтинги 3х 5 звезд, будет отображаться лучше, чем продукт, который имеет рейтинги 100х 5 звезд и рейтинги 2 звезды 2 звезды.

Не должен ли второй продукт проявиться выше, потому что он статистически более заслуживает доверия из-за большего количества рейтингов?

4b9b3361

Ответ 1

До 2015 года База данных фильмов в Интернете (IMDb) публично перечисляла формулу, использованную для ранжирования их списка 250 лучших фильмов. Цитировать:

Формула для расчета 250 наименований с наибольшим рейтингом дает истинную байесовскую оценку:

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

где:

  • R = среднее для фильма (среднее)
  • v = количество голосов за фильм
  • m = минимальное количество голосов, необходимых для включения в список 250 лучших (в настоящее время 25000)
  • C = среднее количество голосов по всему отчету (в настоящее время 7,0)

Для Top 250 учитываются только голоса от обычных избирателей.

Это не так сложно понять. Формула:

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

Который может быть математически упрощен до:

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

Переменные:

  • R - пункт собственного рейтинга. R - среднее число голосов за элемент. (Например, если у элемента нет голосов, его R равно 0. Если кто-то дает ему 5 звезд, R становится 5. Если кто-то дает ему 1 звезду, R становится 3, среднее значение [1, 5]. И так на.)
  • C - средний рейтинг предмета. Найти R каждого элемента в базе данных, включая текущий, и взять их среднее значение; то есть C. (Предположим, что в базе данных есть 4 элемента, и их оценки [2, 3, 5, 5]. C составляет 3,75, среднее из этих чисел.)
  • v - количество голосов за элемент. (Чтобы привести другой пример, если 5 человек проголосовали за элемент, v равен 5.)
  • m - настраиваемый параметр. Количество "сглаживания", примененного к рейтингу, основано на количестве голосов (v) по отношению к m. Регулируйте m, пока результаты не удовлетворят вас. И не следует неверно истолковывать IMDb-описание m как "минимальное количество голосов, необходимое для внесения в список" - эта система отлично способна оценивать позиции с меньшим количеством голосов, чем m.

Все, что делает формула: добавьте m мнимых голосов, каждый со значением C, прежде чем вычислять среднее значение. В начале, когда данных недостаточно (т.е. Количество голосов значительно меньше m), это приводит к заполнению пробелов усредненными данными. Однако, по мере накопления голосов, в конечном итоге воображаемые голоса будут заглушаться реальными.

В этой системе голоса не приводят к резким колебаниям рейтинга. Вместо этого они просто немного возмущают его в каком-то направлении.

При нулевом количестве голосов существуют только мнимые голоса, и все они являются C. Таким образом, каждый элемент начинается с оценки C.

Смотрите также:

Ответ 2

Смотрите эту страницу для хорошего анализа звездных рейтинговых систем, а этот для хорошего анализа upvote-/систем на основе понижений.

При голосовании "вверх" и "вниз" вы хотите оценить вероятность того, что с учетом имеющихся у вас оценок "реальный" балл (если у вас было бесконечное число оценок) больше некоторого количества (например, аналогичного числа для какого-то другого элемента, который вы '). пере сортировка против).

См. Вторую статью для ответа, но вывод заключается в том, что вы хотите использовать доверие Уилсона. В статье приводится уравнение и пример кода Ruby (легко переводится на другой язык).

Ответ 3

Эван Миллер показывает байесовский подход к ранжированию рейтингов 5 звезд: введите описание изображения здесь

где

  • nk - количество оценок k -star,
  • sk - это "ценность" (в точках) звезд k,
  • N - общее количество голосов
  • k - максимальное количество звезд (например, K = 5, в рейтинговой системе с 5 звездами).
  • z_alpha/2 является квантом 1 - alpha/2 нормального распределения. Если вы хотите 95% -ную уверенность (на основе байесовского заднего распределения), что фактический критерий сортировки по крайней мере такой же, как и вычисленный критерий сортировки, выберите z_alpha/2= 1.65.

В Python критерий сортировки можно вычислить с помощью

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))

Например, если предмет имеет 60 пятизвездочных, 80 четырехзвездочных, 75 трехзвездочных, 20 двухзвездочных и 25 однозвездочных, то его общий рейтинг звезд составит около 3,4:

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

и вы можете отсортировать список 5-звездочных рейтингов с помощью

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)]

Это показывает эффект, который могут иметь более высокие оценки для общего значения звезды.


Вы обнаружите, что эта формула имеет тенденцию давать общую оценку, которая немного ниже, чем общий рейтинг, сообщенный такими сайтами, как Amazon, Ebay или Wal-mart особенно если голоса несколько (скажем, менее 300). Это отражает более высокая неопределенность, которая приходит с меньшим количеством голосов. По мере увеличения количества голосов (в тысячах), все эти рейтинговые формулы должны (взвешенный) средний рейтинг.


Поскольку формула зависит только от частотного распределения 5-звездочных оценок для самого элемента легко совместить обзоры из нескольких источников (или, обновить общий рейтинг в свете новых голосов), просто добавив частоту распределения вместе.


В отличие от формулы IMDb эта формула не зависит от средней оценки по всем пунктам, а также искусственное минимальное значение отсечки голосов.

Кроме того, эта формула использует полное распределение частот - не только среднее число звезд и количество голосов. И имеет смысл, что это так как элемент с десятью 5 звездами и десятью 1 звездами следует рассматривать как имея больше неопределенности, чем (и, следовательно, не оценивается так же сильно), как элемент с двадцать 3-звездочных оценок:

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

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

Формула IMDb не учитывает это.

Ответ 4

Вы можете сортировать median вместо среднего арифметического. В этом случае оба примера имеют медиану 5, поэтому оба будут иметь одинаковый вес в алгоритме сортировки.

Вы можете использовать mode для того же эффекта, но медиана, вероятно, является лучшей идеей.

Если вы хотите назначить дополнительный вес для продукта со 100 рейтингами 5 звезд, вы, вероятно, захотите пойти с каким-то взвешенным режимом, присвоив больший вес рейтингам с той же медианной, но с более общим количеством голосов.

Ответ 5

Ну, в зависимости от того, насколько сложным вы хотите это сделать, вы можете иметь рейтинги дополнительно взвешиваться в зависимости от того, сколько рейтингов сделал человек, и каковы эти рейтинги. Если человек сделал только один рейтинг, он может быть рейтингом шилла и может рассчитывать на меньшее. Или, если человек оценил многие вещи в категории a, но немного в категории b, и имеет средний рейтинг в 1,3 из 5 звезд, похоже, что категория a может быть искусственно отягощена низкой средней оценкой этого пользователя и следует отрегулировать.

Но достаточно сделать это сложным. Давайте сделаем это простым.

Предполагая, что для одного элемента было всего два значения: ReviewCount и AverageRating, для меня было бы разумно рассматривать ReviewCount как существенное значение "надежность". Но мы просто не хотим приводить оценки для низких элементов ReviewCount: один рейтинг одной звезды, вероятно, такой же ненадежный, как у одного 5-звездочного рейтинга. Так что мы хотим сделать, вероятно, средние по отношению к середине: 3.

Итак, в основном, я думаю об уравнении что-то вроде X * AverageRating + Y * 3 = the-rating-we-want. Для того, чтобы это значение получилось правильно, нам нужно X + Y равным 1. Также нам нужно, чтобы X увеличивался в стоимости по мере того, как ReviewCount увеличивается... с подсчетом обзора 0, x должно быть 0 (давая нам уравнение "3" ), а с бесконечным числом отсчетов X должно быть 1 (что делает уравнение = AverageRating).

Итак, каковы X и Y уравнения? Для уравнения X хотим, чтобы зависимая переменная асимптотически приближалась к 1, когда независимая переменная приближается к бесконечности. Хорошая система уравнений - это что-то вроде: Y = 1/(factor ^ RatingCount) и (используя тот факт, что X должно быть равно 1-Y) X = 1 - (1/(factor ^ RatingCount)

Затем мы можем настроить "коэффициент" в соответствии с диапазоном, который мы ищем.

Я использовал эту простую программу С#, чтобы попробовать несколько факторов:

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

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

Итак, вы не копируете его, он дает этот результат:

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

Что-то вроде этого? Вы могли бы, очевидно, настроить значение "factor" по мере необходимости, чтобы получить нужный вес.

Ответ 6

Если вам просто нужно быстрое и дешевое решение, которое будет работать в основном без использования большого количества вычислений здесь, один вариант (при условии оценки шкалы 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

Добавив в 25 и разделив общий рейтинг + 20, вы в основном добавляете 10 наихудших оценок и 10 лучших оценок к общим рейтингам, а затем сортируете соответственно.

У этого есть известные проблемы. Например, он несправедливо вознаграждает продукты с низким рейтингом с небольшим рейтингом (как этот график демонстрирует продукты со средним счетом 1 и только один рейтинг 1,2, а товары со средним рейтингом 1 и 1к + рейтинги - ближе к 1,05). Вы также можете утверждать, что он несправедливо наказывает высококачественную продукцию с несколькими рейтингами.

Этот график показывает, что происходит для всех 5 рейтингов более 1-1000 оценок: 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

Вы можете увидеть провал вверх по самым нижним рейтингам, но в целом это справедливый рейтинг, я думаю. Вы также можете посмотреть на это следующим образом:

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

Если вы бросите мрамор в большинстве мест на этом графике, он автоматически перевернется к продуктам с более высокими показателями и более высокими рейтингами.

Ответ 7

Очевидно, что небольшое количество рейтингов ставит эту проблему на статистический недостаток. Тем не менее...

Ключевым элементом повышения качества агрегированного рейтинга является "оценка rater", т.е. сохранение вкладок оценок, которые каждый конкретный "rater" предоставил (относительно других). Это позволяет взвешивать свои голоса в процессе агрегации.

Еще одно решение, более подходящее, заключается в том, чтобы предоставить конечным пользователям счет (или его диапазон) голосов за базовый элемент.

Ответ 8

Один из вариантов - это что-то вроде системы Microsoft TrueSkill, где оценка дается mean - 3*stddev, где константы могут быть изменены.

Ответ 9

Через некоторое время я выберу байесовскую систему. Если кто-то использует Ruby, вот драгоценный камень для него:

https://github.com/wbotelhos/rating

Ответ 10

Я бы очень рекомендовал книгу "Коллективный интеллект программирования" Тоби Сегарана (OReilly) ISBN 978-0-596-52932-1, в которой обсуждается, как извлечь значимые данные из поведения толпы. Примеры находятся в Python, но его достаточно легко конвертировать.