web-dev-qa-db-ja.com

適切な冒fan的なフィルターをどのように実装しますか

私たちの多くは、ユーザー入力、検索クエリ、および入力テキストに冒とく的または望ましくない言語が含まれる可能性がある状況に対処する必要があります。多くの場合、これは除外する必要があります。

さまざまな言語や方言の宣誓単語の良いリストはどこにありますか?

適切なリストを含むソースで利用可能なAPIはありますか?または、単に「はい、これはきれいです」または「これは汚れていません」といくつかのパラメーターで言うAPI?

A $$、azz、a55など、システムをだまそうとする人々を捕まえるための良い方法は何ですか?

PHPのソリューションを提供する場合のボーナスポイント。 :)

編集:単にプログラムの問題を回避するという回答への応答:

たとえば、ユーザーがパブリックイメージ検索を使用して、デリケートなコミュニティプールに追加される写真を見つけることができる場合、この種のフィルターの場所があると思います。彼らが「ペニス」を検索できるなら、彼らはたぶん多くの写真を得るでしょう。その写真が必要ない場合は、Wordを検索用語として使用しないようにすることは、間違いなく確実な方法ではありませんが、優れた門番です。そもそも単語のリストを取得することが本当の問題です。

だから、私は本当に単一のトークンが汚れているかどうかを把握し、それを単純に禁止する方法に言及しています。私は完全に陽気な「長い首のキリン」参照のような感情を妨げることを気にしません。そこでできることは何もありません。 :)

195
Ben Throop

bsフィルター:悪い考え、または信じられないほど相互に作用する悪い考え?

また、忘れることはできません トゥーンタウンのSpeedChatの未定の歴史 、「セーフワードホワイトリスト」を使用しても、14歳ですぐにそれを回避できました:」首の長いキリンをふわふわした白いウサギに突き刺したい。」

結論:最終的に、実装するシステムには、人間によるレビューに代わるものはまったくありません(ピアかどうかに関係なく)。ドライブバイを取り除くための初歩的なツールを自由に実装できますが、断固としたトロールには、アルゴリズムに基づかないアプローチが絶対に必要です。

匿名性を取り除き、説明責任(Stack Overflowがうまくいくもの)を導入するシステムも、特に戦闘を支援するために役立ちます John Gabriel's G.I.F.T。

また、冒とくするために冒fanリストを入手できる場所を尋ねました-チェックアウトするオープンソースプロジェクトの1つは Dansguardian -デフォルトの冒fanリストのソースコードをチェックアウトすることです。また、追加のサードパーティ フレーズリスト があります。これは、プロキシ用にダウンロードできます。これは、役に立つ収集ポイントになる可能性があります。

質問edit:に応答して編集してください。あなたがやろうとしていることを明確にしてくれてありがとう。その場合、単純なWordフィルターを実行しようとしているだけであれば、2つの方法があります。 1つは、検閲する禁止フレーズのすべてを含む単一の長い正規表現を作成し、単に正規表現を検索/置換することです。次のような正規表現:

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

preg_match() を使用して入力文字列で実行し、ヒットのテストをホールセールします。

または preg_replace() で空白にします。

単一の長い正規表現ではなく配列を使用してこれらの関数をロードすることもできます。長いWordリストの場合は、より管理しやすくなります。配列を柔軟に使用する方法の良い例については、 preg_replace() を参照してください。

