Алгоритм популярности пользователя на сайте — «Нестандартный подход к стандартным вещам»

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



Сначала я проведу линию для вас разных алгоритмов рейтинга:
I — Пользователи получают только "+"
Основные преимущества:
  • Нету заморочек.
  • Минимальные нагрузки на сайт и базу.

Недостатки:
  • один человек, один балл.
  • Личный авторитет на сайте/форуме ничего не стоит. Ты одна единица и все.


II — Пользователи получают "+" и "-"
Больших отличий мало от прошлой системы. Добавилось еще одно поле в базе.
Основные преимущества:
  • Нету заморочек.
  • Минимальные нагрузки на сайт и базу.

Недостатки:
  • один человек, один балл.
  • Личный авторитет на сайте/форуме ничего не стоит. Ты одна единица и все.


III — гипербола от @klim-danilovklim-danilov
Да, это довольно интересная идея но для оценки материала. Но не пользователей.
Основные преимущества:
  • «вес каждого плюса или минуса постоянно уменьшается в два раза, в порядке хронологии.
    То есть первый юзер ставит плюс весом в +50 балла, следующий ставит плюс весом в +25 балла, минус в -50 балла, минус в -25, минус в -12,5 баллов»

Недостатки:
  • Каждый последующий голос уже имеет меньший вес.
  • Система еще не закончена.


IV — среднее статистическое
Одна из самых распостраненных систем. В основе лежит общая сумма проголосовавших и общий бал деленный друг на друга.
Основные преимущества:
  • Система давно проверена и работает.
  • Не высокие затраты ресурсов.

Недостатки:
  • Пользователю дано право голосовать с минимума до максимума. А обычно по статистике пользователи ставят самый низкий балл или самый высокий.
  • Система для оценки исключительно материала.


V — плавающая система
В основе принципа лежит изменение кармы в сторону плюса или минуса.
Основные преимущества:
  • Пожалуй самая лучшая система для оценки пользователей/материала.
  • Не высокие затраты ресурсов.

Недостатки:
  • И снова. Твой авторитет на сайте/форуме в рейтенговой системе ничего не стоит.


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

В основе алгоритма лежит геометрическая фигура «прямоугольного треугольника».
Да порой в геометрии мы можем найти вполне необычные вещи.

Почему был избран именно треугольник?
Дело в том что высота треугольника может соответствовать рейтингу пользователя который ставит оценку.
Длина треугольнка рейтингу которому ставят оценку. А гипотенуза как раз та разнице между авторитетами пользователей.

Теперь приступим к самому интересному.
$a = 254; // Рейтинг пользователя голосующего
$b = 47;  // Рейтинг пользователя получающего голос

/* Установим стандартные цифры, которые можно встретить на любом форуме*/


if($b<=0){ $b=1; }
/* Проверяем наличие нуля и отрицательного числа в переменной $b */

###	Получаем квадрат стороны А * 2	###
$aInSquare = ($a * 2) * ($a * 2);

/* Сейчас вы спросите, а почему мы увеличиваем значение переменной в 2 раза?
Методом научного тыка, я увидел что когда у переменной $a число больше в 2 раза, то и результат получается более естественным */

###	Получаем квадрат стороны B	###
$bInSquare = $b * $b;


###Получаем квадрат стороны гипотенузы	###
$cInSquare = $bInSquare + $aInSquare;



###	Получаем длину гипотенузы###
$c = sqrt($cInSquare);


$result = (int) round($c / $b);
/* Делим полученный результат гипотенузы на содержимое стороны $b и сводим значение в целое с помощью округления и превращения числа в int */

if($result > $b / 2){ $result = (int) round($b / 2); }
/* Проверим чтоб пользователю не прилетело слишком много баллов. Если ему поставл очень авторитетный человек, то карма максимум возрастет на 50% */


var_dump($result);
/* А в конце мы получим ответ 11, это число как раз адекватно поднимит карму пользователя. */
?>

Может кто-то спросит. А почему не использовал формулу $result = ($a * 2) / $b;?
Данная формула не адекватно работает когда $a меньше $b более чем в 2 раза.

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

Итог:

