Розшифровуємо формулу Хабра-рейтингу або відновлення функціональних залежностей за емпіричними даними

Якщо ви коли-небудь читали розділ допомога на Хабре, то напевно бачили там прецікаві рядок:
Припустимо, ви написали публікацію з рейтингом +100 — це додало до вашого персонального рейтингу величину Х. Через кілька десятків днів цей самий Х вычтется, тим самим повернувши вас на колишнє місце.
то напевно задавалися питанням, що це за Х і з якого він району чому він дорівнює?

Сьогодні ми відповімо на це питання.


(вимірюємо Хабра-рейтинг у папуг)

Структура статті:
  1. Аналітичний висновок
  2. Регресія
  3. Винятки
  4. Стійка регресія
  5. Скрипт і дані
  6. Чому приховувати функцію марно
  7. Що з цим можна зробити?
  8. Інтерпретація формули


Аналітичний висновок

У цій частині ми розглянемо основні властивості, яким повинна задовольняти будь-яка функція рейтингу, і, використовуючи наші знання про предметної області, спробуємо здогадатися до конкретного виду функції.

Основні припущення
Від чого залежить рейтинг? Рейтинг будь-якого користувача формується за допомогою дій інших користувачів, а точніше їх голосування за карму, топіки і коментарі. Інших способів впливати на показники користувачів у Хабра-жителів немає. Значить, що наша функція приймає на вхід значення карми (раціональне), голосів за топикам (ціле) і коментарям (ціле) і повертає раціональне число.



Більше того, нам відомо, що карма і голоси за коментарі та топіки незалежно один від одного впливають на рейтинг, а значить, що наша тернарная функція розпадається на певну композицію трьох унарных. Припустимо, що це певна сума трьох функцій.



Яким граничним умовам повинна задовольняти будь-яка функція рейтингу? Граничні умови — будь-який новий користувач має рейтинг рівний нулю; якщо користувач не написав ні одного поста, означає, що внесок постів в рейтинг теж дорівнює нулю, etc.



Що ще ми знаємо про ці функції? Вони повинні бути монотонно зростаючими і простими для обчислення (тобто як-то просто виражатися через елементарні функції). Розглянемо найпростіший варіант — лінійна залежність по кожному з параметрів.



Висновок коефіцієнтів
Використовуючи граничні умови, ми можемо легко вивести ці коефіцієнти. Розглянемо випадок, коли тільки карма має вклад у рейтингу (тобто, немає постів і коментарів за останні 30 днів).



Підставимо значення дорівнює одній десятій в формулу:



Отримавши перший коефіцієнт, що ми можемо взяти іншого користувача, для якого один з невизначених коефіцієнтів дорівнює нулю і розрахувати другий коефіцієнт:



Підставимо 4/5 за місце бети у формулу:



І останній штрих.

Фінальна формула
Узявши будь-якого іншого користувача, і підставивши всі параметри, отримаємо, що гамма дорівнює 1/100.

Тоді, функція рейтингу від карми k, голосів за топіки t і за коментарі c дорівнює



Регресія

Зрозуміло, що формула, виведена по трьом точкам, може бути неправильна — є безліч функцій, які проходять через три точки. Тому цю гіпотезу варто перевірити. Як? Давайте спробуємо отримати ці коефіцієнти прямо з даних за допомогою класичної регресії і порівняти з отриманими.

Якщо наша гіпотеза вірна, то ми отримаємо модель з коефіцієнтами схожими з аналітичними (і високими параметрами впевненості в коректності моделі).

Дані по рейтингу і відповідним параметрам карми, голосів за пости і коментарі (там багато інших цікавих і смачних даних по Хабру) доступні тут:
github.com/SergeyParamonov/HabraData/краплі/master/users_rating.csv

Приступимо,
1478 users regular regression
Call:
lm(formula = rating ~ karma + topic_score + comment_score - 1, data = data)

Coefficients:
Estimate Std. Error t value Pr(>|t|) 
karma 0.1017172 0.0006097 166.842 < 2e-16 ***
topic_score 0.7862749 0.0020999 374.428 < 2e-16 ***
comment_score 0.0153159 0.0031884 4.804 1.72 e-06 ***

Як ми бачимо, значення коефіцієнтів по кармі і постам фактично збігається, причому, судячи з параметрами, модель досить впевнена в оцінці цих двох параметрів. Але що ж з третім параметром (внесок коментарів в рейтинг)? І звідки взагалі взялася різниця у коефіцієнтах, якщо відомо, що функція повинна бути детермінованою?

Виключення

Здавалося б, класична регресія серйозно суперечить отриманою нами формулою — розходиться в оцінці третього параметра на 50% і не збігається ідеально по двом іншим. Однак відомо, що класична регресія неймовірно нестійка до статистичних викидів. Давайте поглянемо на них, тобто набір точок, чиє значення рейтингу істотно відрізняється від отриманої нами аналітичної формули.

>data$dif <- abs(rating - karma/10 - topic_score*0.8 - comment_score/100)
>print(data[data$dif > 2, ])
user rating karma topic_score comment_score dif
akrot 80.21 25.00 91 13 4.780
anegrey 60.30 31.50 114 15 34.200
Guderian 56.02 119.00 32 6 18.460
ilusha_sergeevich 154.27 157.75 177 11 3.215
ParyshevD 69.27 42.00 130 7 39.000
PatapSmile 48.75 246.00 0 0 24.150
rw6hrm 38.81 33.00 71 1 21.300
varagian 81.34 170.00 50 34 24.000

