Word2Vec:将词汇转化为向量的技术

news2025/2/25 6:03:36

文章目录

  • Word2Vec
    • 来龙去脉
      • 分层Softmax
      • 负采样


Word2Vec

下面的文章纯属笔记,看完后不会有任何收获,如果想理解这两种优化技术,给大家推荐一篇博客,讲的很好:
详解-----分层Softmax与负采样


来龙去脉

word2vec,即将词语转换为向量。在机器学习或自然语言任务中,我们需要对句子进行翻译或者根据某些词生成另一些词,这些任务现在大多数都可以用神经网络来做。比如在句子翻译任务中,我们给神经网络输入该句子,那么想要的输出就是该句子的翻译版本。但是由于计算机只接受数字形式的输入,所以我们要将词语转化为数字形式。
word2vec就是将词语转换为数字向量的技术,经过该方法训练之后,我们就可以得到每一个词的固定向量表示,使得意思相近的词在向量空间中距离较近,不相关的词在向量空间中距离较远。
word2vec有两种经典的方法来进行训练,从而得到词的向量表示,一种叫做CBOW(连续词袋模型),一种叫skip-gram(跳元模型)。
CBOW的核心想法是通过一个词周围的词,预测该词,类似于完形填空。
skip-gram的核心想法是通过预测该词周围的词,相当于根据一个词造句子。
在用神经网络训练者两种模型的时候,我们输出层的个数就是我们所有词语的个数,需要经过一个softmax才能得到预测的每一个词的概率,这会导致指数运算次数非常多,导致对计算资源的要求很高。
基于这个问题,提出了两种优化方案,一种叫分层softmax,一种叫负采样。本章重点介绍这两种技术。

分层Softmax

在这里插入图片描述

这张图就说明了分层softmax的核心流程,我们以CBOW为例,在得到每一个周围词的词嵌入表示后,对其进行加权平均,就得到了图中的h,然后构建Huffman树(基于每一个词出现的频率构建),得到Huffman树之后,每一个叶子节点就表示了词汇表中的一个词,现在为每一个非叶子节点赋予一个可训练参数,然后将h与每一个非叶子节点的参数相乘,经过一个sigmoid得到一个0-1的值,在计算一个词的概率的时候,将路径上所有非叶子节点得到的值相乘,就得到输出该词的概率值,通过二叉树这种设计,保证了最后得到的所有词的概率的和为1。
损失函数的设计用的是二元交叉熵损失。
Huffman树的构建

import heapq
import numpy as np

# 构建Huffman树
class HuffmanTree:
    def __init__(self, vocab, freq):
        self.vocab = vocab
        self.freq = freq
        self.tree = self.build_huffman_tree()

    def build_huffman_tree(self):
        heap = [[weight, [symbol, ""]] for symbol, weight in zip(self.vocab, self.freq)]
        heapq.heapify(heap)

        while len(heap) > 1:
            lo = heapq.heappop(heap)
            hi = heapq.heappop(heap)
            for pair in lo[1:]:
                pair[1] = '0' + pair[1]
            for pair in hi[1:]:
                pair[1] = '1' + pair[1]
            heapq.heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[1:])
        
        return heap[0][1:]

    def get_code(self):
        return {symbol: code for symbol, code in self.tree}

分层softmax代码

def preprocess(text):
	text = text.lower()
	text = text.replace('.', ' .')
	text = text.replace(',', ' ,')
	text = text.replace('!', ' !')
	words = text.split(' ')
	
	word_to_id = {}
	id_to_word = {}
	word_count = {}
	for word in words:
		if word not in word_to_id:
			new_id = len(word_to_id)
			word_to_id[word] = new_id
			id_to_word[new_id] = word
			word_count[new_id] = 1
		else:
			word_count[word_to_id[word]] += 1
			corpus = np.array([word_to_id[w] for w in words])
	
	return corpus, word_to_id, id_to_word, word_count

负采样

在这里插入图片描述
负采样的前置部分和前面一样,它的基本思想是从一个概率分布中选择少数几个负样本参与每一次的训练,一般情况下,我们不是只用正的样本吗?我们将h经过一个网络后,会得到所有词的logits值,注意,此时我们还没有将其softmax,也就避免了大量的指数运算。我们根据所有logits值和给的正样本的标签得到此时正样本的logits值,同理,我们从词汇库里选择几个词作为负样本,经过网络传播后,也会得到几个负样本的logits值,接下来,我们对这几个词(正样本和负样本)做softmax,从而得到正样本的概率和这几个负样本的概率,通过最大化的正样本的概率并且最小化负样本的概率,进而训练网络。
那么这里负样本的个数应该选几个呢?在word2vec原文中,当数据量较大时,通常选用的负例个数为5,当数据量较小时,选5-20个。

负采样代码:

