Расчет вероятности спама - PullRequest
3 голосов
/ 07 июня 2010

Я создаю веб-сайт в python / django и хочу предсказать, действительна ли отправка пользователя или является спамом.

У пользователей есть уровень согласия на их представления, как у этого сайта.

Пользователи могут модерировать представления других пользователей; и эти модерации позже метамодерируются администратором.

Учитывая это:

  • зарегистрированный пользователь А с уровнем принятия 60% что-то отправляет.
  • пользователь B модерирует сообщение A как действительное сообщение. Однако пользователь B ошибается в 70% случаев.
  • пользователь C модерирует сообщение A как спам. Пользователь C обычно прав. Если пользователь C говорит, что что-то является спамом / не спамом, это будет правильно в 80% случаев.

Как я могу предсказать вероятность того, что сообщение А будет спамом?

Редактировать: я создал скрипт на python, имитирующий этот сценарий:

#!/usr/bin/env python

import random

def submit(p):
    """Return 'ham' with (p*100)% probability"""
    return 'ham' if random.random() < p else 'spam'

def moderate(p, ham_or_spam):
    """Moderate ham as ham and spam as spam with (p*100)% probability"""
    if ham_or_spam == 'spam':
        return 'spam' if random.random() < p else 'ham'
    if ham_or_spam == 'ham':
        return 'ham' if random.random() < p else 'spam'

NUMBER_OF_SUBMISSIONS = 100000 
USER_A_HAM_RATIO = 0.6 # Will submit 60% ham
USER_B_PRECISION = 0.3 # Will moderate a submission correctly 30% of the time
USER_C_PRECISION = 0.8 # Will moderate a submission correctly 80% of the time

user_a_submissions = [submit(USER_A_HAM_RATIO) \
                        for i in xrange(NUMBER_OF_SUBMISSIONS)]

print "User A has made %d submissions. %d of them are 'ham'." \
        % ( len(user_a_submissions), user_a_submissions.count('ham'))

user_b_moderations = [ moderate( USER_B_PRECISION, ham_or_spam) \
                        for ham_or_spam in user_a_submissions]

user_b_moderations_which_are_correct = \
    [i for i, j in zip(user_a_submissions, user_b_moderations) if i == j]

print "User B has correctly moderated %d submissions." % \
    len(user_b_moderations_which_are_correct)

user_c_moderations = [ moderate( USER_C_PRECISION, ham_or_spam) \
                        for ham_or_spam in user_a_submissions]

user_c_moderations_which_are_correct = \
    [i for i, j in zip(user_a_submissions, user_c_moderations) if i == j]

print "User C has correctly moderated %d submissions." % \
    len(user_c_moderations_which_are_correct)

i = 0
j = 0    
k = 0 
for a, b, c in zip(user_a_submissions, user_b_moderations, user_c_moderations):
    if b == 'spam' and c == 'ham':
        i += 1
        if a == 'spam':
            j += 1
        elif a == "ham":
            k += 1

print "'spam' was identified as 'spam' by user B and 'ham' by user C %d times." % j
print "'ham' was identified as 'spam' by user B and 'ham' by user C %d times." % k
print "If user B says it's spam and user C says it's ham, it will be spam \
        %.2f percent of the time, and ham %.2f percent of the time." % \
         ( float(j)/i*100, float(k)/i*100)

Запуск скрипта дает мне такой вывод:

  • Пользователь А сделал 100000 заявок. 60194 из них - «ветчина».
  • Пользователь Б правильно модерировал 29864 представления.
  • Пользователь C правильно проверял 79990 заявок.
  • «Спам» был идентифицирован как «спам» пользователем B, а «ham» - пользователем C 2346 раз.
  • Пользователь Ham идентифицировал «ham» как «спам», а пользователь C - 33634 раза.
  • Если пользователь B говорит, что это спам, а пользователь C говорит, что это хам, это будет спам в 6,52 процента времени, а хам в 93,48 процента времени.

Является ли вероятность здесь разумной? Будет ли это правильный способ симуляции сценария?

Ответы [ 3 ]

5 голосов
/ 07 июня 2010

Теорема Байеса говорит нам:

imageP(A|B)=P(B|A)P(A)/P(B)">

Давайте заменим буквы для событий A и B на X и Y соответственно. потому что вы используете A, B и C для обозначения людей, и это может сбить с толку:

P(X|Y) = P(Y|X) P(X) / P(Y)

