Word2Vec基本实践

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 系列文章目录
  • 前言
  • 一、使用SkipGram 模型
    • 1. 构建实验语料库
    • 2. 生成Skip-Gram训练数据
    • 3. 对Skip-Gram数据进行One-Hot编码
    • 4. 定义Skip-Gram模型
    • 5. 训练Skip-Gram模型
    • 6. 输出Skip-Gram词向量
  • 二、使用CBOW 模型
    • 1. 构建实验语料库
    • 2. 生成CBOW训练数据
    • 3. CBOW数据进行One-Hot编码
    • 4. 定义CBOW模型
    • 5. 训练CBOW模型
    • 6. 输出CBOW词向量


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、使用SkipGram 模型

1. 构建实验语料库

# 定义一个句子列表,后面会用这些句子来训练CBOW和Skip-Gram模型
sentences = ["Kage is Teacher", "Mazong is Boss", "Niuzong is Boss",
             "Xiaobing is Student", "Xiaoxue is Student",]
# 将所有句子连接在一起,然后用空格分隔成词汇
words = ' '.join(sentences).split()
# 构建词汇表,去除重复的词
word_list = list(set(words))
# 创建一个字典,将每个词汇映射到一个唯一的索引
word_to_idx = {word: idx for idx, word in enumerate(word_list)}
# 创建一个字典,将每个索引映射到对应的词汇
idx_to_word = {idx: word for idx, word in enumerate(word_list)}
voc_size = len(word_list) # 计算词汇表的大小
print("词汇表:", word_list) # 输出词汇表
print("词汇到索引的字典:", word_to_idx) # 输出词汇到索引的字典
print("索引到词汇的字典:", idx_to_word) # 输出索引到词汇的字典
print("词汇表大小:", voc_size) # 输出词汇表大小

2. 生成Skip-Gram训练数据

# 生成Skip-Gram训练数据
def create_skipgram_dataset(sentences, window_size=2):
    data = []
    for sentence in sentences:
        sentence = sentence.split()  # 将句子分割成单词列表
        for idx, word in enumerate(sentence):  # 遍历单词及其索引
            # 获取相邻的单词,将当前单词前后各N个单词作为相邻单词
            for neighbor in sentence[max(idx - window_size, 0): 
                        min(idx + window_size + 1, len(sentence))]:
                if neighbor != word:  # 排除当前单词本身
                    # 将相邻单词与当前单词作为一组训练数据
                    data.append((neighbor, word))
    return data
# 使用函数创建Skip-Gram训练数据
skipgram_data = create_skipgram_dataset(sentences)
# 打印未编码的Skip-Gram数据样例
print("Skip-Gram数据样例(未编码):", skipgram_data)

3. 对Skip-Gram数据进行One-Hot编码

# 定义One-Hot编码函数
import torch # 导入torch库
def one_hot_encoding(word, word_to_idx):
    # 创建一个全为0的张量,长度与词汇表大小相同
    tensor = torch.zeros(len(word_to_idx))  
    tensor[word_to_idx[word]] = 1  # 将对应词汇的索引位置置为1
    return tensor  # 返回生成的One-Hot向量

# 展示One-Hot编码前后的数据
word_example = "Teacher"
print("One-Hot编码前的单词:", word_example)
print("One-Hot编码后的向量:", one_hot_encoding(word_example, word_to_idx))

# 展示编码后的Skip-Gram数据样例
print("Skip-Gram数据样例(已编码):", [(one_hot_encoding(context, word_to_idx), 
          word_to_idx[target]) for context, target in skipgram_data[:3]])

4. 定义Skip-Gram模型

# 定义Skip-Gram模型
import torch.nn as nn # 导入neural network
class SkipGram(nn.Module):
    def __init__(self, voc_size, embedding_size):
        super(SkipGram, self).__init__()
        # 从词汇表大小到嵌入大小的线性层(权重矩阵)
        self.input_to_hidden = nn.Linear(voc_size, embedding_size, bias=False)  
        # 从嵌入大小到词汇表大小的线性层(权重矩阵)
        self.hidden_to_output = nn.Linear(embedding_size, voc_size, bias=False)  

    def forward(self, X): # X : [batch_size, voc_size]        
         # 生成隐藏层:[batch_size, embedding_size]
        hidden_layer = self.input_to_hidden(X) 
        # 生成输出层:[batch_size, voc_size]
        output_layer = self.hidden_to_output(hidden_layer)  
        return output_layer
    