import random
import numpy as np
from collections import Counter

# 示例语料库
corpus = [
    'cat is on the mat',
    'dog is in the house',
    'cat and dog are friends',
    'dog is playing with the ball'
]

# 1. 构建词汇表并计算词频
def build_vocab(corpus):
    words = []
    for sentence in corpus:
        words.extend(sentence.split())
    word_counts = Counter(words)
    vocab = {word: count for word, count in word_counts.items()}
    return vocab

# 计算词频并构建词汇表
vocab = build_vocab(corpus)
vocab_size = len(vocab)
print("词汇表:", vocab)

# 2. 负样本采样
def get_negative_sample(vocab, num_samples=5):
    # 获取词频的平方根,并进行归一化
    word_freq = np.array([count for count in vocab.values()])
    word_freq = word_freq ** 0.75  # 使用0.75的幂次方分布
    word_freq /= word_freq.sum()  # 归一化,使得总和为1

    # 根据权重选择负样本
    negative_samples = np.random.choice(list(vocab.keys()), size=num_samples, p=word_freq)
    return negative_samples

# 测试负采样
negative_samples = get_negative_sample(vocab, num_samples=5)
print("负样本:", negative_samples)

# 3. 简单的训练步骤(Skip-Gram模型)
def train_step(context, target, negative_samples, learning_rate=0.1):
    # 这里只是简单地输出每个样本的训练步骤,实际情况中会根据模型进行参数更新
    print(f"\n上下文词: {context}")
    print(f"目标词: {target}")
    print(f"负样本: {negative_samples}")
    
    # 计算损失和梯度的代码可以根据实际模型来实现
    # 这里只是模拟训练过程
    
    # 示例的损失计算(假设目标词是正样本,负样本是负样本)
    for word in [target] + list(negative_samples):
        if word == target:
            print(f"目标词 {target} 的损失:正样本,最大化概率")
        else:
            print(f"负样本 {word} 的损失:最小化概率")

# 4. 模拟训练过程
def train_model(corpus, vocab, num_epochs=10, num_negative_samples=5, learning_rate=0.1):
    for epoch in range(num_epochs):
        print(f"\nEpoch {epoch + 1}/{num_epochs}")
        
        # 遍历语料库
        for sentence in corpus:
            words = sentence.split()
            
            # 模拟Skip-Gram的训练过程
            for i, target in enumerate(words):
                # 上下文词是目标词附近的其他词
                context = [words[j] for j in range(len(words)) if j != i]
                
                # 从词汇表中选择负样本
                negative_samples = get_negative_sample(vocab, num_samples=num_negative_samples)
                
                # 进行训练步骤
                train_step(context, target, negative_samples, learning_rate)

# 训练模型
train_model(corpus, vocab)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电商商品详情API接口(item get)数据分析上货

电商商品详情API接口(item get)在数据分析与商品上货方面发挥着重要作用。以下是对这两个方面的详细探讨: 一、数据分析 数据源获取: 商品详情API接口提供了丰富的数据源,包括商品的标题、价格、库存、描述、图片、用…

如何将你的 Ruby 应用程序从 OpenSearch 迁移到 Elasticsearch

作者:来自 Elastic Fernando Briano 将 Ruby 代码库从 OpenSearch 客户端迁移到 Elasticsearch 客户端的指南。 OpenSearch Ruby 客户端是从 7.x 版 Elasticsearch Ruby 客户端分叉而来的,因此代码库相对相似。这意味着当将 Ruby 代码库从 OpenSearch 迁…

如何对 Java 项目简化接口设计提升开发效率

文章目录 摘要引言简洁接口设计的原则示例代码OrderProcessor 接口StandardOrderProcessor 实现类Order 数据类调用方代码:OrderService 模块之间的协作QA 环节总结参考资料 摘要 简洁的接口设计可以有效降低代码依赖与耦合度,提高代码的可维护性和扩展…

Python字符串及正则表达式(十):字符串常用操作、字符串编码转换

前言:在编程的世界里,字符串无处不在。它们是构建用户界面、存储数据、进行通信的基础元素。无论是财务系统的总账报表、电子游戏的比赛结果,还是火车站的列车时刻表,这些信息最终都需要以文本的形式呈现给用户。这些文本的背后&a…

JAVA爬虫获取1688关键词接口

以下是使用Java爬虫获取1688关键词接口的详细步骤和示例代码: 一、获取API接口访问权限 要使用1688关键词接口,首先需要获取API的使用权限,并了解接口规范。以下是获取API接口的详细步骤: 注册账号:在1688平台注册一…

【AIGC】与模型对话:理解与预防ChatGPT中的常见误解

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯模型的工作原理和用户期望差异人工智能模型的基本工作原理认知上的局限与误解用户期望与模型实际能力的差距精确理解用户意图的重要性实际应用中的建议 &…

