Gensim学习笔记-1.Corpora模块和向量空间表示

本文介绍如何使用Gensim库进行文本预处理及向量化,包括创建词典、生成词袋模型等步骤,并探讨了如何减少内存消耗及语料库的持久化存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本系列的文章是我根据Gensim官方教程整理而成,并不完全是翻译

开始之前

 如果需要记录日志,只需这样:

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

将文本转为向量

 现在假设我们现在有一个语料库documents,在这个语料库中总共有九个文档,每个文档都只包含一句话。

documents = ["Human machine interface for lab abc computer applications",
              "A survey of user opinion of computer system response time",
              "The EPS user interface management system",
              "System and human system engineering testing of EPS",
              "Relation of user perceived response time to error measurement",
              "The generation of random binary unordered trees",
              "The intersection graph of paths in trees",
              "Graph minors IV Widths of trees and well quasi ordering",
              "Graph minors A survey"]

文本预处理

 首先要做的是分词并且去停用词:

from pprint import pprint
stopWordsList = set('for a of the and to in'.split())
texts = [[word for word in document.lower().split() if word not in stopWordsList]
         for document in documents]
pprint(texts)
[['human', 'machine', 'interface', 'lab', 'abc', 'computer', 'applications'],
 ['survey', 'user', 'opinion', 'computer', 'system', 'response', 'time'],
 ['eps', 'user', 'interface', 'management', 'system'],
 ['system', 'human', 'system', 'engineering', 'testing', 'eps'],
 ['relation', 'user', 'perceived', 'response', 'time', 'error', 'measurement'],
 ['generation', 'random', 'binary', 'unordered', 'trees'],
 ['intersection', 'graph', 'paths', 'trees'],
 ['graph', 'minors', 'iv', 'widths', 'trees', 'well', 'quasi', 'ordering'],
 ['graph', 'minors', 'survey']]

 然后我们去除那些仅仅出现一次词:

# 统计各个单词的频率
frequency = {}
for doc in texts:
    for token in doc:
        frequency.setdefault(token, 0)
        frequency[token] += 1

# 去除
texts = [[token for token in doc if frequency[token] > 1] for doc in texts]
pprint(texts)
[['human', 'interface', 'computer'],
 ['survey', 'user', 'computer', 'system', 'response', 'time'],
 ['eps', 'user', 'interface', 'system'],
 ['system', 'human', 'system', 'eps'],
 ['user', 'response', 'time'],
 ['trees'],
 ['graph', 'trees'],
 ['graph', 'minors', 'trees'],
 ['graph', 'minors', 'survey']]

 当然,具体情况所使用的分词方式可能与这里不太相同,我们这里的分词方法是比较简陋的。

向量化

 通过上面的几个步骤,我们就完成了对整个语料库的分词任务。接下来我们需要对整个库进行向量化。
 在这里,我们使用一个最简单的词袋模型/One-Hot编码。在词袋模型中,每一篇文档都被表示成一个长长的向量,向量中每个数值代表着对应单词出现的频数。
 为此,我们想对语料中的每一个单词关联一个唯一的ID。这可以用gensim.corpora.Dictionary来实现。这个字典定义了我们要处理的所有单词表。

# 直接导入可能出现warning
import warnings
warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')
from gensim import corpora
dictionary = corpora.Dictionary(texts)
# 可以将corpora.Dictionary对象保存到文件
# dictionary.save(r'C:\Users\zuoyiping\Desktop\Doc.dict')
print(dictionary)
Dictionary(12 unique tokens: ['computer', 'human', 'interface', 'response', 'survey']...)

 上面的这个dictoinary就是建立了从ID到单词的映射关系的字典,它的词表长度为12,我们可以很轻易的查看想要的信息:

