Нормализация достижений с несколькими источниками - PullRequest
3 голосов
/ 13 июля 2009

Я ищу хорошую рекомендацию алгоритма.

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

В основном:

Achievement :
    owner = Alias
    points = int

User :
    achievements = list(Achievement)
    def points() :
        sum([achievements.points])

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

  1. Предполагая, что все пользователи честны, но они просто по-разному оценивают. Как мне нормализовать баллы? АКА один пользователь дает 5 баллов за каждое простое достижение, а другой дает 10 баллов, как я могу их нормализовать к одному значению. Целью будет распределение, в котором баллы пропорциональны сложности.
  2. Если один пользователь не очень хорошо оценивает баллы, как я могу определить сложность на основе количества пользователей, которые получили достижение?
  3. Предположим, что пользователи могут быть в основном разделены на непересекающиеся группы, где один пользователь дает достижения целому ряду других. Помогает ли это двум предыдущим алгоритмам? Например, пользователь А дает достижения только тем пользователям, которые заканчиваются нечетным числом, а пользователь Б - только достижениям пользователей, заканчивающимся четным числом.
  4. Если все злоумышленники, насколько я могу приблизиться к тому, чтобы у пользователя не было возможности завышать свои баллы?

Примечание : Качество дающего пользователя никак не связано с тем, сколько достижений он получил. Многие дарители - это просто боты, которые сами ничего не получили, но автоматически награждают пользователей за выполнение определенных действий.

Мой текущий план примерно такой. У меня есть распределение 10 очков / человек, который получил от меня достижение. Если я выдал 10 достижений в общей сложности 55 людям, мое распределение составляет 550. Затем это дается каждому достижению в зависимости от количества людей, которые его получили. Если бы распределение составляло [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] людей, которые получили каждое достижение, тогда значения баллов были бы [50, 25, 16.6, 12.5, 10, 8.3, 7.1, 6.25, 5.5, 5].

Любые проблемы с моим подходом и альтернативными рекомендациями приветствуются и приветствуются. Кроме того, опубликуйте другие случаи, о которых вы можете подумать, что я пропустил, и я добавлю их в список. Спасибо!

Ответы [ 3 ]

0 голосов
/ 13 августа 2009

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

SELECT AVG(Points) AS user_average, 
STDDEV_POP(Points) AS user_stddev
FROM Achievements WHERE Owner = X

Используйте эти значения для расчета "z-показателя" без контекста:

$zscore = ($rating - $user_average) / $user_stddev;

Получите среднее и стандартное отклонение для всех достижений:

SELECT AVG(Points) AS all_average, 
STDDEV_POP(Points) AS all_stddev 
FROM Achievements

Используйте эти значения для создания нормализованного "t-показателя":

$tscore = $all_average + ($all_stddev * $zscore);

Затем используйте t-показатель в качестве внутреннего представления значения достижения. YMMV. :)

0 голосов
/ 16 августа 2009

Правильно, $ rating - это ввод, а $ tscore - нормализованный вывод.

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

Нормализация пытается справиться с этими индивидуальными отклонениями и привести оценки каждого к одной и той же шкале. Это похоже на то, что они делают с оценками судей на Олимпиаде. Вы не «слепо доверяете» значению, которое пользователь присвоил достижению, но это то, что вы хотите учесть, если оно является частью системы. В противном случае вы, вероятно, могли бы просто жестко закодировать балльную стоимость достижений, ограничить частоту их создания, и, похоже, это обуздало бы худшее злоупотребление. Но оценка полезна, потому что после нормализации вы можете выяснить, сколько будет стоить достижение, равное , если оно было создано обычным стереотипным пользователем. Это затрудняет "игру" системы для людей, потому что чем дальше они получают от среднего значения и распределения достижений, тем больше их собственные значения нормализуются обратно к исходному уровню.

Я должен упомянуть, что я не профессионально обученный программист, и я никогда не посещал занятия по статистике или какой-либо высшей математике. Из-за моих собственных ограничений понимания, возможно, я не лучший человек, чтобы объяснять это. Но я боролся с подобной проблемой на своем собственном сайте (оценки пользователей), и после попытки многочисленных подходов этот кажется наиболее перспективным. Большая часть вдохновения для реализации пришла от http://www.ericdigests.org/2003-4/score-normilization.html, так что вы могли бы также прочитать это.

0 голосов
/ 14 июля 2009

Я думаю, что в вашей системе, как в stackoverflow, digg, slashdot и т. Д., Ваши основные цели:

  1. Определить честных пользователей
  2. Продвигайте свои действия

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

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

Таким образом, вы можете дать новым учетным записям начальную оценку 10. Этот пользователь может затем дать любое количество достижений, которое он хочет, но его фактическая общая стоимость будет равна 10 (как предложенное вами пропорциональное распределение). То есть, если новый пользователь дает 100 достижений (все они имеют одинаковое количество баллов), то каждое из них будет стоить 0,1 балла, потому что его оценка равна 10. Затем, когда этот пользователь получает достижения от других пользователей, его оценка увеличивается.

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

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

...