Средневзвешенное значение

У меня есть существующее веб-приложение, которое позволяет пользователям «оценивать» предметы на основе их сложности. (От 0 до 15). В настоящее время я просто беру среднее значение мнения каждого пользователя и представляю среднее значение из MySQL. Тем не менее, мне становится ясно (и мои пользователи), что взвешивание чисел было бы более уместным.

Как ни странно, несколько часов работы в Google не сильно выросли. Я нашел две статьи, которые показывали системы рейтингов на сайте, основанные на «байесовских фильтрах» (которые я частично понимаю). Вот один пример:

Формула:

WR = (V / (V + M)) * R + (M / (V + M)) * C

Где:

* WR=Weighted Rating (The new rating) * R=Average Rating (arithmetic mean) so far * V=Number of ratings given * M=Minimum number of ratings needed * C=Arithmetic mean rating across the whole site 

Мне нравится идея увеличения взвешивания на основе общего количества голосов за элемент … однако, поскольку уровни сложности на моем сайте могут резко варьироваться от элемента к элементу, принимая «С» (средний арифметический рейтинг по всему сайт) недействителен.

так, повторим мой вопрос:

Используя MySQL, PHP или и то, и другое, я пытаюсь получить среднее значение арифметики:

 (5 + 5 + 4)/3 = 4.67 (rounded) 

… к средневзвешенному значению:

 rating / weight 5 / 2 (since it was given 2 times) 5 / 2 4 / 1 (sum[(rate * weight)])/(sum of weights) (5 * 2) + (5 * 2) + (4 * 1) / (2 + 2 + 1) (24)/(5) = 4.8 

    Это простой пример того, как это сделать непосредственно в MySQL. Конечно, вам нужно будет добавить условие на подзапрос, чтобы получить только голоса за соответствующий элемент, а не все голоса.

    
     mysql> создавать таблицы голосов (голос int);
     Запрос ОК, 0 строк затронуты (0,01 сек)
    
     mysql> вставить в значения голосов (5), (5), (4);
     Query OK, 3 ряда (0.00 sec)
     Записи: 3 Дубликаты: 0 Предупреждения: 0
    
     mysql> выберите * из голосов;
     + ------ +
     |  голосовать |
     + ------ +
     |  5 |
     |  5 |
     |  4 |
     + ------ +
     3 ряда в наборе (0,00 сек)
    
     mysql> выбирать голос, считать (голосовать), голосовать * подсчитывать (голосовать) от голосов голосов путем голосования;
     + ------ + ------------- + ------------------ +
     |  голосовать |  счет (голос) |  голосование * кол-во (проголосовать) |
     + ------ + ------------- + ------------------ +
     |  4 |  1 |  4 |
     |  5 |  4 |  20 |
     + ------ + ------------- + ------------------ +
     2 ряда в наборе (0,00 сек)
    
     mysql> select sum (vt) / sum (cnt) FROM (select 
     кол-во (проголосовать) * count (vote) as cnt, vote * count (vote) * count (vote) 
     как vt от голосов голосов путем голосования) a;
     + ------------------ +
     |  sum (vt) / sum (cnt) |
     + ------------------ +
     |  4.8000 |
     + ------------------ +
     1 строка в наборе (0,00 сек)
    
    
    

    Что дало понять, что взвешивание будет более уместным? Что вы видите в арифметическом значении, которое вам не полезно? Мне любопытно, потому что кажется, что ответ, который вы ищете, может не всегда соответствовать вашим потребностям. (Кроме того, 16-балльная шкала обычно намного больше, чем требуется большинству людей, люди редко различают так много точек и склонны группировать свои ответы вокруг избранной группы ответов.)

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

    Вы могли бы также рассмотреть возможность использования вычислений, отличных от средних баллов, может быть, процент топ-N-box (процент респондентов, дающих рейтинги уровня N сверху).

    В противном случае, формула для вашего среднего значения – сумма (ответ * счетчик * счет) / сумма (счетчик * счет) …

     select sum(response*ct*ct)/sum(ct*ct) from ( select response, count(response) as ct from your_table group by response) data 

    Извините, если синтаксис не является точным, у меня нет MySQL на работе.

    Обратите внимание, что вам может потребоваться преобразовать суммы из ints в float; не уверен точно, как это работает в MySQL. В SQL Server вы должны указать одну из сумм, чтобы понять, что вам не нужна интегральная средняя.