当前位置: 首页 > article >正文

【NLP】daydayup 词向量训练模型word2vec

词嵌入算法 word2vec

word2vec是一种高效训练词向量的模型,基本出发点是上下文相似的两个词。它们的词向量也应该相似。一般分为CBOW(Continuous Bag-of-Words)与 Skip-Gram

  • CBOW 词袋模型,使用中心词周围的词来预测中心词,中心词是目标,周围词是输入
  • Skip-gram 根据中心词来预测周围词,中心词是输入,周围词是目标
  • 左图为CBOW 右图是Skip-gram

在这里插入图片描述

CBOW模型

连续词袋模型,根据上下文来预测目标单词的模型。使用上下文各词的词向量的均值作为拼接起来的词向量。

对小型的数据比较合适

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

# 定义数据类型为浮点数
dtype = torch.FloatTensor 

# 语料库,包含训练模型的句子
sentences = ["i like dog", "i like cat", "i like animal",
             "dog cat animal", "apple cat dog like", "cat like fish",
             "dog like meat", "i like apple", "i hate apple",
             "i like movie book music apple", "dog like bark", "dog friend cat"]

# 将所有句子拼接为一个字符串并按空格分词
word_sequence = ' '.join(sentences).split()
# 获取词汇表中的所有唯一词
word_list = list(set(word_sequence))
# 创建词典,词汇表中的每个词都分配一个唯一的索引
word_dict = {w: i for i, w in enumerate(word_list)}

# 创建跳字模型的训练数据
cow = []  # 训练数据
for i in range(1, len(word_sequence) - 1):
    # 获取两个上下文词对应的id
    context = [word_dict[word_sequence[i - 1]], word_dict[word_sequence[i + 1]]]
    # 当前词对应的id
    target = word_dict[word_sequence[i]]

    # 将目标词与上下文词配对,添加到训练数据中
    cow.append([context,target])
# print(cow)
# 定义嵌入维度(嵌入向量的大小)为2
embedding_size = 2
# 每次训练的批量大小
batch_size = 5
voc_size = len(word_list)

# 定义CBOW模型
class CBOW(nn.Module):
    def __init__(self):
        super(CBOW, self).__init__()
        # 定义词嵌入矩阵W,随机初始化,大小为(voc_size, embedding_size)
        self.embed = nn.Embedding(voc_size,embedding_size)
        self.l = nn.Linear(embedding_size,voc_size)

    # 前向传播
    def forward(self, x):
        x = self.embed(x)
        x = torch.mean(x,dim=1) # 自动降维
        x = self.l(x)
        return x

# 创建模型实例
model = CBOW()

# 定义损失函数为交叉熵损失
criterion = nn.CrossEntropyLoss()
# 使用Adam优化器
optimizer = optim.Adam(model.parameters(), lr=0.001)


# 定义随机批量生成函数
def random_batch(data, size):
    random_inputs = []  # 输入批次
    random_labels = []  # 标签批次
    # 从数据中随机选择size个索引
    random_index = np.random.choice(range(len(data)), size, replace=False)

    # 根据随机索引生成输入和标签批次
    for i in random_index:
        random_inputs.append(data[i][0])
        random_labels.append(data[i][1])

    return random_inputs, random_labels

# 训练模型
for epoch in range(10000):
    # 获取随机的输入和目标
    inputs, labels = random_batch(cow, batch_size)

    #转为张量
    input_batch = torch.LongTensor(inputs)
    label_batch = torch.LongTensor(labels)

    optimizer.zero_grad() # 梯度清零
    output = model(input_batch)
    # 计算损失函数
    loss = criterion(output, label_batch.view(-1))

    if (epoch + 1) % 1000 == 0:
        print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))

    loss.backward() # 反向传播
    optimizer.step() # 参数更新