После тысячи тестов с $a = rand(0,99999); $b = rand(0,99999);
я пришел к паре багов:
1й — делить на 0.
Исправил if($b<=0){ $b=1; }

2й — когда получающий пользователь имеет 1 балл, и получает от пользователя с 1000, то его объем получающегося становится 2000
Исправил if($result > $b / 2){ $result = (int) round($b / 2); } Максимум можно увеличить на 50%.

Бенчмарк Code-Igniter не дал результатов нагрузки (0,0000).

Всем спасибо. Ищите вдохновление во всем что видите.
Поделиться публикацией
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 56
  • 0
    Спасибо, заставили задуматься. Ваш способ кажется достаточно интересным. Попытаюсь просимулировать на текущей базе пользователей своего проекта.
    • +6
      Рейтинг голосующего равен нулю и получаем fatal error
      • 0
        А вообще идея интересная
        • 0
          Идея то не новая — здесь закладывается принцип экспертных оценок по рангам и опыту. Только пока ранги и опыт сомнительны и попахивают дедовщиной.
          • 0
            я имел в виду саму реализацию этого принципа — интуитивно чувствуется, что +- не должен быть единицей, но вот «физической» реализации принципа не встречал.
        • 0
          При умножении 0 ничего страшного не происходит. Он все равно передает вес в 1н бал.
          Протестируйте прям с этого примера.

          только выберите для вас угодный:
          $a = 0;
          $b = rand(0,5000);

          • 0
            сорри, пропустил if($b<=0){ $b=1; }
            • +1
              точно, и я пропустил. вообще, если бы автор подсветил код с помощью:
              <source lang="php">
              // code is here
              </source>
              

              то не было бы таких незамеченых вещей
            • 0
              допустим, рейтинг пользователя получающего голос $b = 0; (он еще не имеет никакого рейтинга на сайте)
              if ($result > $b / 2){ $result = (int) round($b / 2); }
              // =>
              if ($result > 0 / 2) { $result = (int) round(0 / 2); }
              // =>
              if ($result > 0) { $result = (int) round(0); }
              // =>
              if ($result > 0) { $result = 0 }
              
              • 0
                Здравый смысл говорит одно, но интерпретатор совершенно другое.
                PHP 5.2
                • 0
                  Простите, я сам протупил.
                  if($b <= 0){ $b = 1; }
                  • 0
                    =))) вот потому надо было подсветить код
          • +3
            У вас учитывается голый результат голосовалки пользователей. В оценки материала или того же пользователя стоит обращать еще внимание на качество источника оценки. Если это дискуссионные форумы — то в расчет можно брать:
            а) Активность в том или ином разделе с оценкой его активности и качества информации другими пользователями
            б) Опыт (срок пребывания) с учетом частоты посещения
            в) Оценка полезности (если ресурс с адекватными личностями — то может быть рассчитан)
            г) Законопослушность и чистоту аккаунта
            д) другие характеристики.

            Голая цифра плюсов или минусов не защищает алгоритм от фобов. А вот они массой могут любую статистику поломать фанатично гонясь за самоутвержденного идола.

            И все-таки — это имхо, которым может быть можно было бы дополнить ваши изыскания =)
            • –3
              кстати, автор — СИшник?
              откуда такое обилие depracated "#" и "/**/" в коде для комментариев вместо "//"? )
              • 0
                Это привычка комментариев крупных кусков и выделений важных элементов.
                • +6
                  depracated "#" и "/**/"


                  Кхм… Пруфом не поделитесь?
                  • +2
                    Написано Comments starting with '#' are now deprecated in .INI files. (http://php.net/manual/en/migration53.deprecated.php)

                    Я был бы признателен, если бы кто-то прояснил ситуацию, причем здесь .INI файлы
                    • +1
                      Я имел ввиду depracated "#", но не "/**/"

                      Но пруф что-то не нашел. Возможно, что перепутал. Единственное, что нашел
                      Опции php.ini
                      Так же в конфигурационном файле теперь нельзя использовать Си-комментарии, то есть комментарии, начинающиеся с символа '#

                      Возможно, из-за этого и перепутал. Но, имхо, // менее шумно, чем #
                      • +2
                        Про .ini я видел в ченжлоге, а вот про .php — нет. Скорее всего, Вы перепутали.
                        • +1
                          скорее всего так. забираю слова про deprecated.
                    • –3
                      Я извиняюсь, но deprecated.
                    • +1
                      Сразу подумалось что аналогия с гипотенузой не совсем правильная. Помоему было бы правильней рассматривать как сумму векторов, конкретно в вашему случае это ничего не меняет в рассчетах. Зато можно добится интересного эффекта если делать карму многомерной ;)
                      • +14
                        >Зато можно добится интересного эффекта если делать карму многомерной ;)

                        — У меня карма длиннее, чем у тебя!
                        — А у меня зато толще!
                        • +3
                          Ну это же логично, кто-то пишет новости, а кто-то хорошо и по делу комментирует, но совершенно не может ничего своего написать и т.п.
                      • +18
                        Еще раз посмотрел код. Он на самом деле избыточен. У вас излишняя увлеченность комментариями (много лишних комментариев в коде — это плохо). Лучше заменить их более внятным кодом.

                        Например кусок
                        $result = (int) round($c / $b);
                        /* Делим полученный результат гипотенузы на содержимое стороны $b и сводим значение в целое с помощью округления и превращения числа в int */
                        

                        Комментарий полностью повторяет код. Зачем? Он — лишний и мешает восприятию.
                        И теорему Пифагора все знают. Зачем её повторять в комментариях? Может еще и мануал по функциям процитировать?
                        По-моему всем разработчикам надо запретить пользоваться комментариями и разрешать только тогда, когда они научатся писать такой код, чтобы он был понятным и без комментариев.
                        Весь код можно сократить до такого вида и уйдёт большинство непоняток:

                        function hypotenuseKarmaChange ($userKarma, $targetKarma) {
                        	// Экспериментально определено, что умножение на два делает результат более естественным
                        	// При значениях меньше единицы карма будет уходить вниз или происходить деление на ноль
                        	$u = max(  $userKarma, 1) * 2;
                        	$t = max($targetKarma, 1);
                        
                        	$hypotenuse = sqrt($u*$u + $t*$t);
                        	$change     = round($hypotenuse / $t);
                        
                        	$maxChange  = round($t / 2);
                        	return min($change, $maxChange);
                        }
                        
                        echo hypotenuseKarmaChange(125, 18);
                        
                        • +4
                          Вообще спасибо за оптимизацию.

                          Но в данном случае главное не реализация кода, а сама идея.
                          • +3
                            ну просто идею тяжело понять, если код, который вмещается в 5 строчек распростёрся на страницу.

                            идея интересная, конечно, с этим согласен и плюс поставил.

                            только не хватает аргумента, в какую сторону изменять карму — в большую и меньшую. а тут уже надо думать пожоще. например. человек с кармой 250 минусует человека с кармой 150. а если наоборот? а если минусуют человека в глубоком минусе? и т.д.
                            • 0
                              Если взять пример моего кода, то вы получаете результат.

                              Это число 11. А отнять или добавить, это дело ваше и 1й строчки.
                              Лучше скопируйте и вставьте его на какой-то тестовый сайт ваш (я специально держу на виртуалке спец. сайт)

                              >> если минусуют человека в глубоком минусе?

                              если у пользователя 0 и меньше, то снимается исключительно по 1 баллу.
                              • +1
                                Ну я обычно делаю так:
                                shock@localhost:~> php test.php

                                Теперь понял. Согласен.
                                В топике не хватает десятка примеров, чтобы сходу оценить работу алгоритма.
                                • 0
                                  Проблема в том, что нужно привести не менее сотни примеров.
                                  начиная от
                                  negative->negative
                                  negative->positive
                                  positive->positive
                                  и так далее + сильный разброс чисел.

                                  Это нужно это видеть глазами чтоб почувствовать действие.

                                  Простите за плохое оформление темы =(
                                  Следующую статья я оформлю более интересно.
                                  • +1
                                    ну хотя бы штук десять можно написать, чтобы понять суть.
                                    и еще совет — используйте <h2> для заголовков.
                                    ничего страшного. мы ведь вас не хаим, а советуем, обсуждаем.
                        • +4
                          Я один не могу проследить логическую связь между рейтингом и гипотенузой?

                          Вообще лучше было бы внятно объяснить алгоритм на словах и формулами, обосновать, почему это стоит применять собственно к рейтингу и в конце уже привести исходный код,… желательно красивый исходный код, к примеру, как в комментарии выше.

                          Статья мне не понравилась, но тема очень интересна, не хватает таких материалов, так что, уважаемый автор, работайте над презентабельностью своих статей и пишите еще!
                          • 0
                            >> Я один не могу проследить логическую связь между рейтингом и гипотенузой?

                            C статьи:

                            Почему был избран именно треугольник?
                            Дело в том что высота треугольника может соответствовать рейтингу пользователя который ставит оценку.
                            Длинна треугольнка рейтингу которому ставят оценку. А гипотенуза как раз та разнице между авторитетами пользователей.
                            • +2
                              Может я конечно жирафлю, но разница между авторитетами пользователей это |a-b|, а гипотенуза равна корню суммы квадратов длины катетов и я все еще не могу узреть никакой связи между этими вещами
                              • 0
                                Нарисуйте треугольник.
                                Прочитайте внимательно мое сообщение.
                                Подпишите высоту как userA
                                длину как userB

                                Гипотенуза будет длиннее высоты и длинны.

                                т.е. после того как мы поделим гипотенузу на рейтинг userB

                                мы получим оценку.

                                Вот будет реальный пример:

                                Далее будет код с синтаксическими ошибка, но для наглядности он будет лучше
                                $a = 254; // Рейтинг пользователя голосующего
                                $b = 47; // Рейтинг пользователя получающего голос

                                $aInSquare = ($a * 2) * ($a * 2) = (254*2) + (254*2) = 258064; // Квадрат стороны userA * 2
                                /* Почему умножаем еще на 2? Методом научного тыка, я обнаружил что результат будет более адекватен */

                                $bInSquare = $b * $b = 47*47 = 2209; // Квадрат стороны userB

                                $c = sqrt($bInSquare + $aInSquare) = корень квадратный(258064 + 2209) = 510.16957964975;

                                $result = (int) round($c / $b) = округлим( 510.16957964975 / 47 = 10.854671… ); // Вот и получится 11, это просто число. Корректирующие условия я не привожу тут.


                                мы просто поделили userA * 2 на userB
                                Но если мы будем юзать формулу $result = $a * 2 / $b; то когда $a будет меньше $b более чем в 2 раза, то будут не правильные для нас результаты.

                                К примеру теперь
                                $a = 47
                                $b = 254

                                то

                                как мне помнится то округляется в большую сторону после 0,4
                                в данном случае результат будет равен 0.

                                Гипотенуза действует как защита от не корректных результатов.
                                если
                                $a * 2 / $b = 254 * 2 / 47 = 10,80… // как в нашем условии результаты очень схожи пока $a больше $b но иначе получается
                                $a * 2 / $b = 47 * 2 / 254 = 0.37…

                                В случае с гипотенузой менее 1 мы получить не сможем.
                          • +3
                            Немного по теме, но вот интересная статья про рейтинги типа «TOP Users» и т.д.:
                            www.evanmiller.org/how-not-to-sort-by-average-rating.html
                            • 0
                              формула вынесла мозг. но с идеей статьи согласен.
                              • +1
                                Очень интересная формула приведена в статье, жаль только в русскоязычных интернетах не удалось накопать больше информации об этом Wilson score interval, чтобы разобраться, почему эта формула выглядит именно так… прискорбно, но математическая литература на английском для меня пока слегка тяжеловата, чтобы я читал ее с удовольствием на правах хобби )
                                • 0
                                  именно какую-то такую формулу с мат. выводом я ожидал увидеть в статье под таким заголовком :)
                                • +1
                                  Не стоит забывать про такую штуку как «инфляция кармы»

                                  это когда расчет идёт в процентах. Например, если все юзеры начинают с 10 кармы, и по умолчанию добавляют 10% от своей кармы кому-то. Постепенно кама увеличивается, появляются юзеры с 100 кармы, которые выдают по 10 единиц сразу, а потом всё больше и больше.
                                  • 0
                                    Как и любая денежная система.
                                    Но будут пользователи банится и минусоваться, что в свою очередь будет сдерживать карму от сильнейшего наплыва.

                                    Идеальной системы не существует.
                                    Под каждый проект идут свои надстройки.
                                  • +1
                                    Из того, как вы описали «гиперболу» (при чем там гипербола?), получается, что:

                                    — Никакой пост не может превысить оценку в 100 баллов
                                    — Пост с миллионом голосов ЗА и пятью голосами ПРОТИВ будет иметь вес в… 3 балла.

                                    • 0
                                      Если в кратце описать, мы делали так, что у нас система учитывала:

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

                                      были еще какие-то плюшки в алгоритме, но мы просто ;*?№"* его писать и придумывать. До сих пор пашет в одном интересном проекте.

                                      И да… мы боролись с кармодрочерством. Вот как-то так.
                                      • 0
                                        Спасибо за статью!
                                        Полезно.

                                        Именно про Вашу статью я спрашивал в «q&a» «Как материалы из „Песочницы“ добавить в Избранное?», а кармы для приглашения не хватало.

                                        Теперь можно просто добавить в избранное :)
                                        • 0
                                          Спасибо, буду использовать в последующих проектах.
                                          • 0
                                            Простите за занудство, но «нестандартный» в данном случае пишется слитно.
                                            • 0
                                              Мне, как владельцу форума, не нравятся системы рейтинга, в которых происходит значительное увеличение общей кармы форума и соответственно его инфляция. Если после введения такой формулы чувак с 50 баллами будет — мегакрутой гуру, то через год-два школьник накрутит эти 50 баллов за день. Кроме того, репообмены и реповойны — крайне грустные вещи. Я себе сделал другую систему. Без репообмена и реповойн.
                                              • 0
                                                Любая система рейтинга юзер -> юзер, всегда будет с инфляцией.
                                                Главное не допустить гиперинфляции

                                                А если темпы будут не более 1-3% в день, то это еще допустимо.

                                                Можно какой-то N- период уменьшат карму пользователе в процентах (чтоб не было обделенных).

                                                Подобная система может регулироваться финансовыми принципами.
                                                • 0
                                                  Финансовые принципы — это прекрасно. Именно поэтому я сделал так, что при выставлении балла кому-то у пользователя этот балл вычитается. Это приводит к тому, что никто не шлёпает просто так, а пользуется с большой осторожностью :) Репутация имеет ценность.
                                                  • 0
                                                    Поддерживаю. Аналогично стоит + — и при голосе у человека вычитываеться + и передаеться другому. Никакой инфляции. Но проблема в том что пользователи не одобряют…
                                                    • 0
                                                      В таком случае нужно передавать на 100%, а только часть. от 10% до 50%

                                                      Остальные надстройки идут под ваш вкус.

                                                      Но лучше всего это время проведенное на форуме. Сторожила и в Африке сторожила.
                                                      Будет время подумаю что-то с этим.
                                                      • 0
                                                        ну, причёсывание пользователей — ваша задача. Что значит недовольны? :) В правилах прописано. Не хочешь тратить — не ставь. Точно как деньги. Даже монетизировать можно как-то.
                                                      • 0
                                                        Так подождите, а как происходит ввод новых поинтов в систему? Или каждому новичку на старте даётся базис и на форуме крутится константа поинтов?
                                                        • 0
                                                          баллы даются за полезные для коммъюнити вещи — добавления статей, организацию оффлайновых мероприятий…
                                                  • 0
                                                    Тема очень интересная! Но более интересует формула которая так же зависит и от активности на сайте/форуме что бы избежат накрутчиков.
                                                    • 0
                                                      Я тоже за весовую характеристику пользователей, за ней будущее. Желательно дополнить ее по авторитетности по темам, например дизайнер имеющий большую карму по тематическим сообщениям, соответственно более влияет на аналогичные сообщения чем например, проголосовав за тему где затронута медицина.

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

                                                      Самое читаемое