【问题标题】:NLP - Speed of Named Entity Recognition (StanfordNER)NLP - 命名实体识别速度 (StanfordNER)
【发布时间】:2018-02-15 22:00:52
【问题描述】:

我正在 Python 3 中进行自然语言处理 (NLP),更具体地说,是在哈利波特系列书籍中进行命名实体识别 (NER)。我正在使用 StanfordNER,效果很好,但需要花费大量时间......

我在网上做了一些研究,为什么它会这么慢,但我似乎找不到任何真正适合我的代码的东西,老实说,我认为问题更多在于我编写代码的(坏)方式.

这就是我现在写的:

import string
from nltk.tokenize import sent_tokenize, word_tokenize
import nltk.tag.stanford as st

tagger = st.StanfordNERTagger('_path_/stanford-ner-2017-06-09/classifiers/english.all.3class.distsim.crf.ser.gz', '_path_/stanford-ner-2017-06-09/stanford-ner.jar')

#this is just to read the file

hp = open("books/hp1.txt", 'r', encoding='utf8')
lhp = hp.readlines()

#a small function I wrote to divide the book in sentences

def get_sentences(lbook):
    sentences = []
    for k in lbook:
        j = sent_tokenize(k)
        for i in j:
            if bool(i):
                sentences.append(i)
    return sentences

#a function to divide a sentence into words

def get_words(sentence):
    words = word_tokenize(sentence)
    return words

sentences = get_sentences(lhp)

#and now the code I wrote to get all the words labeled as PERSON by the StanfordNER tagger

characters = []
    for i in sentence:
    characters = [tag[0] for tag in tagger.tag(get_words(sentences[i])) if tag[1]=="PERSON"]
    print(characters)

正如我所解释的,现在的问题是代码需要大量时间......所以我想知道,这是正常的还是 我可以通过以更好的方式重写代码来节省时间吗? 如果是这样,你能帮帮我吗?

【问题讨论】:

  • 需要多少时间?

标签: python python-3.x nlp stanford-nlp named-entity-recognition


【解决方案1】:

瓶颈是tagger.tag 方法,它的开销很大。因此,为每个句子调用它会导致程序非常慢。除非另外需要将书拆分成句子,否则我会立即处理整个文本:

with open('books/hp1.txt', 'r') as content_file:
    all_text = content_file.read()
    tags = tagger.tag(word_tokenize(all_text))
    characters = [tag[0] for tag in tags if tag[1] == "PERSON"]
    print(characters)

现在,如果您想知道每个字符在哪个句子中被提及,那么您可以首先像上面的代码一样在characters 中获取字符的名称,然后循环检查句子是否来自characters 的元素存在于那里。

如果文件大小是一个问题(尽管将大多数书籍的 .txt 文件加载到内存中应该不成问题),那么您可以一次阅读大量 n 的句子,而不是阅读整本书.从您的代码中,修改您的 for 循环,如下所示:

n = 1000
for i in range(0, len(sentences), n):
    scs = '. '.join(sentences[i:i + n])
    characters = [tag[0] for tag in tagger.tag(get_words(scs)) if tag[1]=="PERSON"]

一般的想法是尽量减少对tagger.tag 的调用,因为它的开销很大。

【讨论】:

    猜你喜欢
    • 2018-03-08
    • 2020-07-02
    • 2019-11-12
    • 2018-03-26
    • 2019-07-19
    • 2020-02-01
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    相关资源
    最近更新 更多