Как вы реализуете хороший фильтр ненормативной лексики?
многие из нас должны иметь дело с пользовательским вводом, поисковыми запросами и ситуациями, когда входной текст потенциально может содержать ненормативную лексику или нежелательный язык. Часто это должно быть отфильтровано.
где можно найти хороший список ругательств на разных языках и диалектах?
доступны ли API для источников, содержащих хорошие списки? Или, может быть, API, который просто говорит "Да, это чисто" или "нет, это грязно" с некоторыми параметры?
Каковы некоторые хорошие методы для ловли людей, пытающихся обмануть систему, например$$, azz или a55?
бонусные баллы, если вы предлагаете решения для PHP. :)
Edit: ответ на ответы, которые говорят просто избежать программной проблемы:
Я думаю, что есть место для такого фильтра, когда, например, пользователь может использовать public image search для поиска изображений, которые добавляются в чувствительный пул сообщества. Если они могут ищите "пенис", тогда они, скорее всего, получат много фотографий, да. Если нам не нужны фотографии этого, то предотвращение слова в качестве поискового термина-хороший привратник, хотя, по общему признанию, не надежный метод. Получение списка слов в первую очередь является реальным вопросом.
поэтому я действительно имею в виду способ выяснить, является ли один токен грязным или нет, а затем просто запретить его. Я бы не потрудился предотвратить такое чувство, как совершенно веселый " жираф с длинной шеей" ссылка. Там ты ничего не сможешь сделать. :)
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. Из списка слов всего Оксфордского словаря английского языка, какое было первое слово, которое пришло в голову угадать?
конечно, самое нецензурное слово в английском языке.
Так или иначе, я все еще получил предложение о работе, но затем я отследил список ненормативной лексики (не в отличие от этой) и написал небольшой скрипт для генерации новых словарь без всех плохих слов (даже не глядя на список).
для вашего конкретного случая, я думаю, что сравнение поиска с реальными словами звучит как способ пойти со списком слов, как это. Альтернативные стили/пунктуация требуют немного больше работы, но я сомневаюсь, что пользователи будут использовать достаточно часто, чтобы быть проблемой.
система фильтрации ненормативной лексики никогда не будет идеальной, даже если программист самоуверен и держит руку на пульсе всех обнаженных разработок
тем не менее, любой список "непослушных слов", вероятно, будет работать так же, как и любой другой список, поскольку основная проблема язык понимания который в значительной степени неразрешим с текущей технологией
Итак, единственное практическое решение двоякое:
- будьте готовы обновить свой словарь часто
- наймите человека-редактора для исправления ложных срабатываний (например, "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 основных компонента, или, по крайней мере, это то, что я собираюсь сделать. Вот они:
- фильтр: фоновая служба, которая проверяет черный список, Словарь или что-то в этом роде.
- не разрешать анонимный аккаунт
- сообщил о нарушении
бонус, это будет как-то вознаградить тех, кто вносит свой вклад с точными репортерами злоупотребления и наказать преступника, например заморозить их счета.
нет.
потому что:
- Clbuttic
- ненормативная лексика не ОМГ зло
- ненормативная лексика не может быть эффективно определена
- большинство людей, скорее всего, не ценят быть "защищенными" от ненормативной лексики
Edit: хотя я согласен с комментатором, который сказал, что "цензура неверна", это не характер этого ответа.
фильтры ненормативной лексики-плохая идея. причина в том, что вы не можете поймать каждое матерное слово. Если вы попытаетесь, вы получите ложные срабатывания.
Ловя Слова
давайте просто скажем, что вы хотите поймать F-слово. Полегче, Да? Ну посмотрим.
вы можете перебрать строку, чтобы найти " ебать."К сожалению, сегодня люди обманывают фильтры. Фильтр ненормативной лексики не уловил "Фук."
можно попробовать проверить несколько вариантов написания и слова, но это замедлит производительность вашего кода. Чтобы поймать F-слово, вам нужно искать "Фук", "Фук", "Фук", "Фук", "Ф***" и т. д. И этот список можно продолжать и продолжать.
Избегая Невиновности
хорошо, так как насчет того, чтобы сделать его нечувствительным к регистру и игнорировать пробелы, чтобы он ловил "F u C k"? Это может показаться хорошей идеей, но кто-то может просто обойти фильтр ненормативной лексики с "F. U. C. K."
вы игнорируете знаки препинания.
теперь это реально проблема, так как "чертО, нет!"будут подбирать как "ад", так и " Чтпопкивверх?"подхватывает как "жопа"."
и есть куча слов, которые вы должны исключить из фильтра, такие как " минусыТитution, "потому что в нем есть" синица".
люди также могут использовать заменяющие слова, такие как "Frack.- Ты и это блокируешь? Как насчет "ручка" для "пениса"? Ваша программа не имеет искусственного интеллекта, чтобы знать, является ли строка хорошо это или плохо.
Не используйте фильтры ненормативной лексики. Их трудно развить, и они так же медленны, как ползать.