【发布时间】:2011-08-19 11:49:51
【问题描述】:
我需要对一组 n-gram(n 个单词的序列)及其上下文(出现在 n-gram 附近的单词及其频率)进行建模。我的想法是这样的:
public class Ngram {
private String[] words;
private HashMap<String, Integer> contextCount = new HashMap<String, Integer>();
}
然后,对于所有不同 n-gram 的计数,我使用另一个 Hashmap,例如
HashMap<String, Ngram> ngrams = new HashMap<String, Ngram>();
我在接收文本时添加它。问题是,当 n-gram 的数量超过 10,000 左右时,JVM 堆会填满(设置为最大 1.5GB),并且一切都变得非常缓慢。
有没有更好的方法来做到这一点,以避免这种内存消耗?此外,n-gram 之间的上下文应该很容易比较,我不确定我的解决方案是否可行。
【问题讨论】:
-
我们希望这些尺寸是多少?每个 n-gram 大约有多少个单词?另外,您是否使用了辅助内存,例如大型临时内存?不要忘记,hashmap 在调整大小时可能是内存密集型结构!
-
你到底想用这些 n-gram 做什么?您是否使用 n-gram-tokenfilter 看过 lucene?也许您可以使用 lucene 索引来执行您需要执行的任务。然后,您可以将其保存在内存中或存储到文件系统中。
-
我从大约 50,000 篇新闻文章中收集 ngram。处理6000篇文章后,Ngram中一个context Hashmap的平均大小在13左右。我没有任何辅助记忆,至少我不这么认为:)
-
我试图通过比较它们的上下文向量来找到语义相似的 n-gram。我对 lucene 进行了一些研究,但似乎他们的 n-gram 定义是基于字符的,而不是像我的那样基于单词的。
-
如果地图 contextCount 通常很小,并且不同上下文的数量也很小且固定,请考虑将上下文更改为 Enum 并使用 EnumMap。 String 和 HashMap 对小数据都有很多开销,这可能是你的内存去向。
标签: java string hashmap n-gram