#可视化词嵌入
for i, label in enumerate(word_list):
    W = model.embed.weight.data.numpy()
    x,y = float(W[i][0]),float(W[i][1])
    plt.scatter(x, y) #  绘制散点图
    plt.annotate(label, xy=(x, y), xytext=(5, 2), textcoords='offset points', ha='right', va='bottom')

plt.show()

在这里插入图片描述

在这里插入图片描述

skip-grams

根据目标单词预测上下文单词的模型

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

# 语料库,包含训练模型的句子
sentences = ["i like dog", "i like cat", "i like animal",
             "dog cat animal", "apple cat dog like", "cat like fish",
             "dog like meat", "i like apple", "i hate apple",
             "i like movie book music apple", "dog like bark", "dog friend cat"]

# 构建词表
word_sentences = ' '.join(sentences).split()
word_list = list(set(word_sentences))
word_index = {w: i for i, w in enumerate(word_list)}
index_word = {i: w for i, w in enumerate(word_list)}
vocab_size = len(word_list)

# print(word_index)

# 创建词表
skip_grams = []
for i in range(1, len(word_sentences) - 1):
    # 当前词的id
    input_word = word_index[word_sentences[i]]

    # 获得上下文
    context = [word_index[word_sentences[i - 1]], word_index[word_sentences[i + 1]]]
    for w in context:
        # 当前词和上下文词组合形成的skip-gram数据集
        skip_grams.append([input_word, w])

# 定义超参数
# 词嵌入维度
emb_dim = 2
bach_size = 5
vocab_size = len(word_list)


# skip-gram 模型
class Word2Vec(nn.Module):
    def __init__(self):
        super().__init__()
        self.w1 = nn.Parameter(torch.rand(vocab_size, emb_dim).type(torch.FloatTensor))
        self.w2 = nn.Parameter(torch.rand(emb_dim, vocab_size).type(torch.FloatTensor))

    def forward(self, x):
        x = torch.matmul(x, self.w1)
        x = torch.matmul(x, self.w2)
        return x


# 模型训练
model = Word2Vec()

# 损失函数
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)


def random_bath(data, size):
    label_list = []
    input_list = []

    random_index = np.random.choice(range(len(data)), size, replace=False)

    # 随机索引生成输入和标签批次
    for i in random_index:
        # 目标词one-hot 编码
        input_list.append((np.eye(vocab_size)[data[i][0]]))

        # 上下文
        label_list.append((data[i][1]))
    return input_list, label_list


for epoch in range(10000):
    # 获得数据
    inputs, labels = random_bath(skip_grams, bach_size)

    # 转换为张量
    input_bach = torch.Tensor(inputs)
    label_bach = torch.LongTensor(labels)

    optimizer.zero_grad()
    out = model(input_bach)

    loss = criterion(out, label_bach)

    if (epoch + 1) % 1000 == 0:
        print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))

    loss.backward()
    optimizer.step()

#可视化词嵌入
for i, label in enumerate(word_list):
    W, WT = model.parameters()  # 获取模型参数
    x, y = float(W[i][0]), float(W[i][1])
    plt.scatter(x, y)  # 绘制散点图
    plt.annotate(label, xy=(x, y), xytext=(5, 2), textcoords='offset points', ha='right', va='bottom')

plt.show()

在这里插入图片描述

在这里插入图片描述

使用API调用

Gensim(generate similarity)是一个简单高效的自然语言处理Python库,用于抽取文档的语义主题(semantic topics)。Gensim的输入是原始的、无结构的数字文本(纯文本),内置的算法包括Word2Vec,FastText,潜在语义分析(Latent Semantic Analysis,LSA),潜在狄利克雷分布(Latent Dirichlet Allocation,LDA)等,通过计算训练语料中的统计共现模式自动发现文档的语义结构。这些算法都是非监督的,这意味着不需要人工输入——仅仅需要一组纯文本语料。一旦发现这些统计模式后,任何纯文本(句子、短语、单词)就能采用语义表示简洁地表达。
model.wv: 这个对象包含了所有单词的词嵌入向量。常用的方法有:

  • model.wv[word]:返回某个特定单词的向量。
  • model.wv.most_similar(word):获取与某个单词最相似的词。
  • model.wv.similarity(word1, word2):计算两个词之间的相似度。
