web-dev-qa-db-fra.com

Comment implémentez-vous un bon filtre de grossièretés?

Beaucoup d'entre nous ont besoin de gérer les saisies utilisateur, les requêtes de recherche et les situations dans lesquelles le texte saisi peut potentiellement contenir des injures ou une langue indésirable. Souvent, cela doit être filtré.

Où peut-on trouver une bonne liste de jurons dans différentes langues et dialectes?

Existe-t-il des API disponibles pour les sources contenant de bonnes listes? Ou peut-être une API qui dit simplement "oui c'est propre" ou "non c'est sale" avec certains paramètres?

Quelles sont les bonnes méthodes pour attraper les gens qui essaient de tromper le système, comme un $$, un azz ou un a55?

Points bonus si vous proposez des solutions pour PHP. :)

Edit: Réponse aux réponses disant simplement d'éviter le problème de programmation:

Je pense qu'il existe une place pour ce type de filtre lorsqu'un utilisateur, par exemple, peut utiliser la recherche d'images publique pour rechercher des images ajoutées à un pool de communauté sensible. S'ils peuvent rechercher "pénis", ils auront probablement de nombreuses photos de, ouais. Si nous ne voulons pas d'images de cela, alors empêcher Word comme terme de recherche est un bon garde-porte, même s'il est vrai que ce n'est pas une méthode infaillible. Obtenir la liste des mots en premier lieu est la vraie question.

Donc, je parle vraiment d'une façon de déterminer si un seul jeton est sale ou non, puis de tout simplement le rejeter. Je ne prendrais pas la peine d'empêcher un sentiment comme la référence totalement hilarante à la "girafe à long cou". Tu ne peux rien y faire. :)

195
Ben Throop

Filtres d’obscénité: mauvaise idée ou mauvaise idée??

En outre, il ne faut pas oublier L'histoire inédite du SpeedChat de Toontown , où même en utilisant une "liste blanche safe-Word", un jeune de 14 ans le contournait rapidement avec: "Je souhaite colle ma girafe au long cou sur ton lapin blanc moelleux. "

En bout de ligne: En fin de compte, quel que soit le système que vous implémentez, rien ne peut remplacer l'examen humain (qu'il soit pair ou autre). N'hésitez pas à implémenter un outil rudimentaire pour vous débarrasser des drive-by, mais pour le troll déterminé, vous devez absolument avoir une approche non basée sur des algorithmes.

Un système qui supprime l'anonymat et introduit la responsabilité (quelque chose que Stack Overflow fait bien) est également utile, en particulier pour aider à combattre John Gabriel's G.I.F.T.

Vous avez également demandé où vous pouvez obtenir des listes de blasphèmes pour commencer - un projet open source à vérifier est Dansguardian - consultez le code source pour connaître leurs listes de blasphèmes par défaut. Il existe également une tierce partie supplémentaire liste de phrases que vous pouvez télécharger pour le proxy qui peut être un point de glanage utile pour vous.

Modifier en réponse la question modifier: Merci pour la clarification de ce que vous essayez de faire. Dans ce cas, si vous essayez simplement de faire un simple filtre Word, vous pouvez le faire de deux manières. L'une consiste à créer une seule longue expression rationnelle avec toutes les phrases interdites que vous souhaitez censurer et à effectuer simplement une expression rationnelle à rechercher/remplacer avec celle-ci. Une regex comme:

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

et exécutez-le sur votre chaîne d'entrée en utilisant preg_match () pour tester en gros un hit,

ou preg_replace () pour les effacer.

Vous pouvez également charger ces fonctions avec des tableaux plutôt que de longues expressions rationnelles. Pour les longues listes Word, cela peut être plus facile à gérer. Voir le preg_replace () pour de bons exemples sur la manière dont les tableaux peuvent être utilisés avec souplesse.

Pour plus d'exemples de programmation PHP, voir cette page pour une classe classe générique assez avancée) pour le filtrage par Word qui * est en dehors des lettres centrales des mots censurés, et cela - précédente question relative au débordement de pile qui contient également un exemple PHP (la partie la plus utile étant l’approche Word filtrée basée sur SQL) - le compensateur leet-speak peut être supprimé si vous le trouvez inutile).

