快速将NLTK解析为句法树

5

我正在尝试将几百个句子解析为它们的语法树,并且需要快速完成,问题是如果我使用NLTK,那么我需要定义语法规则,但我不能知道这些规则,我只知道是英语。 我尝试使用此统计解析器,它对我的目的很好,但速度可以更快,有没有办法在不使用语法规则的情况下使用nltk解析?在这个片段中,我使用处理池来“并行”处理,但速度远远达不到预期。

import pickle
import re
from stat_parser.parser import Parser
from multiprocessing import Pool
import HTMLParser
def multy(a):
    global parser
    lst=re.findall('(\S.+?[.!?])(?=\s+|$)',a[1])
    if len(lst)==0:
        lst.append(a[1])
    try:
        ssd=parser.norm_parse(lst[0])
    except:
        ssd=['NNP','nothing']
    with open('/var/www/html/internal','a') as f:
        f.write("[[ss")
        pickle.dump([a[0],ssd], f)
        f.write("ss]]")
if __name__ == '__main__':
    parser=Parser()
    with open('/var/www/html/interface') as f:
        data=f.read()
    data=data.split("\n")
    p = Pool(len(data))
    Totalis_dict=dict()
    listed=list()
    h = HTMLParser.HTMLParser()
    with open('/var/www/html/internal','w') as f:
        f.write("")
    for ind,each in enumerate(data):
        listed.append([str(ind),h.unescape(re.sub('[^\x00-\x7F]+','',each))])
    p.map(multy,listed)

可能是全局声明导致了延迟?也许我应该使用一个新的解析器对象? - Evan
1个回答

11

解析是一个相当计算密集的操作。您可能可以通过使用更精细的解析器(例如bllip)获得更好的性能。它是用 C++ 编写的,并从一个团队长时间的工作中受益。有一个与之交互的 Python 模块。

以下是一个比较你正在使用的解析器和 bllip 的示例:

import timeit

# setup stat_parser
from stat_parser import Parser
parser = Parser()

# setup bllip
from bllipparser import RerankingParser
from bllipparser.ModelFetcher import download_and_install_model
# download model (only needs to be done once)
model_dir = download_and_install_model('WSJ', '/tmp/models')
# Loading the model is slow, but only needs to be done once
rrp = RerankingParser.from_unified_model_dir(model_dir)

sentence = "In linguistics, grammar is the set of structural rules governing the composition of clauses, phrases, and words in any given natural language."

if __name__=='__main__':
    from timeit import Timer
    t_bllip = Timer(lambda: rrp.parse(sentence))
    t_stat = Timer(lambda: parser.parse(sentence))
    print "bllip", t_bllip.timeit(number=5)
    print "stat", t_stat.timeit(number=5)

在我的电脑上,它运行速度大约快了10倍:

(vs)[jonathan@ ~]$ python /tmp/test.py 
bllip 2.57274985313
stat 22.748554945

此外,有一个待处理的拉请求要将bllip解析器集成到NLTK中:https://github.com/nltk/nltk/pull/605

此外,在你的问题中你说:“我不能知道它只会是英语”,如果你是指它需要解析其他语言,那会变得更加复杂。这些统计解析器是基于一些输入进行训练的,通常是来自宾州树库中的WSJ解析内容。某些解析器也会提供针对其他语言的训练模型,但你需要首先确定语言,并将适当的模型加载到解析器中。


谢谢,看起来很不错!我并不是说它会用不同的语言,我是说它可以包含英语中的每个单词,甚至一些奇怪的单词 :) 不过这个应该也没问题,谢谢。 - Evan
1
从NLTK版本3.0.2开始,支持从BLLIP解析器获取树。请参见https://github.com/nltk/nltk/blob/develop/nltk/parse/bllip.py以获取示例代码。 - dmcc
非常感谢,它帮了我很多:) - Harsh Trivedi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接