Универсальный рейтинг или нам важен каждый голос

в 7:13, , рубрики: mysql, Алгоритмы, интересные задачи, рейтинги, Спортивное программирование, фильмы, метки: , , ,

Универсальный рейтинг или нам важен каждый голосНедавно передо мною встала задача сортировки фильмов по рейтингу. Каждый фильм имеет 2 значения — это средняя оценка и количество прогосовавших (точно так же, как на Кинопоиске и IMDB).

Первая мысль, естественно, была о Топ-250 Кинопоиска с их формулой. Но уже при первом взгляде она показалась мне неидеальной — непонятный выбор порога входа и общая средняя оценка вводят в ступор, ведь уже при чуть-чуть измененных условиях (меньшем количестве оценок или голосов) она работает крайне плохо.

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

Суть проблемы

В теории — чем выше оценка, тем фильм интереснее и тем выше он должен выходить, но…
Лучше всего ситуацию опишут примеры.

Пример №1

Фильм №1
Количество проголосовавших — 2
Средняя оценка — 10

Фильм №2
Количество проголосовавших — 100
Средняя оценка — 7

Да, фильм №1 клевый, но вряд ли кто-то захочет ориентироваться на мнение двух человек. Из этого следует, что вести расчет, исходя только из средней оценки — глупо, и в топе у нас всегда будут «фильмы на любителя».

Универсальный рейтинг или нам важен каждый голос

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

Кинопоиск решил эту проблему введя порог голосов (M=500) и дав шансы малорекламируемым фильмам, приблизив их к средней оценке всех фильмов — чем ниже просмотров у фильма, тем на больший коэффициент поднимется его рейтинг.

Универсальный рейтинг или нам важен каждый голос

Где:

V – количество голосов за фильм
M – порог голосов, необходимый для участия в рейтинге Топ-250 (сейчас: 500)
R – среднее арифметическое всех голосов за фильм
С – среднее значение рейтинга всех фильмов (сейчас: 7.3837)

Пример №2

Теперь рассмотрим следующие 2 фильма и посчитаем их рейтинг по формуле Кинопоиска:

Фильм №1

V = 500 (количество голосов за фильм)
M = 500 (порог голосов)
R = 2 (средняя оценка фильма)
C = 7.3837 (средняя оценка всех фильмов)

Raiting = 500/(500+500) * 2 + 500/(500+500) * 7,3837 = 4,69185 (кстати формулу можно сразу вставить в калькулятор :-)

Фильм №2

V = 1000
M = 500
R = 3
C = 7.3837

Raiting = 1000/(1000+500) * 3 + 500/(1000+500) * 7,3837 = 4,4612

Фильм с вдвое меньшим количеством голосов и меньшей оценкой получил бОльший рейтинг! Скорее всего, Кинопоиску выгоден такой подход — он стимулирует голосовать и, как следствие, в бесконечном будущем дает большую объективность.

Но у меня не стояло задачи призывать пользователей к голосованию, и такой подход не подходил — ведь в каждой весовой категории в дискретный момент времени будет нечестная сортировка. Да и выбор порога неочевиден и субъективен.

Итак, задача:
Составить честный топ фильмов с учетом количества голосов и средней оценки за фильм не используя константных значений

Решение

Ладно, давай рассказывай

Долго подставляя цифры туда и обратно, мы (я и жена Катя) искали идеальную формулу, но везде натыкались на человеческий фактор. И правда, что считать важнее — количество голосов или рейтинг и как их коррелировать?

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

  1. Итак, люди больше голосуют за прорекламированный фильм, обычно это фильм с бОльшим бюджетом. Чем выше бюджет, тем выше техническое качество фильма.
  2. Да, в целом, оценка фильма понятие субъективное, но нас интересует Топ для всех и, следовательно, стоит ориентироваться на популярность (popular — общераспространенный, общепонятный).
  3. Чем больше голосов за фильм — тем объективнее мы считаем оценку.

В итоге, мы пришли к тому, что и оценка и количество голосов являются примерно равными по важности факторами, и решение пришло само собой.

Для уравнивания этих двух значений — необходимо привести их к одной шкале. Максимальное количество голосов всегда разное, а вот рейтинг (о да!) от 1 до N. Для упрощения возьмем N=10. Следовательно, задача свелась к приведению количества голосов фильма к проценту от максимально возможного среди всех фильмов.

Дальше я расскажу о реализации подхода на Mysql — так как математики задачу уже решили, а остальным, надеюсь, интересно пощупать готовенькое.

Итак, создаем таблицу

CREATE TABLE IF NOT EXISTS `films` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `raiting` float NOT NULL,
  `count_votes` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Добавляем 4 записи из примеров

Универсальный рейтинг или нам важен каждый голос

Вы, наверное, уже догадались, что для высчитывания процента голосов нам понадобится функция max и логарифм. Итак:

select @a:=POW(max(count_votes), 1/10) from films;

select id,name,raiting, count_votes, (LOG(@a,count_votes))*raiting as actual_raiting from films order by actual_raiting desc ;

Мы получаем корень из 10 от максимального количества голосов для последующего подсчета логарифма. Так мы получаем долю количества голосов конкретного фильма от максимального, приведенного к 10. И перемножаем на среднюю оценку — так мы их коррелируем.

Добро пожаловать к результатам:

Универсальный рейтинг или нам важен каждый голос

Фильм с двумя голосами имеет наименее объективную оценку и он ниже всех. Фильм №4, несмотря на малое количество голосов, существенно опережает соперников по рейтингу.

Таким образом, мы создали весовые категории фильмов (по популярности), и в каждой весовой категории сортируем их по рейтингу. Фильмы с примерно равнозначимым количеством голосов идеально сортируются по рейтингу.

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

Комплимент от шеф-повара: рейтинг актеров

Пришла пора объясниться за главную картинку статьи. Это рейтинг актеров.

После решения первой задачки — здесь решение нашлось мгновенно по тем же правилам: чем в больших фильмах снялся актер, тем он популярнее и лучше играет. Также его игра влияет на рейтинг фильма.

Итак, мы взяли максимальное количество фильмов у отдельного актера, подсчитали количество фильмов и их среднюю оценку для каждого актера и применили ту же формулу.

Вот так стал выглядеть Топ актеров

Универсальный рейтинг или нам важен каждый голос

Для тех, кому интересно посмотреть на результат: http://vk.com/droptv

Автор: arvitaly

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js