我应该使用Wikipedia的文章链接数据转储从组织的网站中提取代表性术语。为了实现这一目标,我 -
- 爬行&下载组织的网页。(〜110,000)
- 创建了Wikipedia ID和条款/标题的字典。(约4000万记录)
现在,我应该使用字典处理每个网页以识别术语并跟踪其术语IDS&频率。
为了使字典适合内存,我将字典分配为较小的文件。根据我对小型数据集的实验,上述处理时间大约为75天。
这仅适用于1个组织。我必须为其中40多个做同样的事情。
实施 -
- 将字典存储在内存中的hashmap。
- 使用Boyer-Moore搜索实现。
- 为每个网页重复上述内容,并将存储在hashmap中。
我尝试优化代码并调整JVM以提高性能。
有人可以为实施以上的更有效的方法提供建议,将处理时间减少到几天。
Hadoop是一个选择?
基于您的问题:
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天的估算值?
有大量的性能目标:
- 您如何存储文档?
- 您如何存储/检索字典?(除非您负担得起,否则并非所有这些都不是所有的)
- 您正在运行几台机器?
- 您是否在并行执行字典查找?(在您已经处理整个Wikipedia后,假设字典是不变的)
这是我相信您在做的事情的概述:
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
}
这实际上是在将每个文档分解为令牌,然后在Wikipedia词典中进行查找,以使其具有代币的存在。
这正是Lucene Analyzer所做的。
Lucene令牌将文档转换为令牌。在将术语索引到Lucene之前发生。因此,您要做的就是实施一个可以查找Wikipedia词典的分析器,以使令牌是否在字典中。
我会这样做:
- 获取所有文档并准备一个令牌流(使用上述分析仪)
- 索引文档条款。
- 在这一点
当您这样做时,您将拥有Lucene索引的现成统计信息,例如:
- 术语的文档频率
- termfequencyVector(正是您需要的)
- 准备使用倒置索引!(要快速介绍倒置索引和检索)
您可以做很多事情来提高性能。例如:
- 并行化文档流处理。
- 您可以将字典存储在键值数据库中,例如Berkeylydb或Kyoto Cabinet,甚至是内存中的键值存储,例如Redis或Memcache。
我希望有帮助。
仅使用MR的方式之一是:
假设您已经有n字典的尺寸较小,可以适合内存:启动n个"仅映射"作业,将扫描您的所有数据(每个数据只有一个字典),然后输出SMTH,例如{pageID,termid,termid,efferes等}到文件夹/your_tmp_folder/n/因此,您将拥有n*m文件,其中m是每个阶段的映射器数量(应该是相同的)。
然后,第二个作业将简单地分析您的{pageID,termid,事件等}对象并构建每个页面ID的统计信息。
在您的情况下,只有映射工作应该很快。如果不是 - 请粘贴代码。