You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Gensim实现基于固定窗口的计数型共现词嵌入?

Gensim中实现固定窗口计数型共现词嵌入

Gensim并没有提供开箱即用的固定窗口二元词频共现模型,但可以利用它的基础工具链快速实现这类计数型词嵌入,适配超大规模语料的处理需求,具体步骤如下:

1. 语料预处理

先用Gensim的轻量工具完成分词与清洗,通过迭代式加载避免一次性占用过多内存:

from gensim.utils import simple_preprocess

def iter_corpus(file_path):
    """迭代式读取超大语料文件"""
    with open(file_path, 'r', encoding='utf-8') as f:
        for line in f:
            yield simple_preprocess(line, deacc=True)

2. 构建词汇表与共现矩阵

针对超大语料,用稀疏方式统计固定窗口内的词共现,降低内存消耗:

from collections import defaultdict
from gensim.corpora import Dictionary

# 生成词汇表,可过滤低频词减少计算量
corpus_iter = iter_corpus("your_large_corpus.txt")
vocab = Dictionary(corpus_iter)
vocab.filter_extremes(no_below=5)  # 过滤出现次数少于5次的词
word2id = vocab.token2id
vocab_size = len(vocab)

# 初始化共现计数器(用键值对存储稀疏共现)
cooccur_counts = defaultdict(int)
window_size = 5  # 自定义上下文窗口大小

# 重新遍历语料统计共现
corpus_iter = iter_corpus("your_large_corpus.txt")
for sentence in corpus_iter:
    sent_ids = [word2id[word] for word in sentence if word in word2id]
    for idx, target_id in enumerate(sent_ids):
        # 确定当前词的上下文窗口范围
        window_start = max(0, idx - window_size)
        window_end = min(len(sent_ids), idx + window_size + 1)
        # 遍历上下文词并统计共现(用sorted避免重复计数双向对)
        for context_id in sent_ids[window_start:idx] + sent_ids[idx+1:window_end]:
            pair = tuple(sorted((target_id, context_id)))
            cooccur_counts[pair] += 1

3. 转换为优化后的词嵌入(PPMI)

原始共现矩阵存在高频词偏差,通常转为**正点互信息(PPMI)**作为最终嵌入,提升效果:

import numpy as np
from scipy.sparse import csr_matrix

# 统计全局词频
corpus_iter = iter_corpus("your_large_corpus.txt")
word_freq = np.zeros(vocab_size, dtype=np.int64)
for sentence in corpus_iter:
    for word in sentence:
        if word in word2id:
            word_freq[word2id[word]] += 1
total_words = word_freq.sum()

# 构建稀疏PPMI矩阵
rows, cols, data = [], [], []
for (i, j), cnt in cooccur_counts.items():
    # 计算PMI并取正值得到PPMI
    pmi = np.log2((cnt * total_words) / (word_freq[i] * word_freq[j]))
    ppmi = max(pmi, 0.0)
    if ppmi > 0:
        rows.extend([i, j])
        cols.extend([j, i])
        data.extend([ppmi, ppmi])

ppmi_sparse = csr_matrix((data, (rows, cols)), shape=(vocab_size, vocab_size))

# 生成词嵌入字典,每个词对应其PPMI向量
word_embeddings = {vocab[id]: ppmi_sparse[id].toarray().flatten() for id in range(vocab_size)}

4. 持久化与加载

用Gensim的KeyedVectors存储嵌入,方便后续快速调用:

from gensim.models import KeyedVectors

# 初始化KeyedVectors并添加向量
kv = KeyedVectors(vector_size=vocab_size)
kv.add_vectors([vocab[id] for id in range(vocab_size)], ppmi_sparse.toarray())

# 保存到本地
kv.save("count_based_embeddings.kv")

# 加载使用
loaded_emb = KeyedVectors.load("count_based_embeddings.kv")
print(loaded_emb["sample_word"])

超大语料适配建议

  • 始终用迭代式方式处理语料,避免一次性读入内存;
  • 全程使用稀疏矩阵存储共现与PPMI数据;
  • 可对语料进行分块处理,逐步累加共现计数,进一步降低内存压力。

内容的提问来源于stack exchange,提问作者la_lo_ca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:44:56