Создание фильтра спама для C# на основе наивного байесовского классификатора

Основы
Многие веб-блоги, которые получают все больше внимания, также привлекают спам. Поначалу можно отделить волну при помощи мер против роботов и отклонять посты от того, что явно не является веб-браузером. Может вам приходилось писать простой скрипт определения пользователя, запущенного за занавесом и обеспечивающего то, чтобы реальные люди оставляли сообщения на вашем блоге вручную.
Такой подход работал очень хорошо некоторое время. Иногда были случаи, когда все же спам проходил контроль, но это можно было пресечь. Все же за занавесом почти 10,000 автоматических спамовых комментариев уничтожались ежедневно, что весьма неплохо.
На данный, 2008-ой год, все по-другому. Мы видим новое поколение спама, и с каждым днем дела обстоят все хуже. Этот спам движим людьми. Он предоставляется людьми за реальной клавиатурой из той страны, где зарплаты слишком низки и рекламодатели могут позволить себе нанять комнаты рабочих для копирования/вставки комментариев вручную. Никакие автоматические определители спама не могут предотвратить это, поскольку сам спам уже не автоматический.
Пора перейти к алгоритму Байса
Современные почтовые клиенты используют алгоритм фильтрации спама Байса, и это мы и реализуем. Проверив в Google реализацию алгоритма на C#, вы не найдете множества решений фильтрации спама на основе алгоритма Байса, которые вы могли бы просто внедрить в свой код. Так в чем же причина? Технологии существовали с 2002, так неужели настолько страшно реализовать данный алгоритм? Может быть, но все же не так удобно вручную модерировать блоги. Если вы попробуете реализовать данный алгоритм, то вы поймете, что все не так сложно.
Мы не будем углубляться в сам алгоритм. Ведь мы всего лишь выполним прямую реализацию алгоритма фильтрации от спама на основе наивного байесовского классификатора на языке C#.
Использование кода
В файле, прикрепленном к данной статье, вы найдете два класса, которые позволяют все это воплотить. Класс CorpusSpamFilter, который получает два класса Corpus и сопоставляет их друг с другом для того, чтобы произвести список вероятностей того, что документ содержащий данное слово, будет спамом. хранит списки слов, а также подсчитывает то, как часто они появляются в определенном тексте. Также существует класс
Как только вы заполнили данными SpamFilter, вы можете скормить ему другие документы и спросить, не "кажется" ли ему, что они представляют собой спам. Мы узнали, что было найдено примерно 6% ошибок исключений (спам, который не был отмечен), и всего лишь 0.2% ошибочных разрешений (сообщения, которые были ошибочно отмечены как спам) из 10,000 сообщений в блоге. Даже при этом, было найдено все, кроме одного сообщения, которое было неподдельным спам-сообщением.
Мы также включили в пример приложения WinForms, чтобы вы могли увидеть фильтр в действии. Это парочка текстовых файлов, которые оно считывает для заполнения SpamFilter достаточным количеством хорошего и плохого содержимого для необходимой демонстрации. Мы также включили 3 примерочных сообщения для проведения теста. Одно по-настоящему является уникальным сообщением, второе является явным спамом и третье - хорошо написанное спам-сообщение, которое прошло проверку в качестве ошибочного исключения. Примерочное приложение позволяет вам редактировать текстовое сообщение для того, чтобы увидеть эффект добавления различного содержимого.
Применение
Все отлично подойдет для тестирования, но как насчет выполнения вживую? Вот как приложение используется сегодня:
Мы держим статический объект SpamFilter в памяти на сервере, тем самым нам нет необходимости в его составлении при каждой необходимости. Один раз в день выполняется сборка SpamFilter из содержимого базы данных, сохраняет фильтр в памяти, а также сохраняет запасную копию при помощи метода .ToFile(). Если наш объект SpamFilter будет отсутствовать по какой-то причине, то мы просто получим последнее состояние файла используя метод .FromFile().
При сохранении нового сообщения в блоге, мы пропускаем его через SpamFilter и устанавливаем бит IsSpam данного сообщения при необходимости. Весь код отображения знает, что стоит проверить данный бит и либо пресечь отображение, либо же вывести ответ 404 для тех сообщений, которые были отмечены как спам. Но есть одно исключение: есть одноминутное окно, после которого новое спам-сообщение будет опубликовано, в таком виде, как будто оно не является спамом. Это достаточное время для того, чтобы спамер осмотрел свое сообщение и поздравил себя с хорошо выполненной работой, но не достаточное время для индексации страницы поисковой системой. Мы конечно же исключим любые спам-сообщения из RSS лент, карт сайта и сервисных запросов Blog Ping.
В качестве части инструментов администрирования сайта, мы имеем список всех последних сообщений и их статус. Это позволяет нам быстро вернуть ложные разрешения и отрицания обратно в их оригинальное состояние, а также быть в курсе того, что происходит на сайте.
Вывод
Мы надеемся, что предоставленный код будет вам пригоден. Существует множество блогов и форумов, которые работают на ASP.NET и при этом перегружены спамом. При помощи данных двух классов вы можете получить немало пользы в борьбе со спамом.