embedding_size = 2 # 设定嵌入层的大小,这里选择2是为了方便展示
skipgram_model = SkipGram(voc_size,embedding_size)  # 实例化SkipGram模型
print("Skip-Gram模型:", skipgram_model)


##建立skipgram模型--使用nn.embedding层替代线性层

import torch.nn as nn
class SkipGram(nn.Module):
    def __init__(self,voc_size,embeding_size):
        super(SkipGram,self).__init__()
        self.input_to_hidden=nn.Embedding(voc_size,embeding_size)
        self.hidden_to_output=nn.Linear(embeding_size,voc_size,bias=False)
        
    def forward(self,X):
        hidden_layer=self.input_to_hidden(X)
        output_layer=self.hidden_to_output(hidden_layer)
        
        return output_layer
        
voc_size=len(words_list)
skipgram_model=SkipGram(voc_size,embeding_size=2)

5. 训练Skip-Gram模型

# 训练Skip-Gram模型
learning_rate = 0.001 # 设置学习速率
epochs = 1000 # 设置训练轮次
criterion = nn.CrossEntropyLoss()  # 定义交叉熵损失函数
import torch.optim as optim # 导入随机梯度下降优化器
optimizer = optim.SGD(skipgram_model.parameters(), lr=learning_rate)  

# 开始训练循环
loss_values = []  # 用于存储每轮的平均损失值
for epoch in range(epochs):
    loss_sum = 0 # 初始化损失值
    for context, target in skipgram_data:        
        X = one_hot_encoding(target, word_to_idx).float().unsqueeze(0) # 将中心词转换为One-Hot向量   
        y_true = torch.tensor([word_to_idx[context]], dtype=torch.long) # 将周围词转换为索引值   
        y_pred = skipgram_model(X)  # 计算预测值
        loss = criterion(y_pred, y_true)  # 计算损失
        loss_sum += loss.item() # 累积损失
        optimizer.zero_grad()  # 清空梯度
        loss.backward()  # 反向传播
        optimizer.step()  # 更新参数
    if (epoch+1) % 100 == 0: # 输出每100轮的损失,并记录损失
        print(f"Epoch: {epoch+1}, Loss: {loss_sum/len(skipgram_data)}")  
        loss_values.append(loss_sum / len(skipgram_data))