Vous avez également ajouté: " Obtenir la liste des mots en premier lieu est la vraie question." - en plus de certains des liens précédents dansgaurdiens, vous pouvez trouver cette pratique .Zip de 458 mots pour être utile.

174
HanClinto

Bien que je sache que cette question est assez ancienne, mais c’est une question courante….

Il existe à la fois une raison et un besoin distinct de filtres de blasphème (voir entrée Wikipedia ici ), mais ils sont souvent insuffisants pour être précis à 100% pour des raisons très distinctes; Contexte et précision .

Cela dépend (entièrement) de ce que vous essayez d'accomplir. En gros, vous essayez probablement de couvrir les " sept mots sales ", puis certains ... Certaines entreprises doivent filtrer le plus élémentaire des blasphèmes: gros mots basiques, URL ou même des informations personnelles, etc., mais d’autres doivent empêcher l’appel à des noms de comptes illicites (Xbox Live en est un exemple) ou bien plus encore ...

Le contenu généré par l'utilisateur ne contient pas que des jurons potentiels, il peut également contenir des références offensantes à:

  • Actes sexuels
  • Orientation sexuelle
  • Religion
  • Ethnicité
  • Etc...

Et potentiellement, dans plusieurs langues. Shutterstock a développé listes de mots sales de base en 10 langues à ce jour, mais il reste basique et très orienté vers ses besoins de "marquage". Il existe un certain nombre d'autres listes disponibles sur le Web.

Je suis d'accord avec la réponse acceptée selon laquelle il ne s'agit pas d'une science définie et comme la langue est en constante évolution défi mais où un taux de capture de 90% est meilleur que 0 %. Cela dépend uniquement de vos objectifs - de ce que vous essayez d’atteindre, du niveau de soutien dont vous disposez et de l’importance de supprimer les profanations de différents types.