import numpy as np
import matplotlib.pyplot as plt
from gensim.models import Word2Vec

sentences = "Word embedding is the collective name for a set of language modeling and feature learning techniques in natural language processing (NLP) where words or phrases from the vocabulary are mapped to vectors of real numbers."

# 每个句子分成单词表
token_list = [sentences.split()]  # 增加一个维度
print(token_list)

# 定义模型
model = Word2Vec(token_list, vector_size=2,window=1,min_count=0)
# 参数  语料库列表  size 词向量的维度  window窗口大小  最小出现次数、

# 获取词汇表   model.wv  映射矩阵 的对象
word_list = list(model.wv.index_to_key)
print(word_list)

# 可视化
# 设置matplotlib支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号
#可视化词嵌入
for i, word in enumerate(word_list):
    W = model.wv[word]
    x,y = float(W[0]),float(W[1])
    plt.scatter(x, y) #  绘制散点图
    plt.annotate(word, xy=(x, y), xytext=(5, 2), textcoords='offset points', ha='right', va='bottom')

word_vector = [model.wv[word] for word in word_list]
sen_vector = np.mean(word_vector,axis=0)
print('句向量',sen_vector)

# 可视化
plt.scatter(sen_vector[0],sen_vector[1])
plt.annotate('句向量', xy=(sen_vector[0],sen_vector[1]), xytext=(5, 2), textcoords='offset points', ha='right', va='bottom')

plt.show()

在这里插入图片描述

在这里插入图片描述

参考博客:

Gensim简介-CSDN博客


http://www.kler.cn/news/323386.html

相关文章:

  • Maven中 <parent > 的<version>可以使用变量吗
  • Unity3D入门(四) : Android和Unity3D交互 - Unity调用Android
  • FreeRTOS 内存管理源码解析
  • 数据结构:线性表的链式表示
  • 中国农业银行——开源软件一体化管理平台
  • 《AI办公类工具表格处理系列之一——办公小浣熊》
  • 逃离陷阱:如何巧妙避免机器学习中的过拟合与欠拟合
  • 【分布式微服务云原生】K8s(Kubernetes)基本概念和使用方法
  • 项目实战总结-Kafka实战应用核心要点
  • NET 7 AOT 的使用以及+NET 与 Go 互相调用
  • C#中的排除法解决问题
  • 基于Java的停车场管理微信小程序 停车场预约系统【源码+文档+讲解】
  • HalconDotNet实现二维码识别功能详解
  • ArcGIS Desktop使用入门(三)常用工具条——拓扑(上篇:地图拓扑)
  • 过去8年,编程语言的流行度发生了哪些变化?PHP下降,Objective-C已过时
  • Vue.js 与 Flask/Django 后端配合开发实战
  • 【Matlab使用Transformer一维序列分类源程序】
  • 0基础学前端 day5
  • 基于SSM+小程序的在线课堂微信管理系统(在线课堂1)(源码+sql脚本+视频导入教程+文档)
  • Android常用C++特性之std::none_of
  • 【数据结构和算法实践-排序-快速排序】
  • 使用canvas截取web camera指定区域,并生成图片
  • 数据结构之——栈
  • 【Kubernetes】常见面试题汇总(四十)
  • EasyExcel 多个不同对象集合,导入同一个sheet中
  • gMLP:Pay Attention to MLPs--模型代码讲解
  • 数字通云平台智慧政务 login 存在登录绕过
  • Java | Leetcode Java题解之第435题无重叠区间
  • E9OA解决文档附件没有关联文档正文问题
  • 54K55LyB5p2l5a6i5pyN57O757uf token硬编码漏洞