Как вы реализуете хороший фильтр ненормативной лексики?


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

где можно найти хороший список ругательств на разных языках и диалектах?

доступны ли API для источников, содержащих хорошие списки? Или, может быть, API, который просто говорит "Да, это чисто" или "нет, это грязно" с некоторыми параметры?

Каковы некоторые хорошие методы для ловли людей, пытающихся обмануть систему, например$$, azz или a55?

бонусные баллы, если вы предлагаете решения для PHP. :)

Edit: ответ на ответы, которые говорят просто избежать программной проблемы:

Я думаю, что есть место для такого фильтра, когда, например, пользователь может использовать public image search для поиска изображений, которые добавляются в чувствительный пул сообщества. Если они могут ищите "пенис", тогда они, скорее всего, получат много фотографий, да. Если нам не нужны фотографии этого, то предотвращение слова в качестве поискового термина-хороший привратник, хотя, по общему признанию, не надежный метод. Получение списка слов в первую очередь является реальным вопросом.

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

20 186

20 ответов:

фильтры непристойности: плохая идея или невероятно плохая идея?

кроме того, нельзя забывать Нерассказанная история Тунтаун в SpeedChat, где даже использование "белого списка безопасных слов" привело к тому, что 14-летний быстро обошел его с помощью:

хотя я знаю, что этот вопрос довольно старый, но это обычно возникает вопрос...

существует как причина, так и явная потребность в фильтрах ненормативной лексики (см. статью в Википедии здесь), но они часто не достигают 100% точности по очень разным причинам;контекст и точность.

Это зависит (полностью) от того, чего вы пытаетесь достичь - на самом основном, вы, вероятно, пытаетесь покрыть " "семь грязных слов" " и еще кое-что... Некоторые компании должны фильтровать самые основные ненормативные выражения: основные ругательства, URL-адреса или даже личную информацию и т. д., Но другие должны предотвращать незаконное именование учетных записей (например, Xbox live) или гораздо больше...

пользовательский контент не просто содержит потенциальные ругательства, он также может содержать оскорбительные ссылки на:

  • половые акты
  • сексуальной ориентация
  • религия
  • национальности
  • Etc...

и, возможно, на нескольких языках. Систему разработала основные списки грязных слов на 10 языках на сегодняшний день, но он по-прежнему основной и очень ориентирован на их потребности в "маркировке". Есть ряд других списков, доступных в интернете.

Я согласен с принятым ответом, что это не определенная наука и как язык постоянно развивается вызов но тот, где скорость улова 90% лучше, чем 0%. Это зависит исключительно от ваших целей - чего вы пытаетесь достичь, уровень поддержки у вас есть и насколько важно удалить профанации разных типов.

при построении фильтра необходимо учитывать следующие элементы и то, как они относятся к вашему проекту:

  • слова
  • акронимы (Д/А и т. д.)
  • ложных срабатываний (слова, места и имена, такие как "mishit", "scunthorpe" и "titsworth")
  • URLs (порно сайты являются очевидной целью)
  • личная информация (электронная почта, адрес, телефон и т. д. - При наличии)
  • выбор языка (обычно английский по умолчанию)
  • модерация (как, если вообще, вы можете взаимодействовать с пользовательским контентом и что вы можете с ним делать)

вы можете легко построить фильтр ненормативной лексики, который захватывает 90%+ ненормативной лексики, но вы никогда не попадете на 100%. Это просто невозможно. Чем ближе вы хотите добраться до 100%, тем сложнее становится... Построив в прошлом сложный механизм ненормативной лексики, который имел дело с более чем 500 тыс. сообщений в реальном времени в день, я бы предложил следующий совет:

основной фильтр будет включать:

  • построение списка применимых ругательств
  • разработка метода борьбы с производные ругательства

умеренно сложный файлер будет включать (в дополнение к базовому фильтру):

  • использование сложного сопоставления шаблонов для работы с расширенными производными (с использованием расширенного регулярного выражения)
  • работа с Leetspeak (l33t)
  • работа с ложных срабатываний

сложный фильтр будет включать в себя ряд следующих (в дополнение к умеренный фильтр):

  • белые и черных
  • наивный байесовский вывод фильтрация фраз / терминов
  • Soundex функции (где слово звучит как другое)
  • расстояние Левенштейна
  • Stemming
  • человеческие модераторы, чтобы помочь направить механизм фильтрации, чтобы узнать на примере или где совпадения не являются достаточно точный без руководства (само / постоянно совершенствующаяся система)
  • возможно, какая-то форма двигателя AI

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

во время моего собеседования на работу технический директор компании, который брал у меня интервью, опробовал слово/веб-игру, которую я написал на Java. Из списка слов всего Оксфордского словаря английского языка, какое было первое слово, которое пришло в голову угадать?

конечно, самое нецензурное слово в английском языке.

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

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