追加のPHPプログラミング例については、このページを参照してください やや高度な汎用クラス 修正された単語から中心文字を除外するWordフィルタリングについて、および 前スタックオーバーフローの質問 また、PHPの例もあります(そこにある主な重要な部分は、SQLベースのフィルター処理されたWordのアプローチです。 。

また、「最初に単語のリストを取得するのが本当の問題です。」-以前のDansgaurdianリンクのいくつかに加えて、あなたは見つけるかもしれません この便利な.Zip 458語のうち、役に立つと思います。

174
HanClinto

この質問はかなり古いことは知っていますが、よくある質問です...

冒fan的なフィルタには理由と明確な必要性の両方があります( Wikipediaのエントリはこちら を参照してください)が、非常に明確な理由で100%正確であるとは言えません。 Contextおよびaccuracy

達成しようとしていることに完全に依存します-最も基本的なのは、おそらく " seven dirty words "をカバーしようとしていることです...最も基本的な冒fan:基本的な誓いの言葉、URL、または個人情報など、他の人は不正なアカウントの命名(Xbox liveがその一例です)などを防ぐ必要があります...

ユーザー生成コンテンツには、潜在的な悪意のある言葉が含まれているだけでなく、以下への攻撃的な参照も含まれています

  • 性行為
  • 性的指向
  • 宗教
  • 人種
  • 等...

そして、潜在的に、複数の言語で。 Shutterstockは、これまで10言語で 基本的なダーティワードリスト を開発しましたが、それでも基本的なものであり、「タグ付け」のニーズを重視しています。 Webには他にも多くのリストがあります。

定義済みの科学ではなく、as言語は絶えず進化しているチャレンジですが、90%キャッチ率は0%よりも優れています。それは純粋にあなたの目標に依存します-あなたが達成しようとしているもの、あなたが持っているサポートのレベル、そして異なるタイプの冒proを取り除くことがどれだけ重要か。

フィルターを作成する際には、次の要素と、それらがプロジェクトにどのように関係しているかを考慮する必要があります。

  • 単語/フレーズ
  • 頭字語(FOAD/LMFAOなど)
  • False positives (「ミスした」、「スカンソープ」、「タイツワース」などの単語、場所、名前)
  • URL(ポルノサイトは明らかなターゲットです)
  • 個人情報(電子メール、住所、電話など-該当する場合)
  • 言語の選択(通常はデフォルトで英語)
  • モデレート(ユーザーが生成したコンテンツと、もしあれば、どのようにやり取りできるか)

冒proの90%以上をキャプチャする冒fanフィルターを簡単に作成できますが、100%に達することはありません。それは不可能です。 100%に近づけるほど難しくなります...過去に1日あたり50万件を超えるリアルタイムメッセージを処理する複雑な冒とくエンジンを構築したので、次のアドバイスを提供します。

基本的なフィルターには以下が含まれます:

  • 該当する冒とくのリストの作成
  • 冒とくの派生物に対処する方法の開発

適度に複雑なファイラーには、(基本的なフィルターに加えて)含まれます:

  • 複雑なパターンマッチングを使用して拡張派生を処理する(高度な正規表現を使用)
  • Leetspeak (l33t)の取り扱い
  • false positives の取り扱い

複雑なフィルターには、次のものが含まれます(中程度のフィルターに加えて):

  • ホワイトリスト およびブラックリスト
  • 単純ベイズ推論 フレーズ/用語のフィルタリング
  • Soundex 関数(Wordは別の単語のように聞こえます)
  • レーベンシュタイン距離
  • ステミング
  • フィルタリングエンジンをガイドして、例によって学習したり、ガイダンスなしでは一致が十分に正確でない場所を学習したりするためのヒューマンモデレーター(自己/継続的に改善するシステム)
  • おそらく何らかの形のAIエンジン
40
nickhar

私はこれに適したライブラリを知りませんが、何をするにしても、あなたが物事を通過させる方向に間違いがあることを確認してください。サブストリングとして「ass」が含まれているため、ユーザー名として「mpassell」を使用できないシステムを扱っています。それはユーザーを疎外する素晴らしい方法です!

26
Matt Passell

私の就職の面接で、私に面接していた会社のCTOは、Javaで書いたWord/webゲームを試しました。オックスフォード英語辞書全体の単語リストのうち、最初に推測される単語は何でしたか?

もちろん、英語で最も汚い言葉。

どういうわけか、私はまだ仕事の申し出を得ましたが、その後、冒fan的な単語リストを追跡し( これとは異なります ではありません)、すべての悪い単語なしで(さえもせずに)新しい辞書を生成する簡単なスクリプトを書きましたリストを見なければなりません)。

特定のケースでは、検索を実際の単語と比較することは、そのような単語リストを使用する方法のように聞こえると思います。別のスタイル/句読点にはもう少し作業が必要ですが、ユーザーが問題になるほど頻繁に使用することはないでしょう。

23
Matthew

冒the的なフィルタリングシステムは、プログラマーが無謀であり、すべてのヌード開発に遅れずについていても、決して完璧ではありません。

とはいえ、根本的な問題は言語理解であるため、「いたずらな単語」のリストは他のリストと同様に機能する可能性が高い

したがって、唯一の実用的な解決策は2つあります。

  1. 辞書を頻繁に更新する準備をしてください
  2. 誤検知(「クラシック」ではなく「clbuttic」など)および誤検知(おっと!見逃した!)
21
Steven A. Lowe
13
Tim Cavanaugh

不快なユーザー入力を防ぐ唯一の方法は、すべてのユーザー入力を防ぐことです。

ユーザー入力を許可し、モデレートが必要な場合は、ヒューマンモデレーターを組み込みます。

13
Axel

