我有大量文字,包括维基百科文章,新闻文章等。总共约15亿个单词,约300万个唯一单词。
我想做的是确定何时将连续单词算作一个单词,例如“橙汁”可能应该被视为一个单词。要决定是否将一对单词视为一个单词,我需要知道双连词出现了多少次,以及双连词中每个单词出现了多少次。
bigramCount/(word1Count*word2Count) > threshold
问题在于,包含我的文本的所有bigram计数的变量将比我的计算机ram大小占用更多的内存。
我尝试做的是:
1. Count single words
2. For every single word:
1. Count every ocurrence of a bigram that starts with that word
2. Decide, applying the formula, which of those bigrams should be treated as a single word.
这样,在内存上就更容易了,但是这样做花费的时间太长。 我目前正在这样做,但是它已经运行了至少一天,因此,我正在尝试提出一种更好的方法。
有什么主意吗?
答案 0 :(得分:0)
将您的数据分成大小均匀的100-200 MiB块。运行算法。将前85%(最常见的组合)的Bigram可能性逗号存储在文件(1.csv)中。按第一个单词对文件排序。
重复不同的文件(2,3,4 ...),直到没有更多数据为止。
将文件1和2关联(合并类似的值计数)到新的CSV文件1a中。 将文件3和4关联到新的CSV文件2a中。 重复其余的文件。 如果文件数量奇数,请将最后一个文件与一个随机文件1..n相关联 然后关联1a,2a ..文件。
继续,直到结果包含单个文件为止。
此过程表示二叉树解决方案。就运行时而言,这是最佳的解决方案,但它会引入空间偏差。在所有样本中更频繁出现的对更紧密或更均匀地分布的对,将在最终产品上具有更高的权重。
最完整的解决方案是完全汇总所有级别的扩展。例如,(分页1和3 => 1b,1和4 => 1c ... 2和1 => 2b,2和3 => 2c,2和4 => 2d ...)...然后下一步将1a和1b ...,2a和2b ...组合起来是指数解决方案(慢)。
要平衡性能 AND 来降低复杂度并降低偏差,您可以在较低级别将配对随机化:
例如:在每个级别分析块时,将块的顺序随机化。确保算法仅一次输出每对。
如果您多次将树底部的选择随机化(如上所述,大约是完整扩展的1/2),同时从所有先前的迭代中消除了重复的对,则上述层中的结果准确性将大大提高
如果您在第二级和第三级重复此随机化操作(如果仍然无法进行全面分析),则由于回报率递减规律,不太可能显着提高性能。
我建议使用预先建立的bigram数据库,或者至少在最高级别限制bigram候选对象(名词或形容词)。否则,您可能会得到最常用的名词/动词组合(在大多数其他现代美国英语数据集中,它们是“我是”或“我有”)。
答案 1 :(得分:0)
而不是试图将其全部保留在内存中,而是多次进行。
首先,创建两个文件,一个用于单个单词,另一个用于双字母组。
现在,依次浏览您的文本。读取每个单词时,将其输出到单个单词文件。将其与前一个单词组合,然后将其写入bigrams文件。例如,给定句子“重点是没有重点,使整个对话变得毫无意义”,则单字文件每行将包含一个字。 bigrams文件将包含:
the point
point is
is that
that there
there is
...
现在,使用操作系统提供的排序实用程序,对每个文件进行排序。将相同的单词组合在一起。
然后,编写一个程序,逐行读取文件,计数相同的行。获得每个单词的总数后,编写一个包含word,count
的相应文件。因此,如果您有:
apple
apple
banana
cherry
cherry
cherry
那么您的输出将是:
apple,2
banana,1
cherry,3
对bigrams文件执行相同的操作。
最后,将您的单字文件加载到地图或词典中,按单词索引,其值为计数。 300万个独特的单词应该适合。如果没有,您可以将它们放入数据库中。像SQLite这样的东西会很好用。
然后开始阅读您的bigrams文件。每行包含二元组及其计数。您可以进行计算并做出决定,然后再将其视为一个单词,也可以将带有其计数和分数的bigram输出到单独的文件中,然后再做出决定。
您可以通过在内存中保留一些内容来减小在第一遍中创建的中间文件的大小。与其立即将每个单词和双字母组写入中间文件,不如在内存中保留两个字典并限制其大小。词典填满后,将单词和计数写入磁盘,然后清除词典。这样,您将只获得少数的“ the,100000”条目,而不是在文件中包含成千上万个单独的“ the”单词。
减小中间文件的大小将提高排序速度。在第二步中,当您删除重复项时,您将为每个条目添加计数,而不仅仅是为每个条目添加计数。
多次执行此操作使事情变得容易,因为它减少了所需的内存,并且每个步骤几乎都非常简单。当然,它没有单程序解决方案快。但是,如果这不是经常性的事情,那么谁在乎这是否需要花费额外的时间呢?
另一个好处是该解决方案具有很好的可扩展性。我在笔记本电脑(8 GB内存)上做过非常相似的事情,字数和二字数与整个英语维基百科的下载量无关。花了一段时间(几个小时),但效果很好。