前言:
最近在忙毕设,要学习一些AI的技术。很多资料看来看去,感觉只是在大脑皮层表面略过了一下,遂还是决定采用老方法,写博客!!!对了,**我也只是一个萌新,博客的内容仅代表我个人当前的理解,可能会有偏差。**若有不对,感谢指正。
我学习过程用到的资料:
最简单的词向量word2vec模型原理通俗解读与代码实现实战 自然语言处理_哔哩哔哩_bilibili
【自然语言处理】Word2Vec 词向量模型详解 + Python代码实战_word2vec模型-CSDN博客
本课程详细讲解了word2vec的训练过程和方法, 不涉及数学公式, 简单易懂, 并且全程手写代码加强理解。_哔哩哔哩_bilibili
目录
[1.1 词向量(Word Embedding)导入](#1.1 词向量(Word Embedding)导入)
[1.2 用计算机描述词语注意点](#1.2 用计算机描述词语注意点)
[1.3 词向量------计算机里描述一个词](#1.3 词向量——计算机里描述一个词)
[1.4 词向量表示及其意义](#1.4 词向量表示及其意义)
[2.1 怎么训练词向量/构建数据集?](#2.1 怎么训练词向量/构建数据集?)
[2.2 不同模型对比 :](#2.2 不同模型对比 :)
[2.3 负采样](#2.3 负采样)
[3.1 官方文档:](#3.1 官方文档:)
[3.2 简单代码例子:](#3.2 简单代码例子:)
[3.3 模型重要参数讲解:](#3.3 模型重要参数讲解:)
一、词向量是什么?
1.1 词向量(Word Embedding)导入
首先,Word2Vec就是 Word to vector,
单词->向量,
我们把这种向量叫做词向量。
那究竟是怎么用词向量来表示词语呢?
怎么描述一个人?
当我们尝试描述taylor swift:taylor swift、美国歌手、音乐家、作词人、金发碧眼、格莱美获奖者......我们发现,描述的信息越多,传达的意思越清楚,越能表达出我们要描述的对象。
那么当我们用向量描述词语时,肯定是,维度越多描述得越清楚。
就像用xyz坐标系描述一个点,肯定比xy准确。
1.2 用计算机描述词语注意点
当我们在计算机里描述一个词(语义为导向)的时候有什么需要注意的呢?
- 当组成词的顺序不同时,短语意思可能完全改变
自然语言处理 与 语言自然处理
虽然 ,"自然" "语言" "处理" 的 词频都是1,但是两个短语的意思完全不一样。
- 不同表示形式的词语,语义是一样
nlp 与 自然语言处理
这两个词表达的意思是完全一致,但是如果从词频、字母构成上来考虑,两个词南辕北辙。
两个词在向量表达上应该要完全一致,有没有算法能把这些问题考虑进去呢?
1.3 词向量------计算机里描述一个词
- 人类可以直观理解汉字的语义和情感,但计算机无法直接"读懂"文字。
- 为了让计算机处理文字,我们需要将汉字转化成它"能看懂"的形式:数字。
- 就像描述一个人需要很多维度(身高、体重、年龄、性格等),描述一个词语也需要多个特征。
- 因此,出现了词向量,一般是50-300维。描述的维度越多,表达的越准确。
词向量的特点:
**越相近的表达离的越近,越远的表达离得越远。**假设在二维向量里表示篮球和足球,它们所处的位置应该是很相近的,因为它们都是球类运动。
正因为这一特性,可以通过以用不同方法(欧氏距离、曼哈顿距离、切比雪夫距离、余弦相似度等)来计算两个向量之间的相似度。
通常,数据的维度越高,能提供的信息越高,从而计算的结果更可靠。
1.4 词向量表示及其意义
词向量长啥样:
queen = [0.14, 0.27, -0.09, 0.58, -0.30, 0.43, 0.31, -0.20, 0.10, 0.18,
-0.42, 0.39, 0.63, -0.17, 0.05, 0.21, -0.28, 0.52, 0.70, -0.07]
词向量的值有含义吗?
词向量是一种用数值向量表示词的方法,其中向量的每个维度都是一个实数值。**这些数字的含义是计算机通过模型学习出来的,目的是捕获单词之间的语义关系。词向量的维度中的数字并不直接代表具体的含义,**而是通过在高维空间中表示单词之间的距离或方向来隐含地描述语义关系。
这些值 无法解释 只是计算机认识它相当于一个编码 而已 我们不用考虑它的具体含义
只需要把它训练出来
至于如何评估 如何认识 交给计算机
二、如何训练词向量
2.1 怎么训练词向量/构建数据集?
我想要我的模型学习到词应该用什么样的向量表达最合适。
我们希望,我们的神经网络再输入 "在 词向量 " 可以得到 "模型"
让我们的神经网络 知道我们想说什么,
这就是我们想构建的一个输入输出。
理想期望:
如图所示,在词向量模型中,输入是 Thou 和 shalt,模型的任务是预测它们的下一个词是什么。
最后一层连接了 SoftMax,Softmax 层将模型的输出(每个词的得分)转化为概率分布,这样就可以得到一个关于哪个词最有可能作为下一个词的预测。
那一个词,是不能往神经网络里输入的,那我们要往神经网络里输入什么呢?
**初始化操作:**首先我们有一个词库大表,每个词都有其对应的初始词向量,这个初始值是随机的。
**输入输出:**输入时,每个词找到其对应的词向量。输出,所预测的词的向量。
**训练迭代:**在这个训练过程中,不光会更新整个神经网络模型的权重参数矩阵,还会更新输入;随着训练进行,整个词库大表也会更新。越进行更新,神经网络学的越好。
数据从哪里来呢?
我们的语言是可以跨文本的,
"今天天气晴朗",
这句话无论是在新闻、小说、日记里......都是表示一个意思。
因此我们的训练文本不用局限于某一处,一切合乎我们说话逻辑的东西,都可以作为训练数据。
怎么构建数据?
数据集构建比较容易理解,这里的滑动窗口,参数可以自己指定。不断扫描出来数据集。
2.2 不同模型对比 :
CBOW:
这个模型的训练集构建:用上下文作为输入,中间词作为输出。
Skipgram:
数据集构建:通过当前的一个词去预测上下文。
对比:
2.3 负采样
当我们的语料库很庞大时,假设有5w个词语,在最后一层softmax时,就是一个五万分类任务,是非常耗时耗力的,有没有什么改进方法呢?
给出 "not",预测出 "thou" 在其之后
转化为:
判断 "thou" 这个词 是在"not"后面的可能性是有多大的?
那么就可以转化为01任务,1的话:是,0的话:不是。
问题来了,在我们构建训练集时,
训练集构建出来的所有标签都是1,训练出来的结果不会好。
对于2分类问题,有了1,那还缺0,
**因此,改进方案:加入一些负样本(负采样模型),**正样本是训练集当中的,负样本是手动构造出来的,是一些在训练集中没有前后关系的数据词。
在 常用包gensim 中,Word2Vec 模型的negative
(负采样的数量)默认为5。
三、实战:调用Gensim训练WordVec模型
3.1 官方文档:
models.word2vec -- Word2vec embeddings --- gensim
https://code.google.com/archive/p/word2vec/
安装gensim:
bash
pip install gensim
3.2 简单代码例子:
python
from gensim.models import Word2Vec
# 示例语料库:一个简单的句子列表,每个句子是一个词的列表
sentences = [
['我', '爱', '吃', '汉堡'],
['狐狸', '快速', '跳跃', '在', '懒狗', '上面'],
['你好', '世界'],
['我', '喜欢', '机器', '学习'],
['gensim', '在', '词向量', '处理中', '很棒'],
['自然', '语言', '处理', '很', '有趣'],
['人人', '都', '喜欢', '吃', '螺蛳粉'],
]
# 训练 Word2Vec 模型
# 这里我们使用默认参数,设置 min_count=1 来保留所有词汇,vector_size=100表示词向量的维度
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)
# 获取 '螺蛳粉' 词的词向量
vector_luosifen = model.wv['螺蛳粉']
print("Word vector for '螺蛳粉':", vector_luosifen)
# 使用模型找到与 'fox' 最相似的词汇
similar_words = model.wv.most_similar('螺蛳粉', topn=3)
print("Most similar words to 'fox':", similar_words)
# 保存模型
model.save("word2vec.model")
# 加载模型
loaded_model = Word2Vec.load("word2vec.model")
# 获取已加载模型中 'fox' 的词向量
vector_fox_loaded = loaded_model.wv['螺蛳粉']
print("Loaded model's vector for '螺蛳粉':", vector_fox_loaded)
这里只是一个简单的使用例子,真实训练中,语料库要大很多,训练出来的模型才有。
3.3 模型重要参数讲解:
1. sentences
- 类型:
iterable of iterables
(例如:列表,列表的列表)- 说明: 输入的语料库,是一个包含句子的可迭代对象。每个句子是一个词的列表。
- 用途: 这是模型训练的核心输入数据,必须传入。如果不传入,则必须通过
corpus_file
或其他方式提供数据。
corpus_file
- 类型:
str
(文件路径)- 说明: 语料库文件的路径,文件应该以
LineSentence
格式存在(每行一个句子,句子中的词之间用空格分开)。可以用来代替sentences
提高效率。- 用途: 当数据集较大时,可以将语料数据保存在文件中,通过指定这个参数来加载数据而不需要将其全部加载到内存中。
3. vector_size
- 类型:
int
(默认值为 100)- 说明: 词向量的维度,即每个词会被表示成一个
vector_size
维的向量。- 用途: 控制模型的复杂度和计算效率,维度越高,模型的表达能力更强,但计算和内存开销也会增加。
4. window
- 类型:
int
(默认值为 5)- 说明: 当前词与预测词之间的最大距离(上下文窗口大小)。
- 用途: 定义了模型在训练时考虑的上下文范围。例如,如果
window=5
,那么每个词的上下文将包括前后各 5 个词。
5. min_count
- 类型:
int
(默认值为 5)- 说明: 忽略所有频率低于此值的词汇。
- 用途: 这个参数用于清理语料中的稀有词汇,减少训练时不重要或噪声数据对模型的影响。
6. sg
(Skip-gram)
- 类型:
{0, 1}
(默认值为 0)- 说明: 训练算法的选择。
sg=1
使用 Skip-gram 模型,sg=0
使用 CBOW 模型。- 用途:
- Skip-gram(
sg=1
)适用于稀有词汇,模型会根据上下文预测中心词。- CBOW(
sg=0
)适用于频繁词汇,模型会根据上下文预测目标词。
7. hs
(Hierarchical Softmax)
- 类型:
{0, 1}
(默认值为 0)- 说明: 是否使用层次化 Softmax 方法来训练词向量。
- 用途:
hs=1
表示使用层次化 Softmax。hs=0
不使用层次化 Softmax,改为使用负采样方法(由negative
参数控制)。
8. negative
- 类型:
int
(默认值为 5)- 说明: 负采样的个数。如果大于 0,将启用负采样,并且会为每个正样本采样
negative
个负样本。- 用途: 负采样减少了每次迭代时计算的词汇量,从而提高了训练速度。通常,负样本数设为 5 到 20 之间。
9. alpha
- 类型:
float
(默认值为 0.025)- 说明: 初始学习率。
- 用途: 控制学习率的大小。在训练开始时,模型的学习率较高,但随着训练的进行,它会逐渐衰减。
10. min_alpha
- 类型:
float
(默认值为 0.0001)- 说明: 学习率衰减到
min_alpha
时停止衰减。- 用途: 用于控制学习率的衰减速率,防止学习率过低而导致模型停止学习。
11. epochs
- 类型:
int
(默认值为 5)- 说明: 训练的总迭代次数。也就是语料库被训练的次数。
- 用途: 增加
epochs
值可以让模型进行更多的训练,从而提升训练效果,但同时也会增加计算开销。
12. workers
- 类型:
int
(默认值为 3)- 说明: 训练时使用的线程数。
- 用途: 设置为更高的值(如 4 或 8)可以加速训练,尤其是在多核 CPU 上。
13. cbow_mean
- 类型:
{0, 1}
(默认值为 1)- 说明: 只有在使用 CBOW 模型时(
sg=0
)有效。它决定了如何聚合上下文词向量。
cbow_mean=1
:使用上下文词向量的平均值。cbow_mean=0
:使用上下文词向量的和。- 用途: 这个参数影响训练的速度和模型的效果。
14. sample
- 类型:
float
(默认值为 1e-3)- 说明: 控制高频词的下采样阈值。频率大于此值的词汇会被随机下采样。
- 用途: 通过对高频词进行下采样来减少训练时的计算负担,避免模型过于关注高频词而忽略了低频词。
15. max_vocab_size
- 类型:
int
(默认值为None
)- 说明: 控制词汇表的大小。当词汇量大于该值时,将对低频词进行剪枝。
- 用途: 在处理极其庞大的语料库时,使用这个参数可以节省内存并加速训练过程。