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

StackOverflow https://stackoverflow.com/questions/273516

Вопрос

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

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

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

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

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

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

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

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

Это было полезно?

Решение

Фильтры Непристойностей:Плохая идея или Невероятно Соблазнительная Плохая Идея?

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

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

Система, которая устраняет анонимность и вводит подотчетность (то, с чем Stack Overflow справляется хорошо), также полезна, особенно для борьбы с G.I.F.T. Джона Гэбриэла

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

Редактировать в ответ на вопрос редактировать: Спасибо за разъяснение того, что вы пытаетесь сделать.В таком случае, если вы просто пытаетесь выполнить простой фильтр по словам, есть два способа, которыми вы можете это сделать.Один из них - создать одно длинное регулярное выражение со всеми запрещенными фразами, которые вы хотите подвергнуть цензуре, и просто выполнить поиск / замену регулярного выражения на него.Регулярное выражение, подобное:

$filterRegex = "(boogers|snot|poop|shucks|argh)"

и запустите его в вашей строке ввода, используя preg_match() провести оптовый тест на попадание,

или preg_replace() чтобы вычеркнуть их из памяти.

Вы также можете загружать эти функции с помощью массивов, а не одного длинного регулярного выражения, и для длинных списков слов это может быть более управляемым.Посмотрите на preg_replace() вот несколько хороших примеров того, как массивы можно гибко использовать.

Дополнительные примеры программирования на PHP приведены на этой странице. несколько продвинутый универсальный класс для фильтрации слов это * вычеркивает центральные буквы из подвергнутых цензуре слов, и это предыдущий вопрос о переполнении стека там также есть пример PHP (основной ценной частью является основанный на SQL подход к отфильтрованным словам - без компенсатора leet-speak можно обойтись, если вы сочтете это ненужным).

Вы также добавили:"Получение списка слов на первом месте - вот в чем реальный вопрос." - в дополнение к некоторым предыдущим ссылкам на Dansgaurdian, вы можете найти это удобно .застегните молнию из 458 слов, которые должны быть полезными.

Другие советы

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

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

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

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

  • Сексуальные действия
  • Сексуальная ориентация
  • Религия
  • Этническая принадлежность
  • И т.д...

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

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

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

  • Слова/ фразы
  • Сокращения (FOAD/LMFAO и т.д.)
  • Ложноположительные результаты (слова, места и названия, такие как "мишит", "сканторп" и "титсворт")
  • URL-адреса (очевидной целью являются порносайты)
  • Личная информация (электронная почта, адрес, телефон и т.д. - если применимо)
  • Выбор языка (обычно по умолчанию используется английский)
  • Модерация (как, если вообще, вы можете взаимодействовать с пользовательским контентом и что вы можете с ним делать)

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

Базовый фильтр будет включать в себя:

  • Составление списка применимых ненормативных выражений
  • Разработка метода борьбы с производными ненормативной лексики

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

  • Использование сложного сопоставления с образцом для работы с расширенными производными (с использованием расширенного регулярного выражения)
  • Имея дело с Литспик (l33t)
  • Имея дело с ложноположительные результаты

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

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

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

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

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

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

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

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

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

