6

C2C Webサイトがあり、Webサイトでブランド製品を販売することはお勧めしません。NikeD&Gなどのブランドワードのデータベースを構築し、これらのワードの製品情報をフィルタリングし、これらのワードが含まれている場合は製品を無効にするアルゴリズムを作成しました。

現在のアルゴリズムでは、提供されたテキストからすべての空白と特殊文字を削除し、データベースの単語とテキストを照合します。これらのケースは、アルゴリズムによってキャッチされる必要があり、効率的にキャッチされます。

  • 私はナイキワールドです
  • 私はnikeeの靴を持っています
  • 私はnikeeshoesを持っています
  • 私はi-phoneのケーシングを販売しています
  • 私はiPhoneのケーシングを販売しています
  • あなたはiPhoneを持つことができます

ここで問題となるのは、次のこともキャッチすることです。

  • rapiD縫製工場(D&G用)
  • rosNIK Electronics(ナイキ用)

真のケースをキャッチすることで効率を維持しながら、そのような誤った一致を防ぐために何ができるでしょうか?

編集

コードをよく理解している方のためのコードは次のとおりです。

$orignal_txt = preg_replace('/&.{0,}?;/', '', (strip_tags($orignal_txt)));
$orignal_txt_nospace = preg_replace('/\W/', '', $orignal_txt);
{
    $qry_kws = array("nike", "iphone", "d&g");
    foreach($qry_kws as $rs_kw)
    {       
        $no_space_db_kw = preg_replace('/\W/', '', $rs_kw);
        if(stristr($orignal_txt_nospace, $rs_kw))
        {
            $ipr_banned_keywords[] = strtolower($rs_kw);
        }
        else if(stristr($orignal_txt_nospace, $no_space_db_kw))
        {
                $ipr_banned_keywords[] = strtolower($rs_kw);
        }

    }
}
4

4 に答える 4

5

遊んでいるだけ....(本番環境では使用しないでください)

$data = array(
        "i am nike world",
        "i have n ikee shoes",
        "i have nikeeshoes",
        "i sell i-phone casings",
        "i sell iphone-casings",
        "you can have iphone",
        "rapiD Garment factor",
        "rosNIK Electronics",
        "Buy you self N I K E",
        "B*U*Y I*P*H*O*N*E BABY",
        "My Phone Is not available");


$ban = array("nike","d&g","iphone");

例1:

$filter = new BrandFilterIterator($data);
$filter->parseBan($ban);
foreach ( $filter as $word ) {
    echo $word, PHP_EOL;
}

出力1

rapiD Garment factor
rosNIK Electronics
My Phone Is not available

例2

$filter = new BrandFilterIterator($data,true); //reverse filter
$filter->parseBan($ban);
foreach ( $filter as $word ) {
    echo $word, " " , json_encode($word->getBan()) ,  PHP_EOL;
}

出力2

i am nike world ["nike"]
i have n ikee shoes ["nike"]
i have nikeeshoes ["nike"]
i sell i-phone casings ["iphone"]
i sell iphone-casings ["iphone"]
you can have iphone ["iphone"]
Buy you self N I K E ["nike"]
B*U*Y I*P*H*O*N*E BABY ["iphone"]

使用したクラス

class BrandFilterIterator extends FilterIterator {
    private $words = array();
    private $reverse = false;

    function __construct(array $words, $reverse = false) {
        $this->reverse = $reverse;
        foreach ( $words as $word ) {
            $this->words[] = new Word($word);
        }
        parent::__construct(new ArrayIterator($this->words));
    }

    function parseBan(array $ban) {
        foreach ( $ban as $item ) {
            foreach ( $this->words as $word ) {
                $word->checkMetrix($item);
            }
        }
    }

    public function accept() {
        if ($this->reverse) {
            return $this->getInnerIterator()->current()->accept() ? false : true;
        }
        return $this->getInnerIterator()->current()->accept();
    }
}