Lors de la création d'un filtre, vous devez prendre en compte les éléments suivants et leur relation avec votre projet:

  • Mots/phrases
  • Acronymes (FOAD/LMFAO, etc.)
  • Faux positifs (mots, lieux et noms tels que "mishit", "scunthorpe" et "titsworth")
  • URL (les sites pornographiques sont une cible évidente)
  • Informations personnelles (email, adresse, téléphone, etc. - le cas échéant)
  • Choix de la langue (généralement l'anglais par défaut)
  • Modération (comment, le cas échéant, vous pouvez interagir avec le contenu généré par l'utilisateur et ce que vous pouvez en faire)

Vous pouvez facilement créer un filtre à profanités qui capture 90% des profanations, mais vous n’atteindrez jamais 100%. C'est juste pas possible. Plus vous voulez vous rapprocher à 100%, plus cela devient difficile ... Après avoir construit un moteur complexe de blasphèmes qui traitait plus de 500 000 messages en temps réel par jour, je donnerais les conseils suivants:

Un filtre de base impliquerait:

  • Construire une liste de blasphèmes applicables
  • Développer une méthode pour traiter les dérivations des profanations

Un déposant moyennement complexe impliquerait, (en plus d'un filtre de base):

  • Utilisation de modèles complexes pour traiter les dérivations étendues (à l'aide de regex avancé)
  • Traiter avec Leetspeak (l33t)
  • Traiter avec faux positifs

Un filtre complexe impliquerait un certain nombre des éléments suivants (en plus d'un filtre modéré):

  • Listes blanches et listes noires
  • inférence bayésienne naïve filtrage de phrases/termes
  • Soundex fonctions (où un mot ressemble à un autre)
  • distance de Levenshtein
  • stemming
  • Les modérateurs humains aident à guider un moteur de filtrage pour apprendre par l'exemple ou lorsque les correspondances ne sont pas assez précises sans guidage (système auto/en amélioration constante)
  • Peut-être une forme de moteur d'IA
40
nickhar

Je ne connais aucune bonne bibliothèque pour cela, mais quoi que vous fassiez, assurez-vous de vous tromper en laissant passer des choses. J'ai traité avec des systèmes qui ne me permettaient pas d'utiliser "mpassell" comme nom d'utilisateur, car il contenait "ass" comme sous-chaîne. C'est un excellent moyen d'aliéner les utilisateurs!

26
Matt Passell

Lors d'une de mes entretiens d'embauche, le CTO de la société qui m'interviewait a essayé un jeu Word/Web que j'avais écrit en Java. Sur une liste de mots de tout le dictionnaire anglais Oxford, quel est le premier mot à être deviné?

Bien sûr, le mot le plus répugnant de la langue anglaise.

Malgré tout, j’ai quand même eu l’offre d’emploi, mais j’ai alors retrouvé une liste de mots grossiers (pas contrairement à celui-ci ) et j’ai écrit un script rapide pour générer un nouveau dictionnaire sans tous les mots mauvais (sans même avoir à regarder la liste).

Dans votre cas particulier, je pense que comparer la recherche à de vrais mots ressemble à la manière de procéder avec une liste de mots comme celle-ci. Les styles alternatifs/ponctuation nécessitent un peu plus de travail, mais je doute que les utilisateurs l'utiliseront assez souvent pour poser problème.

23
Matthew

un système de filtrage profane ne sera jamais parfait, même si le programmeur est sûr de lui et se tient au courant de tous les développements nus

cela dit, toute liste de "vilains mots" sera aussi performante que toute autre liste, puisque le problème sous-jacent est compréhension de la langue, ce qui est pratiquement impossible à résoudre avec la technologie actuelle.

alors, la seule solution pratique est double:

  1. être prêt à mettre à jour votre dictionnaire fréquemment
  2. embaucher un éditeur humain pour corriger les faux positifs (par exemple, "probiotique" au lieu de "classique") et les faux négatifs (oups! un raté!)
21
Steven A. Lowe
13
Tim Cavanaugh

Le seul moyen d'empêcher une entrée offensive de l'utilisateur est d'empêcher toute entrée de l'utilisateur.

Si vous insistez pour autoriser la saisie de l'utilisateur et que vous avez besoin de modération, intégrez des modérateurs humains.

13
Axel

En ce qui concerne votre sous-question "astuce du système", vous pouvez y remédier en normalisant la liste des "mots incorrects" et le texte saisi par l'utilisateur avant de lancer votre recherche. Par exemple, utilisez une série de expressions rationnelles (ou tr si PHP l'a)) pour convertir [z $ 5] en "s", - [4 @] à "a", etc., puis comparez la liste normalisée des "mots erronés" au texte normalisé. Notez que la normalisation peut potentiellement conduire à d'autres faux positifs, bien que je ne puisse pas penser de tous les cas réels en ce moment.

Le plus gros défi consiste à proposer quelque chose qui permettra aux gens de citer "Le le stylo est plus puissant que l'épée" tout en bloquant "P e n i s".

7
Dave Sherohman

Méfiez-vous des problèmes de localisation: ce qui est un gros mot dans une langue peut être un mot parfaitement normal dans une autre.

Un exemple courant de ceci: eBay utilise une approche de dictionnaire pour filtrer les "mauvais mots" des commentaires. Si vous essayez de saisir la traduction allemande de "ceci était une transaction parfaite" ("das war eine perfekte Transaktion"), eBay rejettera les commentaires en raison de mots incorrects.

Pourquoi? Parce que le mot allemand pour "était" est "guerre", et "guerre" est dans le dictionnaire eBay de "mauvais mots".

Alors méfiez-vous des problèmes de localisation.

7
Sam

Si vous pouvez faire quelque chose comme Digg/Stackoverflow où les utilisateurs peuvent voter/marquer du contenu obscène ... faites-le.

Ensuite, tout ce que vous avez à faire est de passer en revue les utilisateurs "vilains" et de les bloquer s'ils enfreignent les règles.

6
scunliffe

Je suis un peu en retard à la fête, mais j'ai une solution qui pourrait fonctionner pour ceux qui lisent ceci. C'est en javascript au lieu de php, mais il y a une raison valable à cela.

Divulgation complète, j'ai écrit ce plugin ...

Quoi qu'il en soit.

L’approche que j’ai choisie est de permettre à un utilisateur de s’inscrire au filtrage par profanation. En gros, les blasphèmes seront autorisés par défaut, mais si mes utilisateurs ne veulent pas le lire, ils ne le seront pas. Cela aide également à résoudre le problème "l33t sp3 @ k".

Le concept est un simple plugin jquery qui est injecté par le serveur si le compte du client active le filtrage profane. A partir de là, ce ne sont que quelques lignes simples qui effacent les jurons.

Voici la page de démonstration
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>

résultat

*** échouera mais le mot de passe ne sera pas

4
Chase Florell

Une fois que vous avez une bonne table MYSQL de mauvais mots que vous voulez filtrer (j'ai commencé avec l'un des liens de ce fil), vous pouvez faire quelque chose comme ceci:

$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 />";

Je suis sûr qu'il existe un moyen plus efficace de procéder à tous ces remplacements, mais je ne suis pas assez intelligent pour le savoir (et cela semble fonctionner correctement, bien que de manière inefficace).

Je pense que vous devriez autoriser les utilisateurs à s'inscrire et utiliser des humains pour filtrer et ajouter à votre tableau des profanations, selon les besoins. Bien que tout dépend du coût d'un faux positif (le mot correct est marqué comme mauvais) par rapport à un faux négatif (le mauvais mot passe). Cela devrait en fin de compte régir le degré d'agressivité ou de prudence de votre stratégie de filtrage.

Je serais également très prudent si vous souhaitez utiliser des caractères génériques, car ils peuvent parfois se comporter de manière plus onéreuse que vous ne le souhaitez.

2
andrew

Je suis d'accord avec le post de HanClinto plus haut dans cette discussion. J'utilise généralement des expressions régulières pour faire correspondre un texte d'entrée. Et c’est un effort vain, car, comme vous l’avez mentionné au départ, vous devez explicitement comptabiliser chaque astuce d’écriture populaire sur le net dans votre liste "bloquée".

Sur une note de côté, alors que d'autres débattent de l'éthique de la censure, je dois convenir qu'une forme est nécessaire sur le Web. Certaines personnes aiment simplement publier des propos vulgaires, car cela peut être immédiatement offensant pour un grand nombre de personnes et ne nécessite aucune réflexion de la part de l'auteur.

Merci pour les idées.

HanClinto règne!

2
msm516

J'ai rassemblé 2200 mauvais mots en 12 langues: en, ar, cs, da, de, eo, es, fa, fi, fr, salut, hu, il, ja, ko, nl, non, pl, pt, ru, sv , th, th, tr, zh.

Les options de vidage MySQL, JSON, XML ou CSV sont disponibles.

https://github.com/turalus/openDB

Je vous conseillerais d'exécuter ce SQL dans votre base de données et de vérifier chaque fois que l'utilisateur saisit quelque chose.

2
Tural Ali

Ne pas Cela ne fait que créer des problèmes. Mon expérience personnelle classique avec les filtres blasphoniques est celle où j’ai été banni/banni d’un canal IRC) pour avoir mentionné que je me dirigeais sur le pont de Hancock pendant quelques heures ou quelque chose du genre. à cet effet.

2
Adam Jaskiewicz

J'ai conclu, afin de créer un bon filtre de grossièretés, nous avons besoin de 3 composants principaux, ou du moins c'est ce que je vais faire. Ce sont:

  1. Le filtre: un service en arrière-plan qui vérifie une liste noire, un dictionnaire ou quelque chose comme ça.
  2. Ne pas autoriser les comptes anonymes
  3. Signaler un abus

Un bonus, ce sera pour récompenser en quelque sorte ceux qui contribuent avec des reporters d'abus précis et punir le contrevenant, par exemple. suspendre leurs comptes.

1
Jaider

Franchement, je les laisserais trouver les mots "tromper le système" et les interdire, ce qui est juste moi. Mais cela simplifie également la programmation.

Ce que je ferais, c’est d’implémenter un filtre regex comme suit: /[\s]dooby (doo?)[\s]/i ou si le mot est préfixé sur d’autres, /[\s]doob(er|ed|est)[\s]/. Celles-ci empêcheraient le filtrage de mots comme assuaged, ce qui est parfaitement valable, mais nécessiterait également la connaissance des autres variantes et la mise à jour du filtre même si vous en apprenez un nouveau. Évidemment, ce sont tous des exemples, mais vous devez décider comment le faire vous-même.

Je ne vais pas taper tous les mots que je connais, pas quand je ne veux pas les connaître.

1
Robert K

Je suis d'accord avec la futilité du sujet, mais si vous devez avoir un filtre, consultez Ning's Boxwood :

Boxwood est une extension PHP pour le remplacement rapide de plusieurs mots dans un texte. Elle prend en charge la correspondance sensible à la casse et insensible à la casse. Elle nécessite que le texte sur lequel il opère soit codé au format UTF- 8.

Voir aussi ce blog pour plus de détails:

Avec Boxwood, votre liste de termes de recherche peut être aussi longue que vous le souhaitez - l'algorithme de recherche et remplacement ne devient pas plus lent, avec davantage de mots sur la liste de mots à rechercher. Cela fonctionne en construisant un tri de tous les termes de recherche, puis en analysant votre texte sujet une seule fois, en décrivant les éléments du test et en les comparant aux caractères de votre texte. Il prend en charge l'US-ASCII et UTF-8, la mise en correspondance sensible à la casse ou insensible, et possède une logique de vérification des limites de mots centrée sur l'anglais.

1
Gordon

Aussi tard dans le jeu, mais faire quelques recherches et est tombé par ici. Comme d'autres l'ont mentionné, c'est presque presque impossible s'il était automatisé, mais si votre conception/exigence peut impliquer dans certains cas (mais pas tout le temps) des interactions humaines pour déterminer si c'est profane ou non, vous pouvez envisager le ML. https://docs.Microsoft.com/en-us/Azure/cognitive-services/content-moderator/text-moderation-api#profanity est mon choix actuel pour plusieurs raisons:

  • Prise en charge de nombreuses localisations
  • Ils continuent à mettre à jour la base de données, donc je n'ai pas à suivre les derniers argots ou langues (problème de maintenance)
  • Quand il y a une forte probabilité (c'est-à-dire 90% ou plus), vous pouvez simplement le nier de manière pragmatique.
  • Vous pouvez observer pour la catégorie qui cause un drapeau qui peut être ou ne pas être un blasphème, et peut demander à quelqu'un de le vérifier pour vous dire qu'il est ou non profane.

Pour mon besoin, il était/est basé sur un service commercial convivial (OK, jeux vidéo) dont les autres utilisateurs peuvent/verront le nom d'utilisateur, mais la conception exige qu'il soit soumis à un filtre grossier pour rejeter un nom d'utilisateur offensant. La partie triste à ce sujet est le problème classique "classique" qui se produira probablement puisque les noms d'utilisateur sont généralement des mots simples (jusqu'à N caractères) de plusieurs mots parfois concaténés ... Encore une fois, le service cognitif de Microsoft n'indiquera pas "Assist" en tant que texte. HasProfanity = true, mais peut signaler l'une des probabilités d'être élevée.

Lorsque le PO vous demande si vous avez "a $$", voici le résultat lorsque je l’ai passé à travers le filtre: enter image description here , comme vous pouvez le constater, il a été déterminé que ce n’est pas profane, mais il est fort probable que c’est le cas, signalez-le comme une recommandation de révision (interactions humaines).

Lorsque la probabilité est élevée, je peux soit revenir en arrière "je suis désolé, ce nom est déjà pris" (même si ce n'est pas le cas) afin qu'il soit moins offensant pour des personnes anti-censure ou quelque chose du genre, si nous ne voulons pas pour intégrer une révision humaine, ou renvoyer "Votre nom d'utilisateur a été notifié au service des opérations en direct, vous pouvez attendre que votre nom d'utilisateur soit revu et approuvé ou choisir un autre nom d'utilisateur". Ou peu importe...

Soit dit en passant, le coût/prix de ce service est assez faible pour moi (à quelle fréquence le nom d'utilisateur est-il changé?), Mais encore une fois, pour OP, la conception nécessite peut-être des requêtes plus intensives et n'est peut-être pas idéale pour payer/s'abonner Les services de ML, ou ne peuvent pas avoir d'analyse/interactions humaines. Tout dépend de la conception ... Mais si la conception convient, c'est peut-être la solution de OP.

Si vous êtes intéressé, je peux énumérer les inconvénients dans le commentaire à l'avenir.

0
HidekiAI