<Ол>
  • будьте готовы регулярно обновлять ваш словарь
  • нанять редактора-человека для исправления ложных срабатываний (например, "clbuttic" вместо "classic") и ложных отрицаний (ой! пропустил один!)
  • Единственный способ предотвратить оскорбительный ввод пользователя - запретить весь ввод пользователя.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Вот демонстрационная страница
    https://chaseflorell.github.io/jQuery .Фильтр ненормативной лексики / демо/

    <div id="foo">
        ass will fail but password will not
    </div>
    
    <script>
        // code:
        $('#foo').profanityFilter({
            customSwears: ['ass']
        });
    </script>
    

    Результат

    *** произойдет сбой, но пароль не будет

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

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

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

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

    Правила HanClinto!

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

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

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

    <*>

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

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

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

    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 языках: en, ar, cs, da, de, eo, es, fa, fi, fr, hi, hu, it, ja, ko, nl, no, pl, pt, ru, sv, th, tlh, tr, zh.

    Доступны опции MySQL dump, JSON, XML или CSV.

    https://github.com/turalus/openDB

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

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

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

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

    Я согласен с бесполезностью этой темы, но если вам нужен фильтр, загляните в Ning's Самшит:

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

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

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

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

    <Ол>
  • Фильтр: фоновый сервис, который проверяет черный список, словарь или что-то в этом роде.
  • Не разрешать анонимный аккаунт
  • Сообщить о нарушении
  • Дополнительным бонусом будет вознаграждение тех, кто вносит свой вклад в точные оскорбления репортеров, и наказание нарушителя, например. приостановить их учетные записи.

    Тоже поздно в игре, но проводил кое-какие исследования и наткнулся здесь.Как упоминали другие, это почти невозможно, если бы это было автоматизировано, но если ваш дизайн / требования могут включать в некоторых случаях (но не всегда) взаимодействие с людьми для проверки, является ли это непристойным или нет, вы можете рассмотреть ML. https://docs.microsoft.com/en-us/azure/cognitive-services/content-moderator/text-moderation-api#profanity это мой текущий выбор прямо сейчас по нескольким причинам:

    • Поддерживает множество локализаций
    • Они продолжают обновлять базу данных, поэтому мне не нужно быть в курсе последних сленгов или языков (проблема с обслуживанием)
    • Когда существует высокая вероятность (Т.е.90% или больше) вы можете просто прагматично отрицать это
    • Вы можете понаблюдать за категорией, которая вызывает флаг, который может быть или не быть ненормативной лексикой, и попросить кого-нибудь просмотреть его, чтобы показать, является он ненормативной лексикой или нет.

    Для моих нужд это было / основано на общедоступном коммерческом сервисе (ОК, видеоигры), в котором другие пользователи могут / будут видеть имя пользователя, но дизайн требует, чтобы оно проходило через фильтр ненормативной лексики, чтобы отклонить оскорбительное имя пользователя.Печальная часть этого заключается в том, что, скорее всего, возникнет классическая проблема "clbutt", поскольку имена пользователей обычно состоят из одного слова (до N символов), иногда из нескольких слов, объединенных...Опять же, когнитивная служба Microsoft не будет помечать "Assist" как текст.HasProfanity = true, но может указывать, что вероятность одной из категорий высока.

    Поскольку OP запрашивает, как насчет "a $ $", вот результат, когда я пропустил его через фильтр:enter image description here, как вы можете видеть, он определил, что это не непристойно, но с высокой вероятностью, что это так, поэтому помечает как рекомендации по пересмотру (взаимодействия с людьми).

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

    Кстати, стоимость / price для этой услуги довольно низкая для моей цели (как часто меняется имя пользователя?), Но опять же, для OP, возможно, дизайн требует более интенсивных запросов и может быть не идеальным для оплаты / подписки на ML-сервисы или не может иметь человеческого обзора / взаимодействия.Все зависит от дизайна...Но если дизайн действительно соответствует всем требованиям, возможно, это может быть решением OP.

    Если интересно, я могу перечислить минусы в комментарии в будущем.

    Не надо.

    Потому что:

    • Щелкающий
    • Ненормативная лексика - это не АБСОЛЮТНОЕ ЗЛО
    • Ненормативная лексика не может быть эффективно определена
    • Большинству людей, вполне вероятно, не нравится, когда их "защищают" от ненормативной лексики

    Редактировать:Хотя я согласен с комментатором, который сказал, что "цензура - это неправильно", суть этого ответа не в этом.

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

    Поймать слова

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

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

    Можно попытаться проверить наличие нескольких вариантов написания и вариантов слова, но это снизит производительность вашего кода. Чтобы поймать F-Word, вам нужно искать «fuc», «Fuc», «fuk», «Fuk», «F ***» и т. Д. И этот список можно продолжать и продолжать .

    Как избежать невиновности

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

    Вы игнорируете пунктуацию.

    Теперь это реальная проблема, поскольку такое предложение, как " Ад o, существует! " будет восприниматься как "ад" и "Wh задница вверх?" воспринимается как "задница".

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top