Python----NLP自然语言处理(Glove)
一、Glove介绍
GloVe (Global Vectors for Word Representation) 是一种用于生成词向量的模型,于2014 年提出。它通过结合全局统计信息与低维词向量表示,将单词的语义关系嵌入到向量空间中,是一种强大的词嵌入技术。
首先我们来说Word2Vec训练时的不足,Word2Vec 通过局部上下文窗口学习词向量。例如,窗口大小为 1 时,有这样两句话:
我 喜欢 甜 豆腐脑,.......
我 喜欢 咸 豆腐脑,.......
Word2Vec能学习到甜和咸都与喜欢,豆腐脑相关,这很好地捕捉了局部语义关系。但Word2Vec并没有直接捕捉到甜与咸是有关系的,都可以表示味道。那么要如何学习到甜与咸的关系呢?
我们可以统计全局单词共同出现的概率,也叫全局共现关系,我们需要知道全局所有单词共同出现的概率,就会发现,甜和喜欢与咸和喜欢的共现次数相近,甜和豆腐脑与咸和豆腐脑共现次数相近,虽然甜和咸可能从不直接共现,但它们的 共现分布模式 很相似,这样虽然没有局部窗口,也可以捕捉到甜和咸的相似性。
举个例子,如果我们只观察某个学校,每次学生出现的情况,我们会发现我与甲乙丙三个同学经常同时出现,这能代表我与甲乙丙关系好;小明也与甲乙丙经常同时出现,这能代表小明与甲乙丙关系好,但推测不出来我与小明关系好。但如果统计所有学生出现的情况,我们就能推测出我与小明关系好,这就是全局统计比局部窗口的优势。而GloVe的核心就是全局共现矩阵。

这个矩阵是一个对称矩阵,真正训练过程中,计算的不是共现次数,而是共现次数和权重递减函数的乘积,从而达到距离越远的共现词的权重越小,而距离越近的词对权重越大。
二、Glove的训练过程
输入语料库,语料库越大越好
生成共现矩阵。通过遍历语料库,统计每对单词和在指定窗口内共现的次数。窗口大小通常是前后 5 到 10 个单词。窗口越大,捕获的语义信息越多,但可能会引入噪声。
训练目标是:中心词的向量 × 上下文词的向量 + 偏置项 ≈ 共现次数

通过神经网络重复训练,更新中心词的向量,上下文词的向量,偏置项,不断降低目标函数以及损失函数的值。

三、Glove案例
Glove的模型出现时间较早,最近没有更新,所以python版本支持到3.8,为了环境稳定,可以使用3.6版本python
Glove的运行需要依赖C++环境,所以要求我们的电脑配置好C++编译环境。
# 导入所需的库
from glove import Glove # GloVe词向量模型
from glove import Corpus # 用于构建共现矩阵
import jieba # 中文分词器
import re # 正则表达式库,用于文本清洗
# 打开三国演义文本文件进行读取
f = open('sanguo.txt', 'r', encoding='utf-8')
# 初始化一个空列表,用于存储所有分词后的文本行
lines = []
# 遍历文件的每一行
for line in f:
# 使用jieba进行精确模式分词,将一行文本分割成词语列表
temp = jieba.lcut(line)
# 初始化一个空列表,用于存储当前行清洗后的词语
words = []
# 遍历当前行的每个词语
for i in temp:
# 使用正则表达式去除标点符号和特殊字符
# 正则表达式匹配各种中文和英文标点符号
i = re.sub("[\s+\.\!\/_,$%^*(+\"\'””《》]+|[+——!,。?、~@#¥%……&*():;‘]+", "", i)
# 只保留非空词语
if len(i) > 0:
words.append(i)
# 只保留非空行
if len(words) > 0:
lines.append(words)
# 打印前5行的分词结果,用于预览
print(lines[0:5])
# 创建Corpus对象用于构建共现矩阵
corpus = Corpus()
# 使用文本数据构建共现矩阵,设置上下文窗口大小为10
# window参数表示在中心词前后各考虑多少个词作为上下文
corpus.fit(lines, window=10)
# 打印词汇表的大小(唯一词的数量)
print("词汇表大小:", len(corpus.dictionary))
# 打印共现矩阵(通常是一个稀疏矩阵)
print(corpus.matrix)
# 创建GloVe模型实例
# no_components: 词向量的维度(这里是20维)
# learning_rate: 学习率,控制参数更新的步长
glove = Glove(no_components=20, learning_rate=0.05)
# 训练GloVe模型
# corpus.matrix: 上一步生成的共现矩阵
# epochs: 训练轮数,整个数据集遍历10次
# no_threads: 使用的线程数,提高训练速度
# verbose: 显示训练进度信息
glove.fit(corpus.matrix, epochs=10, no_threads=4, verbose=True)
# 将词汇表添加到GloVe模型中,建立词语到向量的映射
glove.add_dictionary(corpus.dictionary)
# 查看模型中的词汇表(字典形式:词语->索引)
print(glove.dictionary)
# 获取词语"刘备"对应的词向量
# 1. 通过字典找到"刘备"的索引
# 2. 通过索引在词向量矩阵中找到对应的向量
print(glove.word_vectors[glove.dictionary['刘备']])
# 查找与"主公"最相似的10个词语
# most_similar方法基于余弦相似度计算词语相似度
# number参数指定返回的相似词数量
print(glove.most_similar('主公', number=10))
数据预处理:
使用jieba.lcut()进行中文分词
使用正则表达式re.sub()去除标点符号和特殊字符
过滤空词和空行,确保数据质量
共现矩阵构建:
corpus.fit(lines, window=10):构建词语共现矩阵
窗口大小(window=10)表示考虑中心词前后各10个词作为上下文
GloVe模型训练:
设置词向量维度(no_components=20)
设置学习率(learning_rate=0.05)控制优化速度
训练10个epochs(epochs=10)
使用4个线程并行计算(no_threads=4)
词向量应用:
获取单个词的向量表示(如"刘备")
查找语义相似的词语(如与"主公"最相似的10个词)
更多推荐


所有评论(0)