система фильтрации ненормативной лексики никогда не будет идеальной, даже если программист самоуверен и держит руку на пульсе всех обнаженных разработок

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

Итак, единственное практическое решение двоякое:

  1. будьте готовы обновить свой словарь часто
  2. наймите человека-редактора для исправления ложных срабатываний (например, "clbuttic" вместо "classic") и ложных негативов (ой! пропустил один!)

единственный способ предотвратить оскорбительный пользовательский ввод-это предотвратить весь пользовательский ввод.

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

Что касается вашего подзапроса" trick the system", вы можете справиться с этим, нормализуя как список" плохих слов", так и введенный пользователем текст перед выполнением поиска. например, используйте ряд регулярных выражений (или tr Если PHP имеет его) конвертировать [z$5] к "s",[4@] "а", и т. д., затем сравните нормализованный список "плохое слово" с нормализованным текстом. Обратите внимание, что нормализация потенциально может привести к дополнительным ложным срабатываниям, хотя я не могу думать любые дела на данный момент.

большая проблема-придумать что-то, что позволит людям цитату"ручка сильнее, чем меч" при блокировании "p e n i s".

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

один из текущих примеров этого: ebay использует словарный подход для фильтрации "плохих слов" из обратной связи. Если вы попытаетесь ввести немецкий перевод "this was a perfect transaction" ("das war eine perfekte Transaktion"), ebay отклонит обратную связь из-за плохих слов.

Почему? Потому что немецкое слово " was "- это" война", а "война" - это ebay словарь "плохих слов".

Так что остерегайтесь вопросов локализации.

Если вы можете сделать что-то вроде Digg/Stackoverflow, где пользователи могут понижать/отмечать непристойный контент... так поступать.

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

Я немного опоздал на вечеринку, но у меня есть решение, которое может сработать для тех, кто читает это. Это в javascript вместо php, но для этого есть веская причина.

полное раскрытие, я написал этот плагин...

в любом случае.

подход, с которым я пошел, заключается в том, чтобы позволить пользователю "отказаться" от своей фильтрации ненормативной лексики. В основном ненормативная лексика будет разрешена по умолчанию, но если мои пользователи не хотят ее читать, им это не нужно. Этот также помогает с проблемой "l33t sp3@k".

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

вот демонстрационная страница
https://chaseflorell.github.io/jQuery.ProfanityFilter/demo/

<div id="foo">
    ass will fail but password will not
</div>

<script>
    // code:
    $('#foo').profanityFilter({
        customSwears: ['ass']
    });
</script>

результат

*** не удастся, но пароль не будет

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

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

Спасибо за идеи.

правила HanClinto!

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

$errors = array();  //Initialize error array (I use this with all my PHP form validations)

$SCREENNAME = mysql_real_escape_string($_POST['SCREENNAME']); //Escape the input data to prevent SQL injection when you query the profanity table.

$ProfanityCheckString = strtoupper($SCREENNAME); //Make the input string uppercase (so that 'BaDwOrD' is the same as 'BADWORD').  All your values in the profanity table will need to be UPPERCASE for this to work.

$ProfanityCheckString = preg_replace('/[_-]/','',$ProfanityCheckString); //I allow alphanumeric, underscores, and dashes...nothing else (I control this with PHP form validation).  Pull out non-alphanumeric characters so 'B-A-D-W-O-R-D' shows up as 'BADWORD'.

$ProfanityCheckString = preg_replace('/1/','I',$ProfanityCheckString); //Replace common numeric representations of letters so '84DW0RD' shows up as 'BADWORD'.

$ProfanityCheckString = preg_replace('/3/','E',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/4/','A',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/5/','S',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/6/','G',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/7/','T',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/8/','B',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/0/','O',$ProfanityCheckString); //Replace ZERO's with O's (Capital letter o's).

$ProfanityCheckString = preg_replace('/Z/','S',$ProfanityCheckString); //Replace Z's with S's, another common substitution.  Make sure you replace Z's with S's in your profanity database for this to work properly.  Same with all the numbers too--having S3X7 in your database won't work, since this code would render that string as 'SEXY'.  The profanity table should have the "rendered" version of the bad words.

$CheckProfanity = mysql_query("SELECT * FROM DATABASE.TABLE p WHERE p.WORD = '".$ProfanityCheckString."'");
if(mysql_num_rows($CheckProfanity) > 0) {$errors[] = 'Please select another Screen Name.';} //Check your profanity table for the scrubbed input.  You could get real crazy using LIKE and wildcards, but I only want a simple profanity filter.

if (count($errors) > 0) {foreach($errors as $error) {$errorString .= "<span class='PHPError'>$error</span><br /><br />";} echo $errorString;} //Echo any PHP errors that come out of the validation, including any profanity flagging.


//You can also use these lines to troubleshoot.
//echo $ProfanityCheckString;
//echo "<br />";
//echo mysql_error();
//echo "<br />";