「システムのトリック」サブ質問に関しては、検索を行う前に「悪い単語」リストとユーザーが入力したテキストの両方を正規化することで、それを処理できます。例えば、一連の正規表現(またはPHPがあればtr)を使用して[z $ 5]を "s"に変換します[4 @]を「a」などに変換し、正規化された「悪い単語」リストを正規化されたテキストと比較します。現時点で実際のケースを考えることはできませんが、正規化により追加の誤検知が発生する可能性があることに注意してください。

より大きな課題は、人々が「pen is剣よりも強大」を引用し、「p e n i s」をブロックできるようにすることです。

7
Dave Sherohman

ローカライズの問題に注意してください:ある言語での悪意のある言葉は、別の言語では完全に普通の言葉かもしれません。

これの現在の例:ebayは辞書アプローチを使用して、フィードバックから「悪い言葉」をフィルタリングします。 「これは完璧な取引でした」(「das war eine perfekte Transaktion」)のドイツ語の翻訳を入力しようとすると、ebayは不適切な言葉のためにフィードバックを拒否します。

どうして? 「だった」というドイツ語の単語は「戦争」であり、「戦争」は「悪い単語」のebay辞書にあるからです。

ローカリゼーションの問題に注意してください。

7
Sam

Digg/Stackoverflowのように、ユーザーがわいせつなコンテンツにダウン票/マークを付けることができる場合...そうします。

あとは、「いたずらな」ユーザーを確認し、ルールに違反しているユーザーをブロックするだけです。

6
scunliffe

私はパーティーに少し遅れていますが、これを読んでいる人にとってはうまくいく解決策があります。 phpではなくjavascriptで記述されていますが、正当な理由があります。

完全な開示、私はこのプラグインを書きました...

いずれかの方法。

私が行ったアプローチは、ユーザーが冒fan的なフィルタリングに「オプトイン」できるようにすることです。基本的に冒とく的な表現はデフォルトで許可されますが、ユーザーが読みたくない場合は読む必要はありません。これは、「l33t sp3 @ k」の問題にも役立ちます。

コンセプトはシンプルです jquery クライアントのアカウントが冒fan的なフィルタリングを有効にしている場合にサーバーによって挿入されるプラグインです。そこから、誓いを消し去るのはほんの2、3の簡単な線です。

デモページはこちら
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>

結果

***は失敗しますが、パスワードは失敗しません

4
Chase Florell

フィルタリングしたいいくつかの悪い単語の良いMYSQLテーブルができたら(このスレッドのリンクの1つから始めました)、次のようなことができます:

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

これらすべての置換を行うより効率的な方法があると確信していますが、私はそれを理解するのに十分賢くはありません(そして、これは非効率的ではありますが、大丈夫に働くようです)。

ユーザーの登録を許可し、必要に応じて人を使って冒pro表をフィルタリングおよび追加することを許可する側で誤解する必要があると思います。それはすべて、偽陽性(悪いというフラグが付けられたWord)対偽陰性(悪いWordが通り抜ける)のコストに依存しますが。最終的には、フィルタリング戦略においてどれだけ積極的か保守的かを決定する必要があります。

また、ワイルドカードを使用する場合は、意図しない動作をする可能性があるため、非常に注意してください。

2
andrew

この議論の上位にあるHanClintoの投稿に同意します。私は通常、入力テキストを文字列に一致させるために正規表現を使用します。そして、これは無駄な努力です。あなたが最初に言ったように、あなたは「ブロックされた」リストでネット上で人気のあるあらゆる書き方を明示的に説明しなければなりません。

補足として、他の人は検閲の倫理を議論していますが、ウェブ上で何らかのフォームが必要であることに同意しなければなりません。一部の人々は、下品な投稿を単に楽しんでいるだけで、大勢の人々を不快にさせることができ、作者側の考えをまったく必要としないため、単に下品な投稿を楽しんでいます。

アイデアをありがとう。

HanClintoのルール!

2
msm516

En、ar、cs、da、de、eo、es、fa、fi、fr、hi、hu、it、ja、ko、nl、no、pl、pt、ru、svの2200の悪い単語を収集しました、th、tlh、tr、zh。

MySQLダンプ、JSON、XMLまたはCSVオプションが利用可能です。

https://github.com/turalus/openDB

このSQLをDBに実行し、ユーザーが何かを入力するたびに確認することをお勧めします。

2
Tural Ali

結論として、適切な冒fan的なフィルタを作成するには、3つの主要なコンポーネントが必要です。少なくとも、これは私がやろうとしていることです。これらは次のとおりです。

  1. フィルター:ブラックリスト、辞書などに照らして検証するバックグラウンドサービス。
  2. 匿名アカウントを許可しない
  3. 不正行為を報告

