我正在尝试使用nltk
和Stanford NLP
工具从一段文字中提取关键字。运行我的代码后,我可以得到一个像这样的列表
companyA
companyB
companyC
Trend Analysis For companyA
这一切都很好,但请注意最后一项。这实际上是文本中出现的标题。由于标题的所有单词都是大写的,我的程序认为这些都是专有名词,因此将它们组合在一起,好像它们是一个大公司名称。
好消息是,只要在文本的某处提到了公司,我的程序就会提取它,因此我也会得到companyA
这样的单独项目。这些来自谈论该公司的实际文本。
这是我想要做的。
在我上面的列表中,有没有办法查看项目并确定以前的项目是否是当前项目的子字符串?例如,在这种情况下,当我遇到
Trend Analysis For companyA
我可以检查一下我之前是否看过这部分内容。所以我可以确定我已经companyA
,因此我会忽略Trend Analysis For companyA
。 我相信文本会提到任何公司足够的时间让斯坦福大学拿起它。因此,我不必依赖标题来获得我需要的东西。
这有意义吗?这是正确的方法吗?我担心这不会很有效,但我无法想到其他任何事情。
修改
以下是我使用的代码
sentences = nltk.sent_tokenize(document)
sentences = [nltk.word_tokenize(sent) for sent in sentences]
sentences = [nltk.pos_tag(sent) for sent in sentences]
之后我只在每个句子上使用StanfordNERTagger
result = []
stn = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz')
for s in sentences:
taggedwords = stn.tag(s)
for tag, chunk in groupby(taggedWords, lambda x:x[1]):
if tag == "ORGANIZATION":
result.append((tag, " ".join(w for w, t in chunk)))
return result
通过这种方式,我可以获得所有ORGANIZATION
s。
对于@ Alvas关于Truecasing的观点,难道你不觉得这里有点矫枉过正吗?当我研究算法时,在我看来,他们正试图为每个单词提出最可能的拼写。可能性将基于语料库。我不认为我需要建立一个语料库,因为我可以使用像wordnet
之类的词典或类似pyenchant
的词来找出合适的拼写。此外,在这里我已经拥有了我需要的所有信息,即我正在接收所有提到的公司。
还有另一个问题。考虑公司名称
American Eagle Outfitters
请注意,American
和american
都是正确的拼写。 Eagle
和eagle
的Simlarl。我担心即使我将Truecasing应用到我的算法中,它也会最终降低不应该小写的术语。
同样,我现在的问题是我提取了所有公司名称,但我也提取了标题。蛮力方式是对结果列表执行子串检查。我只是想知道是否有更有效的方法来做到这一点。此外,我不认为我做的任何调整将改善标记。我不认为我能胜过StanfordNERTagger
答案 0 :(得分:2)
我确实遇到过类似的问题,但整个文本都没有大写(ASR输出)。在那种情况下,我确实在非资本化注释数据上重新训练NER模型以获得更好的性能。
根据偏好(和复杂性)顺序,我会考虑以下几个选项:
我个人会考虑第一个选项,因为您可以轻松地人工创建一个全资本化的语料库(来自正确的大写文本)并训练序列贴标机模型(例如CRF)模型以检测应该删除大写的位置。
无论你使用什么样的方法,你的表演都不会像正确的大写字母一样好。您的输入可被视为部分噪音,因为POS标记和NER都缺少线索。