print('各个单词的ID:\n', dictionary.token2id)
print('各个单词的频率:\n', dictionary.dfs)
各个单词的ID:
 {'computer': 0, 'human': 1, 'interface': 2, 'response': 3, 'survey': 4, 'system': 5, 'time': 6, 'user': 7, 'eps': 8, 'trees': 9, 'graph': 10, 'minors': 11}
各个单词的频率:
 {1: 2, 2: 2, 0: 2, 4: 2, 7: 3, 5: 3, 3: 2, 6: 2, 8: 2, 9: 3, 10: 3, 11: 2}

 此外Dictionary还可以继续添加语料库,为其扩容:

add_documents(documents, prune_at=2000000)
"""
documents (iterable of iterable of str) – Input corpus. All tokens should be already tokenized and normalized.
"""

 在有了映射字典之后,就可以将给定的语料转换为词袋模型了,主要用到的函数有两个:

doc2bow(document, allow_update=False, return_missing=False)
"""
    将document转为 bag-of-words (BoW)
    Parameters: 
        document: (list of str)

"""
 doc2idx(document, unknown_word_index=-1)
"""
    将document转为对应的list of ID
    Parameters: 
        document (list of str)
"""
newDoc = "Human response interaction human".lower().split(' ')
oneHotVec = dictionary.doc2bow(newDoc)
docId = dictionary.doc2idx(newDoc)
print('出现的词:')
print(docId)
print('词袋向量:')
print(oneHotVec)
出现的词:
[1, 3, -1, 1]
词袋向量:
[(1, 2), (3, 1)]

 新的文档newDoc被转换为了词袋向量oneHotVec。不过值得注意的是在Gensim中,语料库的词袋表示是使用稀疏向量的。表示方法为: [(ID, 词频)],没有出现的ID对应的值为0。
 现在,我们把原始的语料库转换为词袋向量组:

corpus = [dictionary.doc2bow(doc) for doc in texts]
pprint(corpus)
[[(0, 1), (1, 1), (2, 1)],
 [(0, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)],
 [(2, 1), (5, 1), (7, 1), (8, 1)],
 [(1, 1), (5, 2), (8, 1)],
 [(3, 1), (6, 1), (7, 1)],
 [(9, 1)],
 [(9, 1), (10, 1)],
 [(9, 1), (10, 1), (11, 1)],
 [(4, 1), (10, 1), (11, 1)]]

 这样以来,我们就将文本转化为可以被处理的向量了。当然我们知道,词袋模型只不过是一个最简单的模型,在实际的应用当中,我们很少直接把它拿来用。想要投入实际的应用当中,我们还要需要对这个模型进行一些转换,关于这个主题,我们在接下来的教程中会继续探究。

削减内存开支

 在上一个板块当中,我们成功的得到了文档转换出来的向量。但是还存在着一个很严重的问题,那就是在之前的做法当中,我们一次性将所有的文档全部都入内存,并转换为向量,如果语料库的规模很大,这样做的开支是非常大。
 为此,我们可以利用迭代器这一特性,来建立一个“内存友好型”的语料库。比如我们可以把整个原始文档语料库写入一个文件,每篇文档的内容占一行。然后迭代地读取每一行,并返回词袋向量。
 比如现在我们把之前的文档写入一个文件mycorpus.txt中:

class MyCorpus:
    def __init__(self, filepath, dictionary):
        self.file = filepath
        self.dict = dictionary

    def __iter__(self):
        with open(self.file, encoding='utf-8') as f:
            for line in f:
                text = line.lower().split()
                yield self.dict.doc2bow(text)


memoryFriendlyCorpus = MyCorpus(r'./Data/mycorpus.txt', dictionary)
for vec in memoryFriendlyCorpus:
    print(vec)
[(0, 1), (1, 1), (2, 1)]
[(0, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)]
[(2, 1), (5, 1), (7, 1), (8, 1)]
[(1, 1), (5, 2), (8, 1)]
[(3, 1), (6, 1), (7, 1)]
[(9, 1)]
[(9, 1), (10, 1)]
[(9, 1), (10, 1), (11, 1)]
[(4, 1), (10, 1), (11, 1)]

 同样的道理也可以用于构建Dictionary的过程,这里就不再赘述了。

