我想知道是否有人知道任何好的库或从原始文本解析名称的方法。
例如,假设我有这些作为示例:(注意有时它们是大写的元组,有时不是)
James Vaynerchuck and the rest of the group will be meeting at 1PM.
Sally Johnson, Jim White and brad burton.
Mark angleman Happiness, Productivity & blocks. Mark & Evan at 4pm.
我的第一个想法是加载某种词性标记器(如 Python NLTK),标记所有单词。然后仅删除名词,然后将名词与已知单词的数据库(即文字字典)进行比较,如果它们不在字典中,则假设它们是名称。
其他想法是深入研究机器学习,但这可能超出了我在这里需要的范围。
您可以向我指出的任何想法、建议或库都会非常有帮助。
谢谢!
最佳答案
我不知道为什么你认为你需要 NLTK 只是为了排除字典单词;您只需要一本简单的字典(您可能已将其安装在 /usr/share/dict/words
等位置,或者您可以从互联网上下载一本):
with open('/usr/share/dict/words') as f:
dictwords = {word.strip() for word in f}
with open(mypath) as f:
names = [word for line in f for word in line.rstrip().split()
if word.lower() not in dictwords]
您的单词
列表可能包含名称,但如果是这样,它将包含大写的名称,因此:
dictwords = {word.strip() for word in f if word.islower()}
或者,如果您想将专有名称列入白名单而不是将字典单词列入黑名单:
with open('/usr/share/dict/propernames') as f:
namewords = {word.strip() for word in f}
with open(mypath) as f:
names = [word for line in f for word in line.rstrip().split()
if word.title() in namewords]
但这确实行不通。看看你的例子中的“Jim White”。他的姓氏显然会出现在任何字典中,而他的名字也会出现在许多字典中(作为“jimmy”的缩写版本,作为阿拉伯字母“jīm”的常见罗马化形式等)。 “马克”也是一个常见的字典词。反过来说,“意志”是一个很常见的名字,尽管你想把它当成一个词,而“幸福”是一个不常见的名字,但至少有几个人拥有它。
因此,为了使这项工作哪怕只有一点点,您可能需要结合多种启发式方法。首先,每个单词都有可能在某些相关语料库中用作名称,而不是始终是名称或从不是名称 - White 可能是名称的概率为 13.7%,Mark 为 41.3%,Jim 为 99.1% ,幸福0.1%等等。接下来,如果它不是句子中的第一个单词,而是大写,那么它更有可能是一个名字(还有多少?我不知道,你需要测试和调整对于您的特定输入),如果它是小写的,那么它不太可能是一个名称。您可以引入更多上下文 - 例如,您有很多全名,因此,如果某个内容可能是名字,并且它出现在常见姓氏旁边,则它更有可能是名字。您甚至可以尝试解析语法(如果您放弃某些句子,那也没关系;它们只是不会从语法规则中获得任何输入),因此,如果两个相邻单词只能作为句子的一部分,则第一个单词是第二个单词一个动词,它们可能不是名字和姓氏,即使同一个第二个词在其他上下文中可能是名词(和名字)。等等。
关于python - 如何从原始文本中解析名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25102212/