Алгоритм составления Top10 чего угодно
В каждом сборнике советов о том как сделать блог более популярным есть "Напишите Top10 чего-то". Вот я решил написать Top10. Но как истинный программист, вместо 10 бессмысленных фактов написал алгоритм как правильно выбирать Top10 чего-то.
Допустим, у вас есть сайт со статьями и вы хотите сделать Top10 статей, учитывая количество их просмотров. Не торопитесь, подумайте сначала, зачем вы хотите это сделать. Наверное, чтобы показать людям статьи, которые могут быть им наиболее интересны. Но показывая одни и те же Top10, вы искусственно увеличиваете количество просмотров статей, которые находятся в топе и они, возможно, случайно туда попав, уже никогда не исчезнут. В то же время посещаемость надо учитывать, потому что всё же корреляция посещаемость-интересность есть.
В моём алгоритме, чем больше рейтинг, тем выше будет вероятность появления записи в топе и вероятность более высокого положения там. Записи с нулевым рейтингом появляются только тогда, когда показаны записи с ненулевым рейтингом и выбираются случайно.
Используется функция примерно так
-
function test() {
-
'Item with rating 10' => 10,
-
'Item with rating 8' => 8,
-
'Item with rating 5' => 5,
-
'Item with rating 3' => 3,
-
'Item with rating 1' => 1,
-
'Item with rating 0 #1' => 0,
-
'Item with rating 0 #2' => 0,
-
'Item with rating 0 #3' => 0,
-
'Item with rating 0 #4' => 0,
-
'Item with rating 0 #5' => 0,
-
'Item with rating 0 #6' => 0,
-
'Item with rating 0 #7' => 0,
-
'Item with rating 0 #8' => 0,
-
'Item with rating 0 #9' => 0,
-
);
-
-
-
exit;
-
}
Вот пример того, что выводится:
-
(
-
[0] => Item with rating 8
-
[1] => Item with rating 10
-
[2] => Item with rating 5
-
[3] => Item with rating 1
-
[4] => Item with rating 3
-
[5] => Item with rating 0 #2
-
[6] => Item with rating 0 #1
-
[7] => Item with rating 0 #2
-
[8] => Item with rating 0 #8
-
[9] => Item with rating 0 #4
-
)
-
-
----------------
-
-
(
-
[0] => Item with rating 10
-
[1] => Item with rating 5
-
[2] => Item with rating 8
-
[3] => Item with rating 1
-
[4] => Item with rating 3
-
[5] => Item with rating 0 #3
-
[6] => Item with rating 0 #9
-
[7] => Item with rating 0 #9
-
[8] => Item with rating 0 #3
-
[9] => Item with rating 0 #1
-
)
-
-
----------------
-
-
(
-
[0] => Item with rating 10
-
[1] => Item with rating 8
-
[2] => Item with rating 3
-
[3] => Item with rating 5
-
[4] => Item with rating 1
-
[5] => Item with rating 0 #7
-
[6] => Item with rating 0 #1
-
[7] => Item with rating 0 #8
-
[8] => Item with rating 0 #7
-
[9] => Item with rating 0 #5
-
)
Естественно, лучше применять хитрые оценки для выставления рейтингов, например,
(1000 - кол-во дней с опубликования)+(100 * кол-во комментариев)+(кол-во просмотров)
Ну и можно применять это к "лучшим" пользователям, комментариям, товарам,...
Вот сама функция:
-
/**
-
* Get random top $count items depending of $list values
-
*
-
* @param array $list Hash - $item=>$value. The greater is value the more chances it has to get to top
-
* @param integer $count Max count of result. If count($list)<=$count then count($result)==count($list)
-
* @return array Top $count items
-
*/
-
function getRandomTop($list, $count = 10) {
-
-
// select random items among ones with values>0
-
$sum = 0;
-
foreach ($list as $key=>$value) {
-
$sum += $value;
-
-
if ($rand <= $sum) {
-
$result[] = $key;
-
break;
-
}
-
}
-
-
};
-
-
// select random items with value==0
-
$result[] = $item;
-
}
-
-
return $result;
-
}
pr($this->getRandomTop($a));pr('----------------');
pr($this->getRandomTop($a));
pr('----------------');
pr($this->getRandomTop($a));
$this убери...
Спасибо, убрал и сделал так, чтобы работало без CakePHP.
Скопировал со своего кода, а у меня функции редко вне классов находятся
почему нельзя сделать одним SQL запросом ?
Рейтинг - это просто атрибут у статьи.
Прочитай ещё раз абзац о вероятности попадания в топ. Специально же жирным выделил
SQL-запросом будут выводиться одни и те же записи и это будет увеличивать их рейтинг.
"Богатые станут ещё богаче, бедные - ещё беднее"
getRandomTop пытается с этим как-то бороться, но при этом рейтинг всё же учитывать.
Владимир, замечательная идея! У меня нечто похожее есть на одном сайте, там по похожему принципу строится облако тегов. Я это делал для того чтоб облако не было статичным уже через месяц существования проекта.
Анатолий, аналогичная практика
Владимир, немного не по теме поста хочу сказать. Сейчас копировал некоторые ваши тексты в Вики -- написал парсер, который циферки подчищает. Попробуйте скопировать свой код из блоков. Цифры разметки слева копируются вместе с ним. Может стоит убрать ?
(win, ff)
Я тоже не люблю, когда копируются цифры или когда во вставленном коде пробелы вместо табов.
Поэтому поставил специальный плагин в котором справа сверху есть надпись "plain text".
Если нажать "plain text", то уберётся разметка и цифры.
Ну вот, похоже русскому программисту легче парсер написать, чем кнопку найти
Спасибо.
Здраствуйте
Очень интересненькая задачка и решение
Хочу поделиться одним решением, возможно будет полезным - когда делал у себя что-то похожее, для отсеивания тех, кто заинтересовался объектом, увидев его в топе и соответсвенно щелкал по ссылке на этот объект -> статистика не учитывала переход к объекту в случае если referer - страница с рейтингом
@Дмитрий:
действительно хорошая идея. хотя я бы просто делал бы просто вес такого визита меньше - например, 1% от обычного захода.