# 绘制训练损失曲线
import matplotlib.pyplot as plt # 导入matplotlib
plt.plot(range(1, epochs//100 + 1), loss_values) # 绘图
plt.title('Training Loss') # 图题
plt.xlabel('Epochs') # X轴Label
plt.ylabel('Loss') # Y轴Label
plt.show() # 显示图

6. 输出Skip-Gram词向量

# 输出Skip-Gram习得的词嵌入
print("\nSkip-Gram词嵌入:")
for word, idx in word_to_idx.items(): # 输出每个单词的嵌入向量
    print(f"{word}: \
    {skipgram_model.input_to_hidden.weight[:, idx].detach().numpy()}")  


plt.rcParams["font.family"]=['SimHei'] # 用来设定字体样式
plt.rcParams['font.sans-serif']=['SimHei'] # 用来设定无衬线字体样式
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
# 绘制二维词向量图
fig, ax = plt.subplots() 
for word, idx in word_to_idx.items():
    vec = skipgram_model.input_to_hidden.weight[:, \
            idx].detach().numpy() # 获取每个单词的嵌入向量
    ax.scatter(vec[0], vec[1]) # 在图中绘制嵌入向量的点
    ax.annotate(word, (vec[0], vec[1]), fontsize=12) # 点旁添加单词标签
plt.title('2维词嵌入') # 图题
plt.xlabel('向量维度1') # X轴Label
plt.ylabel('向量维度2') # Y轴Label
plt.show() # 显示图

二、使用CBOW 模型

1. 构建实验语料库

# 定义一个句子列表,后面会用这些句子来训练CBOW和CBOW模型
sentences = ["Kage is Teacher", "Mazong is Boss", "Niuzong is Boss",
             "Xiaobing is Student", "Xiaoxue is Student",]
# 将所有句子连接在一起,然后用空格分隔成词汇
words = ' '.join(sentences).split()
# 构建词汇表,去除重复的词
word_list = list(set(words))
# 创建一个字典,将每个词汇映射到一个唯一的索引
word_to_idx = {word: idx for idx, word in enumerate(word_list)}
# 创建一个字典,将每个索引映射到对应的词汇
idx_to_word = {idx: word for idx, word in enumerate(word_list)}
voc_size = len(word_list) # 计算词汇表的大小
print("词汇表:", word_list) # 输出词汇表
print("词汇到索引的字典:", word_to_idx) # 输出词汇到索引的字典
print("索引到词汇的字典:", idx_to_word) # 输出索引到词汇的字典
print("词汇表大小:", voc_size) # 输出词汇表大小

2. 生成CBOW训练数据

# 生成CBOW训练数据
def create_cbow_dataset(sentences, window_size=2):
    data = []
    for sentence in sentences:
        sentence = sentence.split()  # 将句子分割成单词列表
        for idx, word in enumerate(sentence):  # 遍历单词及其索引
            # 获取上下文词汇,将当前单词前后各window_size个单词作为上下文词汇
            context_words = sentence[max(idx - window_size, 0):idx] \
                + sentence[idx + 1:min(idx + window_size + 1, len(sentence))]
            # 将当前单词与上下文词汇作为一组训练数据
            data.append((word, context_words))
    return data

# 使用函数创建CBOW训练数据
cbow_data = create_cbow_dataset(sentences)
# 打印未编码的CBOW数据样例(前三个)
print("CBOW数据样例(未编码):", cbow_data[:3])

3. CBOW数据进行One-Hot编码

# 定义One-Hot编码函数
import torch # 导入torch库
def one_hot_encoding(word, word_to_idx):
    # 创建一个全为0的张量,长度与词汇表大小相同
    tensor = torch.zeros(len(word_to_idx))  
    tensor[word_to_idx[word]] = 1  # 将对应词汇的索引位置置为1
    return tensor  # 返回生成的One-Hot向量

# 展示One-Hot编码前后的数据
word_example = "Teacher"
print("One-Hot编码前的单词:", word_example)
print("One-Hot编码后的向量:", one_hot_encoding(word_example, word_to_idx))

# 展示编码后的CBOW数据样例
# 展示编码后的CBOW数据样例
print("CBOW数据样例(已编码):", [(one_hot_encoding(target, word_to_idx), 
                          [one_hot_encoding(context, word_to_idx) for context in context_words]) 
                         for target, context_words in cbow_data[:3]])

4. 定义CBOW模型

# 定义CBOW模型
import torch.nn as nn # 导入neural network# 定义CBOW模型
class CBOW(nn.Module):
    def __init__(self, voc_size, embedding_size):
        super(CBOW, self).__init__()
        # 从词汇表大小到嵌入大小的线性层(权重矩阵)
        self.input_to_hidden = nn.Linear(voc_size, 
                                         embedding_size, bias=False)  
        # 从嵌入大小到词汇表大小的线性层(权重矩阵)
        self.hidden_to_output = nn.Linear(embedding_size, 
                                          voc_size, bias=False)  

    def forward(self, X): # X: [num_context_words, voc_size]
        
        # 生成嵌入:[num_context_words, embedding_size]
        embeddings = self.input_to_hidden(X)  
        # 计算隐藏层,求嵌入的均值:[embedding_size]
        hidden_layer = torch.mean(embeddings, dim=0)  
        # 生成输出层:[1, voc_size]
        output_layer = self.hidden_to_output(hidden_layer.unsqueeze(0)) 
        return output_layer
    
embedding_size = 2 # 设定嵌入层的大小,这里选择2是为了方便展示
cbow_model = CBOW(voc_size,embedding_size)  # 实例化cbow模型
print("CBOW模型:", cbow_model)

5. 训练CBOW模型

# 训练CBOW模型
learning_rate = 0.001 # 设置学习速率
epochs = 1000 # 设置训练轮次
criterion = nn.CrossEntropyLoss()  # 定义交叉熵损失函数
import torch.optim as optim # 导入随机梯度下降优化器
optimizer = optim.SGD(cbow_model.parameters(), lr=learning_rate)  

# 开始训练循环
loss_values = []  # 用于存储每轮的平均损失值
for epoch in range(epochs):
    loss_sum = 0
    for target, context_words in cbow_data:
        # 将上下文词转换为One-hot向量并堆叠
        X = torch.stack([one_hot_encoding(word, word_to_idx) for word in context_words]).float() 
        y_true = torch.tensor([word_to_idx[target]], dtype=torch.long)  # 将目标词转换为索引值
        y_pred = cbow_model(X)  # 计算预测值
        loss = criterion(y_pred, y_true)  # 计算损失
        loss_sum += loss.item()
        optimizer.zero_grad()  # 清空梯度
        loss.backward()  # 反向传播
        optimizer.step()  # 更新参数
        
    if (epoch+1) % 100 == 0: # 输出每100轮的损失,并记录损失
        print(f"Epoch: {epoch+1}, Loss: {loss_sum/len(cbow_data)}")  
        loss_values.append(loss_sum / len(cbow_data))
# 绘制训练损失曲线
import matplotlib.pyplot as plt # 导入matplotlib
plt.plot(range(1, epochs//100 + 1), loss_values) # 绘图
plt.title('Training Loss') # 图题
plt.xlabel('Epochs') # X轴Label
plt.ylabel('Loss') # Y轴Label
plt.show() # 显示图

6. 输出CBOW词向量

# 输出CBOW习得的词嵌入
print("\nCBOW词嵌入:")
for word, idx in word_to_idx.items(): # 输出每个单词的嵌入向量
    print(f"{word}: \
    {cbow_model.input_to_hidden.weight[:, idx].detach().numpy()}")  
plt.rcParams["font.family"]=['SimHei'] # 用来设定字体样式
plt.rcParams['font.sans-serif']=['SimHei'] # 用来设定无衬线字体样式
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
# 绘制二维词向量图
fig, ax = plt.subplots() 
for word, idx in word_to_idx.items():
    vec = cbow_model.input_to_hidden.weight[:, \
            idx].detach().numpy() # 获取每个单词的嵌入向量
    ax.scatter(vec[0], vec[1]) # 在图中绘制嵌入向量的点
    ax.annotate(word, (vec[0], vec[1]), fontsize=12) # 点旁添加单词标签
plt.title('2维词嵌入') # 图题
plt.xlabel('向量维度1') # X轴Label
plt.ylabel('向量维度2') # Y轴Label
plt.show() # 显示图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/725660.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

西木科技Westwood-Robotics人型机器人Bruce配置和真机配置

西木科技Westwood-Robotics人型机器人Bruce配置和真机配置 本文内容机器人介绍Bruce机器人Gazebo中仿真代码部署Bruce真机代码部署 本文内容 人形机器人Brcue相关介绍docker中安装Gazebo并使用Bruce机器人控制器更换环境配置 机器人介绍 公司:西木科技Westwood-R…

企业UDP文件传输工具测速的方式(下)

在前一篇文章中,我们深入讨论了UDP传输的基本概念和镭速UDP文件传输工具如何使用命令行快速进行速度测试。现在,让我们进一步探索更为高级和灵活的方法,即通过整合镭速UDP的动态或静态库来实现网络速度的测量,以及如何利用这一过程…

CVPR24最佳论文 | 谷歌:生成图像动力学

原文:Generative Image Dynamics 地址:https://generative-dynamics.github.io/ 代码:未知 出版:CVPR 2024 机构: 谷歌 1 研究问题 本文研究的核心问题是: 如何从单张静止图片生成逼真的长时间动态视频,同时支持用…

Socket 原理和思考

众所周知Reactor是一种非常重要和应用广泛的网络编程模式,而Java NIO是Reactor模式的一个具体实现,在Netty和Redis都有对其的运用。而不管上层模式如何,底层都是走的Socket,对底层原理的了解会反哺于上层,避免空中楼阁…

【数学建模】解析几何与方程模型

文章目录 解析几何与方程模型1.几何建模思想2.Numpy在线性代数中的使用3.国赛求解3.1题目3.2 问题1求解建立模型代码求解 3.3 问题2求解 4.问题答疑Q1:什么是行列式,其使用场景是什么行列式的定义行列式的性质行列式的使用场景 Q2:2023B题问题一用相似三角形求解覆盖…

htb_Editorial

hack the book Editorial 端口扫描 80 22 目录扫描 /upload 是一个上传book information的页面 其中最顶上有一个可以上传书本封面的地方,可以从本地上传,也可以从远程下载 这里可能涉及ssrf和本地文件上传,逐一尝试 随便上传一个图片…

使用高斯混合模型(GMM)进行猫狗音频聚类(Kaggle Audio Cats and Dogs)

Audio Cats and Dogs | Kaggle 目录 一、实验目标 二、数据分析 三、实验结果 四、改进方向 一、实验目标 数据集包括164个标注为猫的.wav文件,总共1323秒和113个标注为狗叫声的.wav文件,总共598秒,要求判别每个音频是狗叫还是猫叫 二、…

Spark SQL函数详解:案例解析(第8天)

系列文章目录 1- Spark SQL函数定义(掌握) 2- Spark 原生自定义UDF函数案例解析(掌握) 3- Pandas自定义函数案例解析(熟悉) 4- Apache Arrow框架案例解析(熟悉) 5- spark常见面试题…

Centos 配置安装Mysql

linux安装配置mysql的方法主要有yum安装和配置安装两种,由于yum安装比较简单,但是会将文件分散到不同的目录结构下面,配置起来比较麻烦,这里主要研究一下配置安装mysql的方法 1、环境说明 centos 7.9 mysql 5.7.372、环境检查 …

ChatGPT Plus GPT-4o Claude 3 Opus合租拼车全新方式

无需自己搭建,登录即可用,国内直连访问,聚合多家最强大模型,随意选择使用。立即体验 datapipe.top 支持 OpenAI 最新 GPT-4o ,获得快速高质量的对话,保证可用配额。支持多种大模型,GPT-4o &…

SerialChart上位机使用详解

SerialChart 上位机 软件分为三个区域:接收数据区,用于显示串口接收的数据。参数配置区,用于配置串口参数和显示参数。波形显示区,显示串口数据的波形。 在参数配置区写入串口号,波特率,通道波形颜色等&am…

高压电阻器支持牙科 X 射线成像的准确性

为了捕获患者牙齿和颌骨的足够图像,牙医依靠锥形束计算机断层扫描 (CBCT) 系统的先进 3D 成像。CBCT系统的输出对于准确诊断口腔健康问题和随后的治疗计划至关重要。为了确保这些图像的可靠性,CBCT系统制造商利用了Exxelia Ohmcra…

Jenkins+K8s实现持续集成(一)

镜像仓库的搭建 docker run -d \--restartalways \--name registry \-p 5000:5000 \-v /root/devops/registry/data:/var/lib/registry \registry安装完之后,执行下面命令可以看到镜像仓库已经安装成功 docker ps 然后在浏览器上输入下面地址进行访问 http://ip:…

一键简易桌签(带背景)-Word插件-大珩助手

问题整理: 如何Word中设计简易桌签?如何设置带背景图的桌签? Word大珩助手是一款功能丰富的Office Word插件,旨在提高用户在处理文档时的效率。它具有多种实用的功能,能够帮助用户轻松修改、优化和管理Word文件&…

Python酷库之旅-比翼双飞情侣库(17)

目录 一、xlwt库的由来 1、背景和需求 2、项目启动 3、功能特点 4、版本兼容性 5、与其他库的关系 6、示例和应用 7、发展历史 二、xlwt库优缺点 1、优点 1-1、简单易用 1-2、功能丰富 1-3、兼容旧版Excel 1-4、社区支持 1-5、稳定性 2、缺点 2-1、不支持.xls…

LVGL开发教程-Flex(弹性布局)

系列文章目录 知不足而奋进 望远山而前行 目录 系列文章目录 文章目录 前言 1.常用方法 2.代码实现 3.对齐方式 4.控件特殊的size 总结 前言 Flexbox布局在现代界面设计中扮演着重要角色,特别是在响应式和动态布局方面。LVGL(LittlevGL&#x…

Dockerfile封装制作pytorch(tensorflow)深度学习框架 + jupyterlab服务 + ssh服务镜像

一:docker-hub官网寻找需求镜像 1.我们在https://hub.docker.com/官网找到要封装的pytorch基础镜像,这里我们以pytorch1.13.1版本为例 2.我们找到的这个devel版本的镜像(我们需要cuda的编译工具) pytorch版本是1.13.1,…

气体泄露隐患多,佛山工业可燃气体报警器年检校准来帮忙

在佛山这座工业发达的城市,可燃气体报警器的应用日益广泛,涉及化工、冶金、石油等多个领域。 然而,长时间的使用和恶劣的工业环境可能导致报警器的性能下降,甚至出现误报或漏报的情况。 因此,定期对可燃气体报警器进…

OPenCV实现把人形轮廓画在实时视频画面中

操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:Visual Studio Code编程语言:C11 1.功能描述 当你从摄像头读取实时视频时,如果想在视频的画面中画一个方框,或者是画一个圆,是很简单的事情,可是…

VMR,支持30+种编程语言的SDK版本管理器,支持Windows/MacOS/Linux。

官方文档地址:documents 官方项目地址:github 欢迎安装使用,分享转发,前往github star。 跨平台,支持Windows,Linux,MacOS支持多种语言和工具,省心受到lazygit的启发,拥…