我有15GB的单词文本。我需要计算固定大小的窗口中单词的共现计数,然后对其进行处理。例如,这是我的文字;
"阿福说呵呵,酒吧说什么?">
要从此文本中构建窗口大小 = 4 的共现频率的双孔图,输出应如下所示;
字1-字2-计数
福,说,1
噗嗤,噗噗,1
福,酒吧,1
说,呼,2
说,酒吧,2
说,说,1
呼,酒吧,1
呼,什么,1
酒吧,什么,1
说,什么,1
我已经知道有工具可以做到这一点,例如 NLTK,但它不是多线程的,因此不适用于大小为 15gb 的文本。有没有任何工具可以在给定的窗口大小中快速为我提供单词的共现矩阵?
我自己也在寻找过这样的工具,但从未找到过。我通常只是简单地写一个脚本来做到这一点。下面是一个示例,其中包含一些可能对您有用的限制:
import concurrent.futures
from collections import Counter
tokens = []
for _ in range(10):
tokens.extend(['lazy', 'old', 'fart', 'lying', 'on', 'the', 'bed'])
def cooccurrances(idx, tokens, window_size):
# beware this will backfire if you feed it large files (token lists)
window = tokens[idx:idx+window_size]
first_token = window.pop(0)
for second_token in window:
yield first_token, second_token
def harvest_cooccurrances(tokens, window_size=3, n_workers=5):
l = len(tokens)
harvest = []
with concurrent.futures.ThreadPoolExecutor(max_workers=n_workers) as executor:
future_cooccurrances = {
executor.submit(cooccurrances, idx, tokens, window_size): idx
for idx
in range(l)
}
for future in concurrent.futures.as_completed(future_cooccurrances):
try:
harvest.extend(future.result())
except Exception as exc:
# you may want to add some logging here
continue
return harvest
def count(harvest):
return [
(first_word, second_word, count)
for (first_word, second_word), count
in Counter(harvest).items()
]
harvest = harvest_cooccurrances(tokens, 3, 5)
counts = count(harvest)
print(counts)
如果您只是运行代码,您应该会看到以下内容:
[('lazy', 'old', 10),
('lazy', 'fart', 10),
('fart', 'lying', 10),
('fart', 'on', 10),
('lying', 'on', 10),
('lying', 'the', 10),
('on', 'the', 10),
('on', 'bed', 10),
('old', 'fart', 10),
('old', 'lying', 10),
('the', 'bed', 10),
('the', 'lazy', 9),
('bed', 'lazy', 9),
('bed', 'old', 9)]
限制:
- 由于切片,此脚本无法很好地处理大型令牌列表
window
列表的切碎在这里有效,但如果您打算对窗口列表切片执行任何操作,您应该意识到这一点- 您可能需要实现一些特定的东西来替换
Counter
对象,以防阻塞(再次是大列表限制(
疯狂猜测:
您可以使用spaCy
Matcher
编写这样的东西(请参阅此处(,但是,我不确定这是否有效,因为您需要的通配符仍然有点不稳定(根据我的经验(。