语料库的序列化表示结构

 为了持久化我们的语料库,一般我们都需要将其序列化并存在硬盘上。这样一来,我们就有许多种格式可以选择,而Gensim也为我们提供了很多种方法来序列化,每种方法都对应着一种不同的文件表示格式
 这些方法一般都形如corpora.xxxCorpus,其中xxxCorpus是对用方式的类。使用格式如下:
- 序列化并保存: corpora.xxxCorpus.serialize(filepath, corpus)
- 导入: corpora.xxxCorpus(filepath)

 常用的主要有这几个:
- MmCorpus
- LowCorpus
- SvmLightCorpus
- BleiCorpus

 其他更多的请看官方API文档。这里以MmCorpus为例。

sampleCorpus = [[(1, 0.5), (3, 4)], []]
# 序列化导出
corpora.MmCorpus.serialize('./Data/sampleCorpus.mm', sampleCorpus)
# 导入
sampleCorpus = corpora.MmCorpus('./Data/sampleCorpus.mm')
print(sampleCorpus)
for doc in sampleCorpus:
    print(doc)
MmCorpus(2 documents, 4 features, 2 non-zero entries)
[(1, 0.5), (3, 4.0)]
[]

 注意到MmCorpus对象是可迭代的,这也是为了友好内存。另外,其他的一些也是可以保存的,比如Dictionary对象,他就有saveload两个方法,可以用于持久化。

