Algorithm 跟踪/计数字频

Algorithm 跟踪/计数字频,algorithm,indexing,word-frequency,Algorithm,Indexing,Word Frequency,我想在一个好的设计上取得一些社区共识,以便能够存储和查询词频计数。我正在构建一个应用程序,在这个应用程序中,我必须解析文本输入并存储一个单词出现的次数(随着时间的推移)。因此,考虑到以下输入: “杀死一只知更鸟” “模仿钢琴手” 将存储以下值: Word Count ------------- To 1 Kill 1 A 2 Mocking 2 Bird 1 Piano 1 Player 1 然后能够快速查询给定任意单词的计数值 我目前的计划是

我想在一个好的设计上取得一些社区共识,以便能够存储和查询词频计数。我正在构建一个应用程序,在这个应用程序中,我必须解析文本输入并存储一个单词出现的次数(随着时间的推移)。因此,考虑到以下输入:

  • “杀死一只知更鸟”
  • “模仿钢琴手”
将存储以下值:

Word    Count
-------------
To      1
Kill    1
A       2
Mocking 2
Bird    1
Piano   1
Player  1
然后能够快速查询给定任意单词的计数值

我目前的计划是简单地将单词和计数存储在数据库中,并依靠缓存单词计数值。。。但我怀疑,我不会得到足够的缓存命中率,使其成为长期可行的解决方案


有人能提出算法、数据结构或任何其他想法,使其成为一个性能良好的解决方案吗?

单词计数是程序的典型示例(来自维基百科的伪代码):


我并不是说这是一种方法,但如果你需要一种能够在单个机器上的不同单词数量超过可用内存时进行良好扩展的工具,那么这绝对是一种选择。只要您能够保持在内存限制以下,一个简单的循环更新哈希表就可以了。

我不明白为什么您觉得数据库不是一个合适的解决方案。您可能只有大约100000行,表的小尺寸意味着它可以完全存储在内存中。将单词作为主键,查找速度将非常快。

使用a。

您的解决方案听起来不错。如果缓存基于最近的使用计数,则它将保存最频繁的字的字计数。(单词分布类似于前100个单词覆盖了90%的单词实例),因此您不需要非常大的缓存


如果要提高性能并删除数据库,可以将单词编码为trie,并将使用计数存储在叶节点中。在本质上,如果您对word文本进行索引,那么数据库就是这样做的,因此您实际上只是在避免数据库延迟。如果这就是目标,那么还有其他避免db延迟的方法,例如使用并行查找。

如果性能是您的主要目标,那么您可以仅在RAM中使用基于哈希或基于trie的结构。假设您仍然执行一些有用的筛选(不计算包含非单词字符的术语),则表中的最大字数将在10个范围内⁶ 到10⁷ (即使涉及多种语言),因此这将很容易放入当前PC的内存中(并完全避免所有数据库处理)

另一方面,如果您必须自己实现哈希表细节,那么可能会有更多的代码出错(而数据库人员希望将代码调整到最大)。因此,即使是您自己实现中的微小细节也可能再次导致性能损失

因此,这一困境清楚地向我们展示了优化的第一条和第二条规则: 1.不要过早地优化。 2.测量,然后再优化

:)

void map(String name, String document):
  for each word w in document:
     EmitIntermediate(w, "1");

void reduce(String word, Iterator partialCounts):
  int result = 0;
  for each pc in partialCounts:
    result += ParseInt(pc);
  Emit(AsString(result));