おまけに、正確な虐待レポーターで貢献し、犯罪者を罰する人々に何らかの形で報いることです。アカウントを一時停止します。

1
Jaider

率直に言って、私は彼らに「システムをだます」という言葉を出させて、代わりに彼らを禁止させました。ただし、プログラミングも簡単になります。

私がやることは、次のような正規表現フィルターを実装することです:/[\s]dooby (doo?)[\s]/iまたは、Wordが他の接頭辞/[\s]doob(er|ed|est)[\s]/に付けられます。これらは完全に有効なassuagedのような単語のフィルタリングを防ぎますが、他のバリアントの知識と新しいフィルタを学習する場合は実際のフィルタの更新も必要になります。明らかにこれらはすべて例ですが、自分でそれを行う方法を決定する必要があります。

私が知っているすべての単語を入力するつもりはありません。実際にそれらを知りたくないときではありません。

1
Robert K

主題の無益さに同意しますが、フィルターが必要な場合は、Ningの Boxwood を確認してください。

Boxwoodは、テキスト内の複数の単語を高速で置換するためのPHP拡張機能です。大文字と小文字を区別するマッチングと大文字と小文字を区別しないマッチングをサポートします。動作するテキストはUTF-8としてエンコードされる必要があります。

詳細については、このブログ投稿も参照してください。

Boxwoodを使用すると、検索用語のリストを好きなだけ長くすることができます。検索および置換アルゴリズムは、検索する単語のリストに含まれる単語が増えても遅くなりません。すべての検索用語のトライを作成し、対象テキストを1回だけスキャンし、トライの要素を歩いて、テキスト内の文字と比較することで機能します。 US-ASCIIとUTF-8、大文字と小文字を区別する、または区別しないマッチングをサポートし、いくつかの英語中心のWord境界チェックロジックを備えています。

1
Gordon

ゲームの後半でも、いくつかの調査を行って、ここで偶然見つけました。他の人が言ったように、それが自動化された場合、それはほとんど不可能に近いですが、デザイン/要件が場合によっては(しかし常にではない)人間のやり取りが不敬であるかどうかを確認することができる場合、MLを検討することができます。 https://docs.Microsoft.com/en-us/Azure/cognitive-services/content-moderator/text-moderation-api#profanity は、現在さまざまな理由で私の選択です:

  • 多くのローカライズをサポート
  • データベースを更新し続けるので、最新のスラングや言語についていく必要はありません(メンテナンスの問題)
  • 可能性が高い場合(つまり、90%以上)、実際に拒否することができます。
  • 冒とく的であるかどうかわからないフラグの原因となるカテゴリを観察し、誰かにレビューして、それが冒or的であるかどうかを教えることができます。

私の必要性のために、それは他のユーザーがユーザー名を見る/見る公的な商用サービス(OK、ビデオゲーム)に基づいていました/しかし、デザインは不快なユーザー名を拒否するために冒proフィルターを通過する必要があります。これについての悲しい部分は、ユーザー名は通常複数の単語が連結された単一の単語(最大N文字)であるため、古典的な「clbuttic」問題が発生する可能性が高いことです。繰り返しますが、Microsoftの認知サービスは「Assist」をテキストとしてフラグ付けしません。 HasProfanity = trueですが、カテゴリのいずれかの確率が高いとフラグを立てることがあります。

OPが「a $$」について尋ねると、フィルターを通過した結果がここにあります: enter image description here ご覧のように、不敬ではないと判断しましたが、そうである可能性が高いため、レビューの推奨としてフラグを立てます(人間のやり取り)。

可能性が高い場合は、「申し訳ありませんが、その名前はすでに使用されています」と返すことができます。そうでない場合でも、反検閲の人や何かに対する不快感が少なくなります人間のレビューを統合するか、「ユーザー名が実際の運用部門に通知されました。ユーザー名が確認および承認されるまで待つか、別のユーザー名を選択する」ことができます。または何でも...

ちなみに、このサービスのコスト/価格は私の目的では非常に低いです(ユーザー名はどのくらいの頻度で変更されますか?)が、再び、OPではデザインがより集中的なクエリを要求し、支払い/購読するのが理想的ではない可能性がありますMLサービス、または人間によるレビュー/相互作用はありません。それはすべて設計に依存します...しかし、設計が法案に適合する場合は、おそらくこれがOPのソリューションになります。

興味があれば、私は将来のコメントに短所をリストすることができます。

0
HidekiAI