「悪い」単語のフィルターを書く

あなたの多くは、おそらく公開のマルチユーザーチャットに複数回行ったことがあるでしょう。 フォーラム、ウェブチャット、プロバイダーのLAN内のチャットサーバーのいずれであっても、理想的な順序は少数のユーザー(私の意見では100人以下)でのみ達成できます。 コミュニティが成長すると、ほぼ同じ問題が発生します。仲間、スパム、洪水-1つは「国のすべて」という個別の投稿を退屈させます。



理想的なマットフィルターはまだ発明されていません。 ただし、これは行わず、必要最小限の実装を検討します。





チェックメイト



もちろん、私たちはそれについて議論しています、誰が:)と主張しています。 私の見地からは、赤い言葉またはより大きな表現の表現のために仲間ができます。 しかし、誰もがそれを理解するのがそれほど簡単ではないため、それに耐える必要があります(または、「どれだけの問題に適合するか」という独自のコミュニティを作成する必要があります)。 特に魅力的でないのは、あまり賢くない/教育を受けた市民からのやる気の弱いマットの流れです。 さて、良心に任せましょう。



ロシア語は単語とフレーズの形成の可能性が非常に豊富であるため、多くのわいせつな構成を考えることができます-時々疑問に思うかもしれません。 そのため、(現時点では)これらの現象に対処しようとはしません。 額の解決策は辞書フィルターです。 辞書自体を組み立てるのは難しくないと思います。 私は約250語を得ました:)。



しかし、最初の実験では、この方法では肯定的な結果が得られないことが示されています。 ユーザーは、火災の最初の犠牲者数人の失敗を見て、非常に迅速にそれを回避することを学びます。 彼らはどうやってそれをしますか? 基本的に、いくつかのオプションがあります。



正規表現が助けになります。 上記に基づいて、文字置換テーブルを作成します。



(

'' => [ '' , 'a' , '@' ],

'' => [ '' , '6' , 'b' ],

'' => [ '' , 'b' , 'v' ],

'' => [ '' , 'r' , 'g' ],

'' => [ '' , 'd' , 'g' ],

'' => [ '' , 'e' ],

'' => [ '' , '' , 'e' ],

'' => [ '' , 'zh' , '*' ],

'' => [ '' , '3' , 'z' ],

'' => [ '' , 'u' , 'i' ],

'' => [ '' , 'u' , 'y' , 'i' ],

'' => [ '' , 'k' , 'i{' , '|{' ],

'' => [ '' , 'l' , 'ji' ],

'' => [ '' , 'm' ],

'' => [ '' , 'h' , 'n' ],

'' => [ '' , 'o' , '0' ],

'' => [ '' , 'n' , 'p' ],

'' => [ '' , 'r' , 'p' ],

'' => [ '' , 'c' , 's' ],

'' => [ '' , 'm' , 't' ],

'' => [ '' , 'y' , 'u' ],

'' => [ '' , 'f' ],

'' => [ '' , 'x' , 'h' , '' , 'k' , '}{' ],

'' => [ '' , 'c' , 'u,' ],

'' => [ '' , 'ch' ],

'' => [ '' , 'sh' ],

'' => [ '' , 'sch' ],

'' => [ '' , 'b' ],

'' => [ '' , 'bi' ],

'' => [ '' ],

'' => [ '' , '' , 'e' ],

'' => [ '' , 'io' ],

'' => [ '' , 'ya' ],

)




* This source code was highlighted with Source Code Highlighter .








ここで、辞書から正規表現ライブラリを作成する必要があります。 原則として、それらはオンザフライで設計できます。 分析の原理は単純です。文字の代わりに、表の任意のシーケンスを使用できます。 人々がスペース、ピリオドなどを挿入することによってだまされないように。 フィルターをバイパスする文字間-文字間の外観も考慮します。 さて、誤検出がないように、複雑な構造の派生を考慮せずに、単語全体のみを計算します。



