Python Naiver算法

Python Naiver算法,python,nlp,Python,Nlp,我从来没有真正处理过NLP,但对NER有一个想法,它本不应该起作用,而且在一个案例中表现得异常出色。我不明白它为什么会起作用,为什么不起作用,或者它是否可以扩展 其想法是通过以下方式提取故事中主要人物的姓名: 为每个单词建立字典 为每个单词填写一个列表,列出文本中出现在其旁边的单词 为每个单词查找一个列表相关性最大的单词(意味着这些单词在文本中的使用方式类似) 考虑到故事中一个角色的名字,使用的词语也应该如此(伪造,这是不应该的,但因为我直到今天早上才处理NLP,所以我开始了天真的一天) 我在上

我从来没有真正处理过NLP,但对NER有一个想法,它本不应该起作用,而且在一个案例中表现得异常出色。我不明白它为什么会起作用,为什么不起作用,或者它是否可以扩展

其想法是通过以下方式提取故事中主要人物的姓名:

  • 为每个单词建立字典
  • 为每个单词填写一个列表,列出文本中出现在其旁边的单词
  • 为每个单词查找一个列表相关性最大的单词(意味着这些单词在文本中的使用方式类似)
  • 考虑到故事中一个角色的名字,使用的词语也应该如此(伪造,这是不应该的,但因为我直到今天早上才处理NLP,所以我开始了天真的一天)
  • 我在上运行了过于简单的代码(附在下面),对于“Alice”返回:

    21[‘老鼠’、‘纬度’、‘威廉’、‘兔子’、‘渡渡鸟’、‘鹰头狮’、‘螃蟹’、‘王后’、‘公爵夫人’、‘仆人’、‘黑豹’、‘毛毛虫’、‘红心’、‘国王’、‘比尔’、‘鸽子’、‘猫’、‘帽匠’、‘兔子’、‘海龟’、‘睡鼠’]

    虽然它会过滤大写单词(并将“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()
    

    从您的计划和之前的NER经验来看,我认为这“有效”,因为您没有进行适当的评估。你已经找到了“野兔”在你应该找到“三月野兔”的地方

    NER(至少英语)的困难在于找不到名字;它正在检测它们的全部范围(“三月兔”示例);即使在句子开头,所有单词都大写,也能检测到它们;将他们分类为个人/组织/地点/等

    此外,《爱丽丝梦游仙境》是一本儿童小说,是一本相当容易处理的文本。像“微软首席执行官史蒂夫·鲍尔默”这样的通讯社短语带来了一个更难的问题;在这里,你会想要检测

    [ORG Microsoft] CEO [PER Steve Ballmer]
    

    您所做的是构建一个——查找在分布上与查询相似的单词(例如Alice),即出现在相似上下文中的单词。这不会自动使它们成为同义词,但意味着它们在某种程度上类似于查询。您的查询是命名实体这一事实本身并不能保证您检索的类似单词将是命名实体。然而,由于
    Alice
    Hare
    Queen
    的出现往往是相似的,因为它们有一些共同的特征(例如,它们都会说话、走路、哭泣等——爱丽丝梦游仙境的细节我不知道),它们更有可能被检索到。事实证明,当确定某个单词是否为命名实体时,单词是否大写是一条非常有用的信息。如果您不过滤掉非大写单词,您将看到许多其他未命名实体的邻居

    请阅读以下文章,了解人们如何使用分布语义:

    为了将您的想法用在这些论文中使用的术语中,第2步是从大小为1的窗口中为单词with构建上下文向量。步骤3类似于分布语义中的几个众所周知的相似性度量(最显著的是所谓的Jaccard系数)

    正如
    larsmans
    所指出的,这似乎效果很好,因为您没有进行正确的评估。如果你在一个手工标注的语料库上运行它,你会发现它在识别名称实体的边界方面非常糟糕,它甚至不会尝试猜测它们是人、地方还是组织。。。尽管如此,这是NLP的第一次伟大尝试,请继续努力