UE5制作倒计时功能

设置画布和文本 文本绑定 格式化时间 转到事件图表,计算时间,时间结束后面的事件可以按自己需求写 进入关卡蓝图,添加倒计时UI

Excel + Notepad + CMD 命令行批量修改文件名

注意:该方式为直接修改原文件的文件名,不会生成新文件 新建Excel文件 A列:固定为 renB列:原文件名称C列:修改后保存的名称B列、C列,需要带文件后缀,为txt文件就是.txt结尾,为png图片…

F5中获取客户端ip地址(client ip)

当F5设备对其原始设置上的所有IP地址使用NAT时,连接到poo成员(nodes、backend servers)的出站连接将是NAT IP地址。 pool 成员(nodes、backend servers)将无法看到真实的客户端 ip地址,因为看到的是F5上的…

什么是网络数据包分析?有什么特点?

网络数据包分析(Packet Analysis),也被称为网络流量分析或抓包分析,是指通过捕获和检查在网络上传输的数据包来监控、诊断和评估网络性能及安全性的一种技术。这项技术可以用来识别网络问题、优化网络性能、检测安全威胁以及了解网…

大数据技术与应用——数据可视化(山东省大数据职称考试)

大数据分析应用-初级 第一部分 基础知识 一、大数据法律法规、政策文件、相关标准 二、计算机基础知识 三、信息化基础知识 四、密码学 五、大数据安全 六、数据库系统 七、数据仓库. 第二部分 专业知识 一、大数据技术与应用 二、大数据分析模型 三、数据科学 数据可视化 大…

window QT/C++ 与 lua交互(mingw + lua + LuaBridge + luasocket)

一、环境与准备工作 测试环境:win10 编译器:mingw QT版本:QT5.12.3 下载三种源码: LuaBridge源码:https://github.com/vinniefalco/LuaBridge LUA源码(本测试用的是5.3.5):https://www.lua.org/download.html luasocket源码:https://github.com/diegonehab/luasocket 目…

Docker在Ubuntu和CentOS系统下的安装

目录 1. 各版本平台支持情况2. 在Ubuntu系统下安装docker3. 常见报错4. Docker的镜像源修改5. Docker目录修改6. 在CentOS系统下安装docker 1. 各版本平台支持情况 (1)平台支持情况如下: Server 版本 桌面版本 2. 在Ubuntu系统下安装docker…

图形化界面MySQL(MySQL)(超级详细)

目录 1.官网地址 1.1在Linux直接点击NO thanks..... 1.2任何远端登录,再把jj数据库给授权 1.3建立新用户 优点和好处 示例代码(MySQL Workbench) 示例代码(phpMyAdmin) 总结 图形化界面 MySQL 工具大全及其功…

IP数据云查询IP归属地信息

互联网时代,我们每天都会面对大量的网站或App,但你们是否知晓,所有程序员进行程序或者系统的开发都离不开查询IP地址,这是由于对于每个安全的网站/软件来说,基础的服务日志,登录IP等就离不开IP归属地离线库&#xff0c…

PH热榜 | 2024-12-17

1. Eden 标语:一键用AI生成网页评论。 介绍:Eden是一款人工智能驱动的社交插件,只需点击表情符号就能在任何网页上评论。它能自动总结网页内容并生成个性化评论。 想调侃朋友、表达喜爱,还是快速评论几句?用Eden&…

Hadoop学习笔记(包括hadoop3.4.0集群安装)(黑马)

Hadoop学习笔记 0-前置章节-环境准备 0.1 环境介绍 配置环境:hadoop-3.4.0,jdk-8u171-linux-x64 0.2 VMware准备Linux虚拟机 0.2.1主机名、IP、SSH免密登录 1.配置固定IP地址(root权限) 开启master,修改主机名为…

ChatGPT Search开放:实时多模态搜索新体验

点击访问 chatTools 免费体验GPT最新模型,包括o1推理模型、GPT4o、Claude、Gemini等模型! ChatGPT Search:功能亮点解析 本次更新的ChatGPT Search带来了多项令人瞩目的功能,使其在搜索引擎市场中更具竞争力。 1. 高级语音模式&…

php基础:正则表达式

1.正则表达式 正则表达式是用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分割、匹配、查找及替换操作。到目前为止,我们前面所用过的精确(文本)匹配也是一种正则表达式。 在PHP中,正则表达式一般是由正规字…

PHP代码审计学习(一)--命令注入

1、漏洞原理 参数用户可控&#xff0c;程序将用户可控的恶意参数通过php可执行命令的函数中运行导致。 2、示例代码 <?php echorec-test; $command ping -c 1 .$_GET[ip]; system($command); //system函数特性 执行结果会自动打印 ?> 通过示例代码可知通过system函…