在Python中加速斯坦福依存解析

3

有没有更快的方法来实现 CoreNLPParser,或者我应该通过另一个库与API进行交互?还是我应该重新看一下Java书?

我有一个包含6500个句子的语料库,我正在使用nltk.parse.corenlp中的CoreNLPParser方法运行它。为了测试我之前编写的tree_height函数,我已经将与主项目有关的所有其他内容隔离开来。然而,速度仍然很慢——事实上,这个过程需要超过15分钟才能完成。

这是我的tree_height函数:

from nltk.parse.corenlp import CoreNLPParser
Parser = CoreNLPParser(url='http://localhost:9000')
def tree_height(tokenized_sent):
    ddep = Parser.raw_parse(tokenized_sent)
    for i in ddep:
        sent_height = i.height()
    return sent_height

我正在解析西班牙语句子,并使用以下命令启动了CoreNLP服务器:

java -mx10g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -serverProperties StanfordCoreNLP-spanish.properties -port 9000 -timeout 15000

我也试过将mx3g部分改为mx5g,但似乎没有太大的区别。

我看到了GitHub上的这个讨论,并且正在运行最新版本的StanfordCoreNLP。

--- 更新 ---

我担心我的脚本执行缓慢是因为效率低下或代码编写不好,所以我尝试找出代码中的低效之处:

  1. 在不调用任何NLP函数的情况下,遍历所有数据(从pandas dataframe中)需要大约20秒。
  2. 遍历所有数据并仅对句子进行分词需要约30秒。
  3. 在我的最新尝试中,我将所有分词后的句子添加到一个变量中,并逐个调用tree_height函数,发现速度没有差别(与我开始隔离代码之前一样长)。

根据我的个人经验,使用斯坦福CoreNLPParser的速度很慢,除非采用另一种更好的解决方案。一个快速的技巧是将文本分批处理。然而,我想知道在你的情况下这样做会有多快。 - sophros
你能分享一下你想要注释的文件吗?我记得当我尝试解析另一个数据时速度还是很快的。 - alvas
1
我正在尝试撰写有关通过Python访问服务器的一些信息。当我通过服务器解析西班牙语句子时,您的时间不应该那么慢,仅花费约2分钟即可完成6500个句子。我很快会写更多内容。 - StanfordNLPHelp
@alvas,您是我的NLP英雄。我不允许分享文件,但自从我发布问题以来,我已经尝试了一些东西,并更新了问题。 - matt_07734
@StanfordNLPHelp 我认为看一下您是如何设置的会很有用——我想可能是我在StanfordNLP设置方面遗漏或忘记了某些东西。 - matt_07734
我会尝试在今天发布答案... - StanfordNLPHelp
2个回答

2

好的,这是我们正在开发的Python接口的描述。要获得最新版本,您需要从GitHub上下载并按照安装说明进行操作(非常容易跟进!)

前往GitHub并克隆Python接口存储库:

https://github.com/stanfordnlp/python-stanford-corenlp

cd到目录中并键入 python setup.py install

(不久我们将使用condapip等设置此功能,但目前仍在开发中...您现在可以在pip上获取旧版本)

在另一个终端窗口中启动Java服务器:

java -Xmx4g edu.stanford.nlp.pipeline.StanfordCoreNLPServer -serverProperties StanfordCoreNLP-spanish.properties -port 9000 -timeout 15000

注意:确保在您的CLASSPATH中拥有所有必需的jar文件,或者使用带有所有适当jar文件的目录的-cp“*”选项运行。

运行此Python代码:

import corenlp
client = corenlp.CoreNLPClient(start_server=False, annotators=["tokenize", "ssplit", "pos", "depparse"])
# there are other options for "output_format" such as "json"
# "conllu", "xml" and "serialized"
ann = client.annotate(u"...", output_format="text")

ann 将包含最终的注释信息(包括依赖解析)...这应该比您报告的速度快得多...请尝试并让我知道。


这快多了!!现在我只需要弄清楚如何找到给定句子的树高度——NLTK返回一个Tree类——其中有一个方便的height()方法。你能否立即想到一种超级快速的方法来做到这一点? - matt_07734
顺便提一下--你给我启动服务器的命令没用,所以我使用了我在问题中列出的那个命令,一切运行得很好。 - matt_07734
抱歉,我想在我的设置中我将西班牙的JAR包放在了我的CLASSPATH中。它没有工作是因为它找不到那个文件吗? - StanfordNLPHelp

0

由于解析自然语言可能会很复杂,你所遇到的经历似乎并不例外。当你尝试使用Stanford Parser Demo Interface中的spanishPCFG.ser.gz模型解析一个简单的句子时http://nlp.stanford.edu:8080/parser/index.jsp,可能需要几毫秒,但是长而复杂的句子可能需要几秒钟。你可以试一试,他们也提供统计数据。

如果你想节省时间,可以尝试并行化解析任务;这是我能建议的全部。

顺祝

你提供的链接是关于标记器的讨论,Steven Bird说已经解决了,顺便说一下。


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