Я уверен, что есть более эффективный способ сделать все эти замены, но я недостаточно умен, чтобы понять это (и это, кажется, работает нормально, хотя и неэффективно).

Я считаю, что вы должны ошибаться на стороне разрешения пользователям регистрироваться и использовать людей для фильтрации и добавления к вашей ненормативной лексике таблица по мере необходимости. Хотя все зависит от стоимости ложного положительного (хорошо слово помечено как плохое) против ложного отрицательного (плохое слово проходит). Это должно в конечном счете управлять тем, насколько вы агрессивны или консервативны в своей стратегии фильтрации.

Я также был бы очень осторожен, если вы хотите использовать подстановочные знаки, так как они иногда могут вести себя более однообразно, чем вы намереваетесь.

Я собрал 2200 плохие слова на 12 языках: английский, АР, КС, да, де, эо, Эс, ФА, фи, ФО, привет, ху, да, ко, Ньюфаундленд и Лабрадор, нет, ПЛ, пт, ру, Св, Ю, так как tlh, тр.матем. журн.

MySQL дамп, JSON, XML или CSV параметры доступны.

https://github.com/turalus/openDB

Я бы предложил вам выполнить этот SQL в вашей БД и проверять каждый раз, когда пользователь вводит что-то.

честно говоря, я бы позволил им получить слова "trick the system" и запретить их вместо этого, что касается только меня. Но это также упрощает Программирование.

то, что я бы сделал, это реализовать фильтр регулярных выражений следующим образом:/[\s]dooby (doo?)[\s]/i или это слово с приставкой на других,/[\s]doob(er|ed|est)[\s]/. Это предотвратит фильтрацию таких слов, как assuaged, что совершенно справедливо, но также потребует знания других вариантов и обновления фактического фильтра, если вы узнаете новый. Очевидно, что это все примеры, но вам придется решить, как это сделать самому.

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

нет. Это только приводит к проблемам. Один clbuttic личный опыт, который у меня есть с фильтрами ненормативной лексики, - это время, когда меня ударили/запретили из канала IRC за упоминание о том, что я "направлялся по мосту в Хэнкок на пару часов" или что-то в этом роде.

Я согласен с тщетностью предмета, но если вам нужно иметь фильтр, проверьте Ning's самшита:

Boxwood-это PHP расширение для быстрой замены нескольких слов в куске текста. Он поддерживает с учетом регистра и без учета регистра совпадения. Он требует, чтобы текст, с которым он работает, был закодирован как UTF-8.

также смотрите это сообщение в блоге для более подробной информации:

с Boxwood, вы можете иметь свой список поисковых терминов быть так долго, как вам нравится-алгоритм поиска и замены не становится медленнее с большим количеством слов в списке слов для поиска. Он работает, создавая trie всех поисковых терминов, а затем сканирует текст темы только один раз, идя вниз элементы trie и сравнивая их с символами в тексте. Он поддерживает US-ASCII и UTF-8, чувствительное к регистру или нечувствительное соответствие, и имеет некоторую англо-ориентированную логику проверки границ слов.

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

  1. фильтр: фоновая служба, которая проверяет черный список, Словарь или что-то в этом роде.
  2. не разрешать анонимный аккаунт
  3. сообщил о нарушении

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

нет.

потому что:

  • Clbuttic
  • ненормативная лексика не ОМГ зло
  • ненормативная лексика не может быть эффективно определена
  • большинство людей, скорее всего, не ценят быть "защищенными" от ненормативной лексики

Edit: хотя я согласен с комментатором, который сказал, что "цензура неверна", это не характер этого ответа.

фильтры ненормативной лексики-плохая идея. причина в том, что вы не можете поймать каждое матерное слово. Если вы попытаетесь, вы получите ложные срабатывания.

Ловя Слова

давайте просто скажем, что вы хотите поймать F-слово. Полегче, Да? Ну посмотрим.

вы можете перебрать строку, чтобы найти " ебать."К сожалению, сегодня люди обманывают фильтры. Фильтр ненормативной лексики не уловил "Фук."

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

Избегая Невиновности

хорошо, так как насчет того, чтобы сделать его нечувствительным к регистру и игнорировать пробелы, чтобы он ловил "F u C k"? Это может показаться хорошей идеей, но кто-то может просто обойти фильтр ненормативной лексики с "F. U. C. K."

вы игнорируете знаки препинания.

теперь это реально проблема, так как "чертО, нет!"будут подбирать как "ад", так и " Чтпопкивверх?"подхватывает как "жопа"."

и есть куча слов, которые вы должны исключить из фильтра, такие как " минусыТитution, "потому что в нем есть" синица".

люди также могут использовать заменяющие слова, такие как "Frack.- Ты и это блокируешь? Как насчет "ручка" для "пениса"? Ваша программа не имеет искусственного интеллекта, чтобы знать, является ли строка хорошо это или плохо.

Не используйте фильтры ненормативной лексики. Их трудно развить, и они так же медленны, как ползать.