Тут можна помітити, що автор даної статті знаходиться в списку. Чому? Тому що є стаття написана 30 днів тому, а значить вона не потрапила у вибірку даних, але при цьому голоси пропадають протягом трьох днів. Звідси виникає різниця в рейтингу і свідченнях отриманої формули.

Але це вірно не для всіх точок, наприклад візьмемо запис Guderian. У нього не є граничних статей в останні 30 днів. Звідки ж різниця? Все дуже просто. TM неправильно порахували йому рейтинг на Хабре, так як його стаття переїхала на megamozg, і саме по ній у нього є відсутні голоси за статтями.



Бінго! Ми пояснили звідки беруться невідповідні точки:
  • граничні статті, написані від 30 до 33 днів тому, з зникаючими голосами;
  • переїзди і ділення Хабра;
  • статті, прибрані в чернетки або оффтопики (НЛО чи автором).
Але все це звучить, як підгонка під відповідь, а не красива верифікація гіпотези, чи не правда? І тут на допомогу нам приходить…

Стійка регресія

Нехай у нас є набір точок-викидів у вибірці і він невеликий, ну наприклад до 5%, і достатня вибірка за користувачам (експериментально вистачає 1500 з верхом), то використовуємо методи регресії, стійкої до викидів (robust regression, а ось тут цікавий KDD tutorial по темі).

Спробуємо використовувати метод прямо з коробки:
library("MASS")
...
Call: rlm(formula = rating ~ karma + topic_score + comment_score - 1, data = data)

Coefficients:
Value Std. Error t value 
karma 0.10 0.00 23463021.30
topic_score 0.80 0.00 54494665.88
comment_score 0.01 0.00 448681.05

Вуаля, коефіцієнти знайдені і вони в точності збігаються з отриманими аналітично.

Скрипт і дані

Скачати можна тут і застосувати на цих.

Для тих кому не хочеться далеко ходити за скриптом:
R-код регресії
library("MASS")
data <- read.csv("users.csv", header=T, stringsAsFactors=F)
names(data) <- c("user","rating","karma","topic_score","comment_score")

fit <- lm(data=data, rating ~ karma + topic_score + comment_score - 1)
print("regular regression")
print(summary(fit))
fit <- rlm(data=data, rating ~ karma + topic_score + comment_score - 1)
print("robust regression")
print(summary(fit))
attach(data)
data$dif <- abs(rating - karma/10 - topic_score*0.8 - comment_score/100)
print(data[data$dif > 2, ])


Чому приховувати функцію марно

Тут звичайно ж уважний читач може сказати: «Ну ось, тепер TM доведеться придумувати нову таємну функцію підрахунку рейтингу», і саме тому в цій частині ми обговоримо чому приховувати функцію рейтингу в принципі марно.

Наведемо основні властивості рейтингу:
  • рейтинг залежить тільки від дій інших користувачів і каналів для голосування, яких всього три: голоси за пости, коментарі і карму;
  • голоси за пости, карму та коментарі незалежні один від одного, тобто функція завжди розкладається в певну композицію трьох незалежних унарных функцій від постів, коментарів і карми;
  • кожна з цих функцій має бути просто і швидко вычислима, так як показники рейтингу потрібно весь час перераховувати для великого числа користувачів;
  • з цієї ж причини, вона повинна бути можна виразити елементарних і монотонно зростаючих функцій;
  • функція повинна бути детермінованою і без шуму, i.e., для двох користувачів з рівними показниками карми, голосів за пости і коментарі рейтинг повинен бути однаковий (за ефективний період = 30 днів).
Все це дозволяє по елементарно зібраним даними відновити цю функцію автоматично, використовуючи методи стійкої регресії та підбору унарных функцій окремо один від одного. Введення шуму, недетермінованих елементів і ймовірностей всього лише трохи ускладнить завдання і можливо незначно вплине на точність параметрів.

Security through obscurity і тут не працює.

Що з цим можна зробити?

Коли я писав Хабра-монітор (це частина Хабра-аналітики, якщо ви пишіть на Хабр, то можливо ресурс буде вам корисний), який відображає зміну параметрів статті у часі, перше, що хотілося прикрутити — це зміна голосів у часі. По ряду причин цей параметр недоступний для перегляду перед голосуванням за пост. Маючи аналітичну функцію для рейтингу користувача, завжди можна вивести рейтинг його поточної статті (за умови, що вона одна і у нього немає статей, за якими голоси «пропадають» в даний момент).

Фактично, маючи дану функцію можна до монітора (картинка нижче) прикрутити параметр рейтинг статті.


Ще це дозволить СоХабру прикрутити рейтинг статей.

Інтерпретація формули

Голоси за коментарі практично не мають вкладу у рейтинг, навіть самі рейтингові коментарі за всю історію Хабра (~400+) додають до рейтингу 4-5 очок, тобто стільки ж, скільки стаття набрала 6-7 плюсів.

Карма втратила свою вагу по відношенню до рейтингу, раніше у неї було коефіцієнт 0.5, а зараз 0.1, що робить топ набагато більш динамічним (раніше увійти в топ-10 було практично нереально).

Кожні 5 голосів за статтю приносять 4 очки до рейтингу, тобто помноживши на 0.8 голоси статті, отримаємо надбавку до рейтингу. На даний момент, це самий істотний і фактично єдиний визначальний рейтинг користувача фактор.

І ще, Х = 80.

P. S. затвердження (звідси
[...] з часом рейтинг прийме значення половини карми.
вже невірно.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.