Редактировать : следующее слегка ошибочно, потому что X должно быть this post _by A_ is spam, а не просто "это сообщение является спамом" (и, следовательно, Y должен быть просто "B принимает сообщение A, C отклоняет его «). Я не переделываю математику прямо здесь, потому что числа все равно меняются - см. Другие правки ниже для правильного числа и правильной арифметики.

Вы хотите, чтобы X означало "этот пост является спамом", Y означает комбинацию обстоятельств A has posted it, B approved it, C rejected it (и давайте предположим, что эти обстоятельства условно независимы).

Нам нужно P(X), априорная вероятность того, что любой пост (независимо от того, кто его создает или одобряет) является спамом; P(Y), априорная вероятность того, что сообщение будет сделано A, одобрено B, отклонено C (будь то спам или нет); и P(Y | X), такой же, как последний, но с постом, являющимся спамом.

Как вы, наверное, заметили, вы на самом деле не дали нам все кусочки, которые нам нужны для вычислений. Вы, три пункта, говорите нам: данный пост от A является спамом с вероятностью 0,4 (кажется, именно так читается первая точка); Вероятность принятия B составляет 0,3, но мы не знаем, как это отличается для спама и не спама, за исключением того, что должна быть «небольшая» разница (низкая точность); C составляет 0,8, и мы опять не знаем, как на это влияет спам против не спама, за исключением того, что должна быть «большая» разница (высокая точность).

Итак, нам нужны еще цифры! Тот факт, что С имеет высокую точность при принятии 80% сообщений, говорит о том, что общий спам должен быть на удивление низким - если общий спам был таким же, как и у А, то 40%, то С должен был бы принять половину его (даже если он был идеален, чтобы всегда принимать не спам), чтобы получить общий 80% -й показатель принятия, и это вряд ли было бы "высокой точностью". Допустим, общее количество спама составляет всего 20%, а C принимает только 1/4 от него (и отвергает 1/16 не спама), что действительно очень хорошая точность и в целом соответствует числам, которые вы даете.

Догадываясь о В, который принимает в целом 30% и теперь «зная», что спам в целом составляет 20%, мы можем догадаться, что В принимает 1/4 спама и только 5/16 не спама.

Итак: P(X)=0.2; P(Y)=0.3*0.2=0.06 (общее время принятия B, вероятность отказа C); P(Y|X)=0.4*0.25*0.75=0.075 (вероятность спама времени B вероятность принятия спама времени C вероятность отказа от спама).

Итак P(X|Y)=0.075*0.2/0.06=0.25 - если я не совершил какую-то арифметическую ошибку (вполне возможно, главное - показать вам, как можно рассуждать в таких случаях ;-), вероятность того, что этот конкретный пост будет спамом, составляет 0,25 - - немного выше, чем вероятность того, что любой случайный пост является спамом, ниже, чем вероятность того, что случайный пост на A будет спамом.

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

Если вы сможете лучше оценить пять ключевых чисел, вычисление можно сделать более точным.

И, кстати, Python (и тем более Django) не имеют абсолютно никакого отношения к делу - я рекомендую вам удалить эти нерелевантные теги, чтобы получить более широкий диапазон ответов!

Редактировать : пользователь уточняет (в комментарии - ШД действительно редактирует свой Q!):

Когда я сказал: «Модерации Б» принимают ставка составляет всего 30% "Я имею в виду, что длякаждые десять раз B смягчает что-то спам / нет спама он делает неправильно решение 7 раз. Так что есть 70% вероятность того, что он отметит что-то спам / нет спам, когда его нет. Для пользователя C "Его Приемлемость модераций составляет 80% что если С говорит что-то спам или нет спам, он прав 80% времени. Общий шанс зарегистрированного пользователя спам 20%.

... и просит меня повторить математику (я предполагаю, что ложные положительные и отрицательные значения одинаково вероятны для каждого из B и C). Обратите внимание, что B - отличный «противоположный индикатор», так как он ошибается 70% времени! -).

В любом случае: общий уровень принятия B сообщений А должен быть 0,6 * 0,3 (для тех случаев, когда он принимает не спам А) + 0,4 * 0,7 (для тех случаев, когда он принимает спам А) = 0,18 + 0,28 = 0,46; С должно быть 0,8 * 0,4 + 0,2 * 0,6 = 0,32 + 0,12 = 0,44. Итак, у нас есть ...:

P(X)=0.4 (раньше я ошибался в 0,2, так как игнорировал тот факт, что вероятность спама в A равна 0,4 - общая вероятность спама не равна актуально, так как мы знаем, что этот пост - это А!); P(Y)=0.46*0.56=0.2576 (общий коэффициент приемлемости B для A, коэффициент отклонения C для A); P(Y|X)=0.7*0.8=0.56 (вероятность получения спама от B, вероятность отклонения спама от C).

То есть P(X|Y)=0.56*0.4/0.2576=0.87 (округление). IOW: хотя априори вероятность того, что пост А является спамом, равна 0,4, как принятие Б, так и отклонение С усиливают его, поэтому этот конкретный пост А имеет около 87% вероятности быть спамом.

2 голосов
/ 07 июня 2010

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

Результаты с высокой вероятностью спама могут быть перенесены в процесс модерации (если у вас есть выделенные модераторы). Точно так же образец результатов предыдущих модераций может быть представлен в рабочем процессе метамодерации, чтобы получить представление о качестве классификации (т. Е. Мы получили неприемлемо высокий уровень ложных срабатываний и отрицательных результатов).

Наконец, «апелляция», в которой пользователь может жаловаться на то, что публикации несправедливо классифицированы, может также подтолкнуть публикации в рабочий процесс метамодерации. Если у пользователя есть история отклонения апелляции или чрезмерно высокий уровень подачи апелляций (возможно, попытка атаки DOS), его публикациям может быть присвоен постепенно более низкий приоритет в процессе апелляции.

0 голосов
/ 07 июня 2010

Мы подходим к этому более эмпирически.

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

Наши общие правила для незарегистрированных пользователей таковы: 1 ссылка может быть в порядке, 2 - это 80% +, вероятно, спам, 3 или более, и они уже опубликованы. Мы храним список основных доменных имен, которые появляются в отклоненных сообщениях, и они становятся триггерами, даже если в компоновщике 1 или 2. Вы также можете использовать RBL, но будьте осторожны, поскольку они могут быть очень драконовскими.

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

...