はい、もちろん後者はフィルターの有効性をわずかに低下させますが、それにもかかわらず、変更された単語はもはやそれほどわいせつではなく、辞書で基本的な単語やフレーズの大部分を切り捨てることができます。 原則として、見苦しい言葉を隠すためだけにフィルターがトリガーされた場合(即時禁止ハンマーではない場合)、この条件は破棄されます。



その結果、よく知られている3文字の単語の場合、レギュラーシーズンは次のようになります。



m/(?:^|\W)((?:|x|h||k|}{)\W*[yu]\W*[uyi])(?:$|\W)/ig;









一般に、本質は簡単です。辞書を作成し、そこから正規表現のライブラリを生成し、フィルターで使用します。



アプローチの欠点:



つまり 一般に、これは万能薬ではありませんが、一定の封じ込め効果があります。



スパムと洪水



洪水、またはキャラクター、顔文字、文章の無意味な流れは、秩序を悩ますことがあります。 私たちの文脈では、スパムを「Fse f country! xxxx "または"人々に作成された、私のスーパーメガストページページのリンクに移動します。 ただし、これらの現象はチャットの特徴です。



テキストのセマンティック分析を使用せずに、この全体を純粋に機械的に追跡できますが、これを行う簡単な方法はありますか?



繰り返されるシンボルと絵文字の洪水では、一般にすべてが明確です。ライブチャットで最も頻繁に発生する洪水パターンを調べ、それらを使用して定量化します。 ほんの数例:



/(.)\\1{15,}/is;

/(.{3,})\\1{5,}/is;

/(\n|\r|\r\n)\\1{3,}/is;









状況は、フレーズの繰り返しにより複雑になります。 額へのアプローチは非常に原始的です。ユーザーの最後からn番目のメッセージを比較し、偶然一致した場合は「動作」します。



抵抗する最初の方法は、行にスペースを追加し、句読点(ドット、感嘆符)の数を変更することです。 ただし、このような変更を考慮した行の正規化を行うことができます。たとえば、不要な変更をすべて削除します。



ただし、ここでは、抵抗の第2波で失敗が見つかります。フレーズがわずかに変化し始め、間投詞、導入語などが追加されます。 ここでは、ファジー比較アルゴリズムがすでに有用です。



たとえば、 レーベンシュタイン距離を計算できます。 このアルゴリズムの実装はそれほど複雑ではなく、ほとんどの一般的な言語で使用できます。また、phpでは一般的にネイティブに存在します。 実際、最初の行から2番目の行を取得するために必要な編集回数の行の差を返します。



さらに、技術的な問題:応答する最小メッセージサイズを決定し、距離を考慮し、たとえばメッセージの長さの20%を超えない場合は、それを繰り返します! すべてがシンプルです。 通常のユーザーに干渉しないように、メッセージの長さと距離のしきい値を経験的に選択します。



もちろん、この方法は、すべてを手動で送信する退屈な個人に対抗する場合にのみ役立ちます(したがって、小さな編集とフレーズの頻度)。 ユーザーが異質なメッセージを驚くべき速度で送信する場合、これはスパムボットである可能性が高く、ここではライブモデレーターの他のアプローチまたはアクションが必要です。



まとめ



そのため、一般的な用語で、メイト、フラッド、スパムに対抗する方法を検討しました。 提案された方法は、ショートメッセージチャットシステムに最も関連しています。 多くの点で、アプローチの単純さは、このような一般的にかなり複雑なものを正規表現として使用しているためです。



句の形態学的および意味解析の試みを含む、代替方法が存在します。 ただし、同じAIMLのイデオロギーに従えば、入力と出力の間に「コンピューターが多すぎる」ことを埋め込むことなく、人間のような行動を非常に経験的に得ることができます。



この情報が誰かに役立つことを願っています。 どんなコメントでも喜んでいます。 時間が経つにつれて、私は上記のアクションの私自身の実装を公開しようとします。



All Articles