Формирование рейтинга по количеству просмотров и посещений

в 8:46, , рубрики: разработка, рейтинг, рейтинговая система, метки: ,

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

Предметная область

  • имеется веб-ресурс — каталог некоторых сущностей
  • сущности разделены на группы/каталоги
  • у каждый сущности могут быть фото, видео, отзывы, контактные данные
  • в разных категориях сущностей разные средние посещения и просмотры, последние обозначим "k"

Требования

Необходимо внедрить алгоритм сортировки внутри категорий сущностей, который зависит следующих переменных:

  • визиты сущности. Составной ключ: день + ip + id + дополнительное_поле:= «index»
  • визиты страницы с видео. Составной ключ: день + ip + id + дополнительное_поле:= «video»
  • визиты страницы с аудио. Составной ключ аналогично визиту для видео
  • визиты страницы с фото. Составной ключ аналогично визиту для видео
  • просмотры по аналогичным параметрам
  • "k" — среднее количество просмотр в каталоге за единицу времени


Фактически, визит — одна запись в таблице визитов, а просмотр — это счетчик обновляемый следующим запросом в бд:

INSERT INTO `visit` (pEssence, pMethod, tEssense, ip, ddDateCreated) 
VALUES ("%s", "%s", %d, "%s", "%s")  
ON DUPLICATE KEY UPDATE pViewsCount = pViewsCount + 1;

Причем, все визиты должны влиять на рейтинг линейно, но при росте числа просмотров скорость роста рейтинга(производная) должна замедляться, а просмотр страницы с контактами сущности должен поднимать рейтинг в два раза быстрее.
С линейными параметрами всё ясно, а для просмотров нужна формула разная для каждого каталога, которая зависит от нашего k, т.е до достижения параметра k количество просмотров «почти линейно» должно влиять на рейтинг, а после «утрачивать свое влияние». Первым в голову пришли логарифм и функция квадратного корня. Я выбрал логарифм.

Ход работы

f(x) = ln(x)
f(x)=ln(x)
Здесь видно, что на отрезке x:[1; 2] и x:[2; +infinity] график ведет почти так, как нам нужно — остается только изменить его масштаб, переместить пересечение с осью x в точку [0,0], подобрать коэффициент так, чтобы график попал в точку [k, k].

Чтобы адаптировать его под параметр k нужно будет произвести несколько преобразований:
Для наглядности возьмем k=10
Растянем график в k раз и переместим пересечение с осью x в точку [0,0]:
f(k, x)|k:=10 = 10 + 10*ln((10+x)/(10*e))
f(k, x)|<sub>k:=10</sub>=10 + 10*ln((10+x)/(10*e)))
Осталось подобрать коэффициент j:
f(k, k)*j = k => j = k/f(k, k)
j — константа, равная 1.44269504089

Интересно, что же это за число? Wolframalpha подсказывает, что это 1/ln(2), за что ему спасибо.
В итоге конечная формула имеет вид:
f(k, x) = (k + k*ln((x+k)/(k*e)))*(1.44269504089) или f(k, x) = (k + k*ln((x+k)/(k*e)))/ln(2)

Для оптимизации под бд, с помощью того же Wolframalpha, уменьшим количество умножений, делений и выделим константы:

c1(k) = k*ln(k)
c2 = 1.4426950408889634
f(k, x) = (k*ln(k + x)-c1(k))*c2

f(k, x)|k:=10
Формирование рейтинга по количеству просмотров и посещений
Что и требовалось получить.

Защита рейтинга

Первое что нужно сделать — выдавать заголовок для всех рейтинговых страниц «X-FRAME-OPTIONS: DENY» чтобы рейтинг не накручивался через i-фреймы.
Второе — это ввод геофильтра ip-адресов. В моем случае мне нужно было отсечь все адреса, которые не относятся к двум нашим мегаполисам и к их областям.
Третье — посещения записывать только с помощью javascript, чтобы осложнить работу ленивым накрутчикам. Соответственно необходимо обфусцировать сам скрипт, обфусцировать его выдачу (выдавать в случайные места страницы), создать ложные выдачи, написать генератор обфусцированного javascript-кода, обфусцировать URI приёмника запроса на обновление статистики, т.е лучше всего его сделать динамическим, который зависеть от ip-адреса и текущей даты

Идеальную защиту придумать здесь будет трудно, но так мы отнимем некоторое время на анализ защиты и отсеим ленивую/дешевую рабочую силу.

Использованные реусрсы

fooplot.com — построение графиков
wolframalpha.com — математические преобразования

Автор: frostosx

Источник

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


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