【问题标题】:How to improve the performance when working with wikipedia data and huge no. of webpages?如何在使用维基百科数据和巨大的数字时提高性能。的网页?
【发布时间】:2023-03-31 13:25:02
【问题描述】:

我应该使用维基百科的文章链接数据转储从组织的网站中提取具有代表性的术语。 为了实现这一点,我 -

  1. 抓取并下载了组织的网页。 (~110,000)
  2. 创建了维基百科 ID 和术语/标题的字典。 (约 4000 万条记录)

现在,我应该使用字典来处理每个网页,以识别术语并跟踪它们的术语 ID 和频率。

为了让字典适合内存,我将字典拆分为更小的文件。根据我对小数据集的实验,上述处理时间约为 75 天。

这仅适用于 1 个组织。我必须为其中的 40 多个人做同样的事情。

实施 -

  • HashMap 用于在内存中存储字典。
  • 使用 Boyer-Moore 搜索实现循环遍历每个地图条目以搜索网页中的术语。
  • 对每个网页重复上述操作,并将结果存储在 HashMap 中。

我已经尝试优化代码并调整 JVM 以获得更好的性能。

有人可以建议一种更有效的方法来实施上述方法,将处理时间缩短到几天。

是否可以考虑使用 Hadoop?

【问题讨论】:

  • 你绝对应该使用 Lucene 来完成这项任务。
  • 感谢@MarkoTopolnik。我将检查 Lucene。

标签: java hadoop ontology text-mining wikimedia-dumps


【解决方案1】:

根据您的问题:

Number of Documents = 110000

Dictionary => List of [TermID, Title Terms] = 40million entries

Size of documents = 11000 * 1KB per document on an average =  26.9GB
(1KB per document on an average)

Size of dictionary = 40million * 256bytes = 9.5GB of raw data
(256bytes per entry on an average)

您是如何得出 75 天的估算值的?

有多个性能目标:

  • 您如何存储文档?
  • 您如何存储/检索字典? (假设不是全部都在内存中,除非你负担得起)
  • 你在多少台机器上运行它?
  • 您是否正在并行执行字典查找? (当然,一旦你已经处理了整个维基百科,假设字典是不可变的)

以下是我认为您正在做的事情的大纲:

dictionary = read wikipedia dictionary
document = a sequence of documents
documents.map { doc =>
  var docTermFreq = Map[String, Int]()
  for(term <- doc.terms.map if(dictionary.contains(term)) ) {
     docTermFreq = docTermFreq + (term -> docTermFreq.getOrElse(term, 0) + 1)
  }
  // store docTermFreq map
}

这实质上是将每个文档分解为标记,然后在维基百科字典中查找其标记的存在。

这正是 Lucene Analyzer 所做的。

Lucene Tokenizer 会将文档转换为令牌。这发生在术语被索引到 lucene 之前。所以你所要做的就是实现一个分析器,它可以在维基百科词典中查找一个标记是否在词典中。

我会这样做:

  • 获取每个文档并准备令牌流(使用上述分析器)
  • 为文档术语编制索引。
  • 此时,Lucene 索引中只有维基百科术语。

执行此操作时,您将获得来自 Lucene 索引的现成统计信息,例如:

您可以做很多事情来提高性能。例如:

  • 并行化文档流处理。
  • 您可以将字典存储在键值数据库中,例如BerkeylyDB 或Kyoto Cabinet,甚至可以存储在内存键值中,例如RedisMemcache

希望对你有帮助。

【讨论】:

  • 感谢您的回答。我使用monq library 来做同样的事情,但它看起来很复杂。所以,我打算使用Lucene。我已经在 Google 上搜索过构建自定义分析器,但如果您能指导我找到一个好的资源,那就太好了。另外,我想指出维基百科词典有多字词(短语)。非常感谢!
【解决方案2】:

仅使用 MR 的方法之一是:

假设您已经有 N 个适合内存的较小尺寸的词典,您可以: 启动 N 个“仅映射”作业,这些作业将扫描您的所有数据(每个作业只有一个字典),并将 {pageId、termId、occurrence 等}之类的内容输出到文件夹 /your_tmp_folder/N/ 结果,您将拥有 N*M 个文件,其中 M 是每个阶段的映射器数量(应该相同)。

然后第二个作业将简单地分析您的 {pageId、termId、occurrence, etc} 对象并构建每个页面 id 的统计信息。

在您的情况下,仅地图作业应该非常快。如果没有 - 请粘贴您的代码。

【讨论】:

    猜你喜欢
    • 2016-08-04
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多