class Word {
    private $ban = array();
    private $word;
    private $parts;
    private $accept = true;

    function __construct($word) {
        $this->word = $word;
        $this->parts = explode(" ", $word);
    }

    function __toString() {
        return $this->word;
    }

    function getTrim() {
        return preg_replace('/\W/', '', $this->word);
    }

    function accept() {
        return $this->accept;
    }

    function getBan() {
        return array_unique($this->ban);
    }

    function reject($ban = null) {
        $ban === null or $this->ban[] = $ban;
        $this->accept = false;
        return $this->accept;
    }

    function checkMetrix($ban) {
        foreach ( $this->parts as $part ) {
            $part = strtolower($part);
            $ban = strtolower($ban);
            $t = ceil(strlen(strtolower($ban)) / strlen($part) * 100);
            $s = similar_text($part, $ban, $p);
            $l = levenshtein($part, $part);
            if (ceil($p) >= $t || ($t == 100 && $p >= 75 && $l == 0)) {
                $this->reject($ban);
            }
        }
        // Detect Bad Use of space
        if (ceil(strlen($this->getTrim()) / strlen($this->word) * 100) < 75) {
            if (stripos($this->getTrim(), $ban) !== false) {
                $this->reject($ban);
            }
        }
        return $this->accept;
    }
}
于 2012-12-21T12:03:05.503 に答える
3

簡単です。スペースや特殊文字を削除する前に、ブランドを一致させてください。そうすると、これらの奇妙なエッジケースとは一致しなくなります。

于 2012-12-21T09:39:28.433 に答える
3

あなたはすでにこれを知っていますが、はっきりと言う価値があります:あなたの現在のアルゴリズムはタスクに対して完全に不十分です。単純なケースでさえも処理できません。ましてや、人々が意図的にフィルターを通過しようとするケースも処理できません。現在のフィルターでできることは1つだけです。それは、フィルターを完全に破棄することです。それを機能させることはできません。

ここではオブセニティフィルターについては説明していませんが、これはほぼ同じ種類の概念であるため、オブセニティフィルターによって発生した最悪の間違いのいくつかを読むことをお勧めします。

これらの記事は主に誤検知を扱っています。つまり、フィルターが本来あるべきではないものと一致し、正当なエントリをブロックする場合です。この種のことはあなたの顧客を混乱させ、それがたくさん起こると人々をあなたのサイトから遠ざけるので非常に損害を与える可能性があります。自然言語の複雑さはそれをほとんど避けられないものにします。

また、偽陰性に注意する必要があります。これらは、フィルターが取得する必要のあるものを取得できない場所です。ここでのあなたの問題は、スパマーがフィルターを通過するための技術の膨大な武器を持っているということです。現在のフィルターを通過するのは簡単ですが、最も高度なフィルターでさえも無効にすることができます。これの証拠として、受信トレイに受信するスパムの量を確認してください。そして、彼らは常に技術を変えているので、静的アルゴリズムは単に長期的には機能しません。

ベイジアンフィルターが最適なソリューションのように思われます。これらは、進むにつれて学習するフィルターです。それらを監視し、何をフィルタリングする必要があるかを認識するようにトレーニングする必要があるため、設定するのは少し手間がかかりますが、他の方法で実行可能な解決策があるとは思えません。

于 2012-12-21T10:09:08.387 に答える
1

これがただのアイデアです。

最初にマッチングを行ってみませんか。それが「ブランド」フィルターにヒットすると、レビューキューに入れられて承認/拒否され、簡単に見つけられるように一致が強調表示されます。

人間は、ブランドがほぼ即座に正確に使用されているかどうかを確認できます。これを機械学習に変えることもできます。

そうは言っても、これは正規表現の問題ではなく、気の利いた表現では解決できません。システムをトレーニングし、ヒットを覚えて(自信を高めて)、ミスから学ぶ必要があります。

于 2012-12-21T09:46:11.577 に答える