dictionary.save('./Data/sampleDict.dict')
dictionary = corpora.Dictionary.load('./Data/sampleDict.dict')
print(dictionary)
Dictionary(12 unique tokens: ['computer', 'human', 'interface', 'response', 'survey']...)
<think>我们正在解决用户在使用pip安装gensim时遇到的两个问题:下载超时文件访问冲突(另一个程序正在使用此文件)。根据引用内容,我们可以提供以下解决方案:1.更换镜像源(解决下载超时问题):使用国内镜像源可以加速下载,例如清华源、中科大源等。2.设置超时时间(解决下载超时问题):通过增加`--default-timeout`参数来延长超时时间。3.使用.whl文件手动安装(解决下载问题):从官方网站下载对应的.whl文件,然后使用pip安装该文件。4.编写脚本处理安装(解决超时跳过错误):编写一个Python脚本,读取包含库名的文件,逐个安装并设置超时。5.检查文件占用(解决“另一个程序正在使用此文件”问题):关闭可能占用文件的程序,或者重启计算机后再尝试安装。具体步骤:方法一:更换镜像源并设置超时在命令行中执行:pipinstall --default-timeout=1000-ihttps://pypi.tuna.tsinghua.edu.cn/simplegensim或者使用中科大源:pipinstall --default-timeout=1000-ihttps://pypi.mirrors.ustc.edu.cn/simple gensim方法二:手动下载.whl文件安装步骤1:访问https://pypi.org/project/gensim/#files,下载与你的Python版本系统对应的.whl文件。步骤2:将下载的.whl文件放到某个目录(例如C:\)。步骤3:在命令行中进入该目录,执行:pip installgensim-*.whl#将*替换为具体的文件名方法三:使用脚本安装(适用于批量安装或需要跳过错误的情况)编写一个Python脚本(例如install_req.py),内容如下:import sysfrom pip._internalimport mainas pip_maindefinstall(package):pip_main(['--default-timeout=1000', 'install','-U', package])if __name__=='__main__':withopen(sys.argv[1])as f:for linein f:install(line.strip())然后创建一个文本文件(例如requirements.txt),里面写入要安装的库名,每行一个,例如:gensim运行脚本:python install_req.py requirements.txt方法四:解决文件占用问题错误提示“另一个程序正在使用此文件”通常是因为有程序占用了pip要操作的文件(可能是之前安装中断导致的锁定文件,或者杀毒软件等占用)。可以尝试:a)关闭所有正在运行的Python程序。b)关闭可能占用文件的安全软件。c)重启计算机,然后再次尝试安装。如果以上方法都不能解决,可以考虑在虚拟环境中安装(避免全局环境干扰):python-mvenvmyenvmyenv\Scripts\activate(Windows)或source myenv/bin/activate(Linux/Mac)然后在虚拟环境中使用上述方法安装。根据引用[5],用户可能遇到的是环境问题,使用虚拟环境可以避免一些权限冲突问题。注意:在运行任何安装命令之前,请确保以管理员身份运行命令行(Windows)或使用sudo(Linux/Mac)以获得必要的文件操作权限(如果遇到权限问题)。希望这些方法能帮助用户成功安装gensim。</think>### pip install gensim 下载超时及文件占用问题解决方案 #### 问题原因分析 1. **下载超时**: - 网络连接不稳定或服务器响应慢 - 默认超时时间(通常15秒)不足以下载大型包 - 国内访问PyPI官方源速度较慢 2. **文件占用错误**: - 其他程序(如IDE、杀毒软件)锁定了pip缓存文件 - 前次安装意外中断导致文件未释放 - 系统权限问题(常见于Windows) --- #### 解决方案指南 ##### 一、解决下载超时 1. **更换国内镜像源**(推荐首选): ```bash pip install --default-timeout=1000 -i https://pypi.tuna.tsinghua.edu.cn/simple gensim ``` ```bash pip install -i https://pypi.mirrors.ustc.edu.cn/simple gensim ``` 2. **手动指定超时时间**: ```bash pip install --timeout 1000 gensim ``` 3. **下载whl文件手动安装**: 1. 访问[gensim官方下载页](https://pypi.org/project/gensim/#files) 2. 下载对应版本(如`gensim-4.3.2-cp39-cp39-win_amd64.whl`) 3. 执行本地安装: ```bash pip install gensim-4.3.2-cp39-cp39-win_amd64.whl ``` ##### 二、解决文件占用错误 1. **关闭占用程序**: - 退出所有Python IDE(如PyCharm、VSCode) - 临时禁用杀毒软件实时扫描 - 检查任务管理器中是否有python.exe进程残留 2. **清除pip缓存**: ```bash pip cache purge ``` 3. **强制解锁文件**(Windows): 1. 使用资源监视器定位占用进程: - 按`Win+R`输入`resmon` - 在"关联的句柄"中搜索`.whl`或`gensim` 2. 结束占用进程后重试安装 4. **使用安装脚本**(应对复杂环境): ```python:install_req.py import sys from pip._internal import main as pip_main def install(package): pip_main(['--default-timeout=1000', 'install', '-U', package]) if __name__ == '__main__': with open(sys.argv[1]) as f: for line in f: install(line.strip()) ``` 执行命令: ```bash python install_req.py requirements.txt ``` ##### 三、进阶方案 1. **使用虚拟环境**(避免全局冲突): ```bash python -m venv gensim_env gensim_env\Scripts\activate # Windows pip install gensim ``` 2. **添加用户权限**(Windows): ```bash pip install --user gensim ``` 3. **管理员模式运行**: - 右键点击命令提示符 → 以管理员身份运行 - 再执行安装命令 --- #### 关键注意事项 1. 镜像源更新后仍超时 → 尝试更换其他镜像(阿里云:`https://mirrors.aliyun.com/pypi/simple/`) 2. 文件占用错误反复出现 → 重启操作系统后立即安装 3. 复杂依赖问题 → 使用`conda install -c conda-forge gensim` > 引用说明:解决方案参考了清华大学镜像源文档[^1]、中科大镜像源指南[^2]、pip缓存管理规范[^3]、Windows资源监视器官方文档[^4]及Python虚拟环境最佳实践[^5]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值