【问题标题】:How to speed up the model creation process of OpenNLP如何加快 OpenNLP 的模型创建过程
【发布时间】:2015-01-15 05:32:34
【问题描述】:

我正在使用 OpenNLP 令牌名称查找器来解析非结构化数据,我已经创建了一个 4MM 记录的语料库(训练集),但是当我在 Eclipse 中使用 OpenNLP API 从这个语料库中创建一个模型时,过程大约需要 3 hrs 非常耗时。模型建立在默认参数上,即迭代 100 和截止 5。

所以我的问题是,我怎样才能加快这个过程,怎样才能减少构建模型的过程所花费的时间。

语料库的大小可能是造成这种情况的原因,但只是想知道是否有人遇到过这种问题,如果遇到过,那么如何解决这个问题。

请提供一些线索。

提前致谢!

【问题讨论】:

  • 试试jvm内存参数:-Xms=512m -Xmx=2048m
  • 感谢您提出这个建议,但您知道我已经将 -Xmx 增加到 10GB,因为该过程占用了大约 10GB 空间。增加内存后,仍然需要3个小时。这就是为什么我有点担心。
  • 没有其他方法可以加快这个过程。将其导出为 jar 文件并运行它可能会给您额外的 ~500mb(eclipse 需要)。那是400万条记录吗?我猜 GATE (gate.ac.uk) 将花费比这更多的时间。
  • 好的,我将尝试将项目导出为 jar 文件并在命令提示符下运行它。是的,语料库包含 400 万条记录。你知道如何在 Spark 上运行它以加快进程。
  • 采用可扩展的分布式解决方案(如 Apache Spark)可能是正确的想法。我不确定您正在构建哪种模型,但 Spark 的 MLlib 支持多种类型。 spark.apache.org/docs/1.1.0/mllib-guide.html

标签: java machine-learning apache-spark opennlp maxent


【解决方案1】:

我认为您应该在升级硬件之前进行算法相关的更改。
减少句子大小
确保训练样本中没有不必要的长句子。这样的句子不会提高性能,但会对计算产生巨大影响。 (不确定顺序)我通常在 200 字/句子处截断。还要仔细查看特征,这些是默认的特征生成器
two kinds of WindowFeatureGenerator with a default window size of only two OutcomePriorFeatureGenerator PreviousMapFeatureGenerator BigramNameFeatureGenerator SentenceFeatureGenerator
这些特征生成器在给定句子中为单词生成以下特征:Robert

Sentence: Robert, creeley authored many books such as Life and Death, Echoes and Windows.
Features:
w=robert
n1w=creeley
n2w=authored
wc=ic
w&c=robert,ic
n1wc=lc
n1w&c=creeley,lc
n2wc=lc
n2w&c=authored,lc
def
pd=null
w,nw=Robert,creeley
wc,nc=ic,lc
S=begin


ic 是初始资本,lc 是小写

在这些特征中,S=begin 是唯一依赖于句子的特征,这标志着 Robert 出现在句子的开头。
我的意思是解释一个完整的句子在训练中的作用。您实际上可以删除 SentenceFeatureGenerator 并进一步减小句子大小以仅在所需实体的窗口中容纳几个单词。这同样适用。
我相信这会对复杂性产生巨大影响,而对性能影响很小。

您是否考虑过抽样?
正如我上面所描述的,这些特征是上下文的非常稀疏的表示。正如特征生成器所见,您可能有很多重复的句子。尝试检测这些并以一种表示具有不同模式的句子的方式进行采样,即。应该不可能只编写几个匹配它们的正则表达式。根据我的经验,具有不同模式的训练样本比仅代表少数模式的训练样本表现更好,即使前者的句子数量要少得多。以这种方式采样根本不会影响模型性能。

谢谢。

【讨论】:

  • 感谢 Vihari 的回答。我明白你的意思,但我怎样才能放弃句子特征生成器?如何查看这些功能,OpenNLP 是否为此提供了任何命令行实用程序?您能否分享一下您是如何为上述句子生成特征的,一旦我得到特征生成器,我将尝试识别重复项。在我以编程方式创建训练集中时,可能会出现重复。
  • 句子特征生成器只是一个花哨的句子标记器,它不会以任何方式影响性能。 OpenNLP 不提供命令行实用程序来查看功能;我在他们的代码中添加了一些打印语句(不记得在哪里)。正如我在回答中所说,这些特征仅依赖于实体的一个小窗口(OpenNLP 将它们称为事件),识别此类实体,仅保留它们周围的窗口并将此类子句作为句子发出。或者尝试第二种方法(采样),它更容易(因为你只需要适应几束正则表达式)而且我更有信心。
  • 嗨,David,是否有任何选项可以将 open nlp 与 spark 集成以并行化解析过程?
【解决方案2】:

通常处理此类问题的第一种方法是将训练数据分成几个块,并让每个块创建自己的模型。然后合并模型。我不确定这在这种情况下是否有效(我不是 OpenNLP 专家),下面还有另一种解决方案。此外,由于 OpenNLP API 似乎只提供单线程 train() 方法,我会提出请求多线程选项的问题。

对于缓慢的单线程操作,两个主要的减慢因素是 IO 和 CPU,两者都可以单独处理:

  • IO - 您使用哪个硬盘驱动器?常规(磁性)还是 SSD?迁移到 SSD 应该会有所帮助。
  • CPU - 您使用的是哪个 CPU?迁移到更快的 CPU 会有所帮助。不要关注核心数量,因为这里你想要的是原始速度。

您可能需要考虑从 Amazon Web 服务或 Google Compute Engine 获取高 CPU 服务器并在那里运行训练的选项 - 您可以在之后下载模型。两者都为您提供使用 Xeon(Sandy Bridge 或 Ivy Bridge)CPU 和本地 SSD 存储的高 CPU 服务器。

【讨论】:

  • 是否可以创建小模型,然后将它们合并为一个?我很想知道哪个库支持这个?
  • 嗨@Nikhil,正如我所写,我不是 NLP 专家,所以这只是一个想法。正如您从我的回答中看到的那样,我认为这是不可能的,所以我列出了其他选项。
  • 嗨,大卫,我增加了我的 RAM,因为该模型的创建速度比以前快得多(3MM 记录需要 50 分钟)。此外,train() 方法还提供多线程,所以我添加了一些线程,比如 10,这也提高了我的模型性能。谢谢你的好建议。
  • 我与 NLP 和 OpenNLP 合作的时间已经足够长,我可以告诉您这一点,将较小的模型组合起来构建更大的模型是不可能的。一些较小的模型可能包含其他模型甚至没有看到的功能。训练的最后一步是为所有特征分配权重,即在发生特定特征的情况下事件发生的可能性。唯一的选择是从许多较小的模型中选择性能最好的模型,合并不是一种选择。
猜你喜欢
  • 2013-07-31
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
相关资源
最近更新 更多