【问题标题】:How to extract relationship from text in NLTK如何从 NLTK 中的文本中提取关系
【发布时间】:2012-09-04 13:31:53
【问题描述】:

您好,我正在尝试根据此处的倒数第二个示例从文本字符串中提取关系:https://web.archive.org/web/20120907184244/http://nltk.googlecode.com/svn/trunk/doc/howto/relextract.html

从诸如“出版商周刊的迈克尔·詹姆斯编辑”之类的字符串中,我想要的结果是输出如下:

[PER: 'Michael James']','[ORG: 'Publishers Weekly'] 的编辑

执行此操作的最佳方法是什么? extract_rels 期望什么格式以及如何格式化我的输入以满足该要求?


尝试自己做,但没有成功。 这是我从书中改编的代码。我没有打印任何结果。我做错了什么?

class doc():
 pass

doc.headline = ['this is expected by nltk.sem.extract_rels but not used in this script']

def findrelations(text):
roles = """
(.*(                   
analyst|
editor|
librarian).*)|
researcher|
spokes(wo)?man|
writer|
,\sof\sthe?\s*  # "X, of (the) Y"
"""
ROLES = re.compile(roles, re.VERBOSE)
tokenizedsentences = nltk.sent_tokenize(text)
for sentence in tokenizedsentences:
    taggedwords  = nltk.pos_tag(nltk.word_tokenize(sentence))
    doc.text = nltk.batch_ne_chunk(taggedwords)
    print doc.text
    for rel in relextract.extract_rels('PER', 'ORG', doc, corpus='ieer', pattern=ROLES):
        print relextract.show_raw_rtuple(rel) # doctest: +ELLIPSIS

text ="出版商周刊的迈克尔·詹姆斯编辑"

发现关系(文本)

【问题讨论】:

  • 您是否验证了中间步骤是否正常工作?您应该首先尝试这样做,并确定代码的哪个步骤(标记化、pos 标记、ner、关系提取)没有按照您的预期进行。
  • 当我将分块更改为使用 ne_chunk(而不是 batch_ne_chunk)时得到的输出是 (S (PERSON Michael/NNP) (PERSON James/NNP) ,/, editor/NN of/IN (组织出版商/NNP 周刊/NNP))
  • 那么是batch_ne_chunk不工作的问题吗?
  • 两者都不返回任何结果。但是当使用 ne_chunk 时 print doc.text 行会在我之前的评论中产生输出,而当使用 batch_ne_chunk 时 print doc.text 会产生错误: File "/usr/lib/python2.6/site-packages/nltk/ chunk/named_entity.py",第 49 行,in _feature_detector pos = simple_pos(tokens[index][1])IndexError: string index out of range
  • ok.. 即使我上次尝试使用 nltk 时也遇到过这样的问题.. 作为一个积极开发的库 nltk 的 api 可能经历了一些更改,导致此代码不再工作.设置 nltk 有时还需要您在交互式 shell (ipython) 中使用 nltk.download 方法下载一堆模型文件。我对您的建议是在 ipython 终端中使用所有这些 nltk 函数,看看它们是什么输入/输出规格是。

标签: nlp nltk


【解决方案1】:

这里有一个基于你的代码(只需少量调整),效果很好;)

import nltk
import re 
from nltk.chunk import ne_chunk_sents
from nltk.sem import relextract


def findrelations(text):
    roles = """
    (.*(                   
    analyst|
    editor|
    librarian).*)|
    researcher|
    spokes(wo)?man|
    writer|
    ,\sof\sthe?\s*  # "X, of (the) Y"
    """
    ROLES = re.compile(roles, re.VERBOSE)

    sentences = nltk.sent_tokenize(text)
    tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
    tagged_sentences = [nltk.pos_tag(sentence) for sentence in tokenized_sentences]
    chunked_sentences = nltk.ne_chunk_sents(tagged_sentences)


    for doc in chunked_sentences:
        print doc
        for rel in relextract.extract_rels('PER', 'ORG', doc, corpus='ace', pattern=ROLES):
            #it is a tree, so you need to work on it to output what you want
            print relextract.show_raw_rtuple(rel) 

findrelations('Michael James editor of Publishers Weekly')

(S (人迈克尔/ NNP) (人詹姆斯/NNP) 编辑/NN 的/IN (组织出版商/NNS 周刊/NNP))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 2018-04-23
    • 2016-10-22
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多