6

POSタグ付けに基づいて文を否定する方法を見つけようとしています. 考えてください:

include_once 'class.postagger.php';

function negate($sentence) {  
  $tagger = new PosTagger('includes/lexicon.txt');
  $tags = $tagger->tag($sentence);
  foreach ($tags as $t) {
    $input[] = trim($t['token']) . "/" . trim($t['tag']) .  " ";
  }
  $sentence = implode(" ", $input);
  $postagged = $sentence;

  // Concatenate "not" to every JJ, RB or VB
  // Todo: ignore negative words (not, never, neither)
  $sentence = preg_replace("/(\w+)\/(JJ|MD|RB|VB|VBD|VBN)\b/", "not$1/$2", $sentence);

  // Remove all POS tags
  $sentence = preg_replace("/\/[A-Z$]+/", "", $sentence);

  return "$postagged<br>$sentence";
}

ところで: この例では、Ian BarberのPOS タグ付けの実装レキシコンを使用しています。このコードの実行例は次のとおりです。

echo negate("I will never go to their place again");
I/NN will/MD never/RB go/VB to/TO their/PRP$ place/NN again/RB 
I notwill notnever notgo to their place notagain

ご覧のとおり (この問題はコードでもコメントされています)、否定語自体は wel: become として否定されていますnevernotnever、これは明らかに発生すべきではありません。私の正規表現スキルはそれだけではないので、使用される正規表現からこれらの単語を除外する方法はありますか?

[編集] また、この否定的な実装についての他のコメントや批評を大歓迎します。なぜなら、(まだ) かなり欠陥があると確信しているからです :-)

4

1 に答える 1

3

これを試してください:

$sentence = preg_replace("/(\s)(?:(?!never|neither|not)(\w*))\/(JJ|MD|RB|VB|VBD|VBN)\b/", "$1not$2", $sentence);
于 2012-05-04T19:09:59.207 に答える