4

私は実際にNLPを扱ったことはありませんでしたが、NERについて考えていましたが、これは機能しないはずであり、ある場合にはどういうわけか非常にうまく機能します。なぜそれが機能するのか、なぜそれが機能しないのか、またはそれが延長できる天気がわからない。

アイデアは、ストーリーの主人公の名前を次の方法で抽出することでした。

  1. 単語ごとに辞書を作成する
  2. 各単語のリストに、テキストのすぐ隣に表示される単語を入力します
  3. 各単語について、リストの相関が最大の単語を検索します(つまり、単語はテキスト内で同様に使用されます)
  4. 物語の中のキャラクターの名前の1つを考えると、そのように使用される単語も同様である必要があります(偽物、それは機能しないはずですが、今朝までNLPを扱ったことがなかったので、私は素朴な一日を始めました)

不思議の国のアリスで非常に単純なコード(以下に添付)を実行しました。これは「アリス」に対して次のように返されます。

21 ['マウス'、'緯度'、'ウィリアム'、'ウサギ'、'ドードー'、'グリフォン'、'カニ'、'クイーン'、'公爵夫人'、'フットマン'、'パンサー'、'キャタピラー'、 'Hearts'、'King'、'Bill'、'Pigeon'、'Cat'、'Hatter'、'Hare'、'Turtle'、'Dormouse']

大文字の単語をフィルタリングしますが(そして、クラスター化する単語として「Alice」を受け取ります)、元々は大文字の単語が500個まであり、メインキャラクターに関してはまだかなりの位置にあります。

他のキャラクターや他のストーリーではうまく機能しませんが、興味深い結果が得られます。

このアイデアが使用可能、拡張可能であるかどうか、または「アリス」のこのストーリーでなぜそれがまったく機能するのか、何かアイデアはありますか?

ありがとう!

#English Name recognition
import re
import sys
import random
from string import upper

def mimic_dict(filename):
  dict = {}
  f = open(filename)
  text = f.read()
  f.close()
  prev = ""
  words = text.split()
  for word in words:
    m = re.search("\w+",word)
    if m == None:
      continue
    word = m.group()
    if not prev in dict:
      dict[prev] = [word]
    else :
      dict[prev] = dict[prev] + [word] 
    prev = word
  return dict

def main():
  if len(sys.argv) != 2:
    print 'usage: ./main.py file-to-read'
    sys.exit(1)

  dict = mimic_dict(sys.argv[1])
  upper = []
  for e in dict.keys():
    if len(e) > 1 and  e[0].isupper():
      upper.append(e)
  print len(upper),upper

  exclude = ["ME","Yes","English","Which","When","WOULD","ONE","THAT","That","Here","and","And","it","It","me"]
  exclude = [ x  for x in exclude if dict.has_key(x)] 
  for s in exclude :
    del dict[s]

  scores = {}
  for key1 in dict.keys():
    max = 0
    for key2 in dict.keys():
      if key1 == key2 : continue
      a =  dict[key1]
      k =  dict[key2]
      diff = []
      for ia in a:
        if ia in k and ia not in diff:
          diff.append( ia)
      if len(diff) > max:
        max = len(diff)
        scores[key1]=(key2,max)
  dictscores = {}
  names = []
  for e in scores.keys():
    if scores[e][0]=="Alice" and e[0].isupper():
      names.append(e)
  print len(names), names     


if __name__ == '__main__':
  main()
4

2 に答える 2

7

あなたのプログラムの見た目とNERでの以前の経験から、あなたが適切な評価をしていないので、これは「うまくいく」と思います。「マーチハレ」を見つけたはずの「ハレ」を見つけました。

NERの難しさ(少なくとも英語では)は名前を見つけられないことです。それらの全範囲を検出しています(「マーチヘア」の例)。すべての単語が大文字になっている文の先頭でもそれらを検出します。それらを人/組織/場所などとして分類します。

また、子供の小説である不思議の国のアリスは、処理するのがかなり簡単なテキストです。「MicrosoftCEOのSteveBallmer」のようなニュースワイヤーのフレーズは、はるかに難しい問題を引き起こします。ここでは、検出したい

[ORG Microsoft] CEO [PER Steve Ballmer]
于 2012-05-14T15:24:35.083 に答える
3

あなたがしているのは、分布シソーラスを構築することです-クエリに分布的に類似している単語(例えば、アリス)、すなわち、類似した文脈で現れる単語を見つけます。これにより、自動的に同義語になるわけではありませんが、クエリに似ていることを意味します。クエリが名前付きエンティティであるという事実は、取得した類似の単語が名前付きエンティティになることをそれ自体で保証するものではありません。ただし、以降AliceHareおよびQueenいくつかの特徴を共有しているため(たとえば、すべてが話したり、歩いたり、泣いたりします。不思議の国のアリスの詳細は私を逃れます)、表示される傾向があります。単語が大文字であるかどうかは、何かが名前付きエンティティであるかどうかを判断するときに非常に役立つ情報であることがわかります。大文字でない単語を除外しないと、エンティティという名前ではない他の多くのネイバーが表示されます。

次の論文を見て、分布セマンティクスで人々が何をしているのかを理解してください。

これらの論文で使用されている用語にあなたのアイデアを入れるために、ステップ2は、サイズ1のウィンドウから単語のコンテキストベクトルを構築しています。ステップ3は、分布セマンティクス(特にいわゆるJaccard)におけるいくつかのよく知られた類似性の尺度に似ています。係数)。

larsmansご指摘のとおり、適切な評価を行っていないため、これは非常にうまく機能しているようです。手で注釈を付けたコーパスに対してこれを実行すると、名前エンティティの境界を識別するのが非常に悪く、それらが人であるか場所であるか組織であるかを推測しようとさえしません...それにもかかわらず、それは素晴らしい最初ですNLPを試して、それを維持してください!

于 2012-05-14T17:57:42.377 に答える