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

浅谈Word2vec算法模型

Word2vec 是一种基于神经网络的词嵌入(Word Embedding)模型,通过无监督学习将词语映射到低维稠密向量空间,使得语义相近的词语在向量空间中距离相近。模型的核心目标是将语法的语义和语法特征编码为向量形式。
 

1.模型架构

  • CBOW (Continuous Bag-of-Words)

    • 输入:上下文词的向量(如窗口内的周围词)。

    • 输出:预测中心词的概率分布。

    • 适用场景:小规模数据集,高频词效果更好。

  • Skip-gram

    • 输入:中心词的向量。

    • 输出:预测上下文词的概率分布。

    • 适用场景:大规模数据集,低频词效果更好。

2.优化技术

  • 负采样 (Negative Sampling)
    将多分类问题转化为二分类问题,随机采样负样本(非目标词)以降低计算复杂度。

  • 层次 Softmax (Hierarchical Softmax)
    使用哈夫曼树(Huffman Tree)加速概率计算,减少计算量。

3.应用场景

  1. 语义相似度计算

    • 通过余弦相似度比较词向量,如 cos(向量("猫"), 向量("狗"))

  2. 文本分类

    • 将词向量作为特征输入分类模型(如LSTM、CNN)。

  3. 推荐系统

    • 用向量表示用户行为或物品属性,计算相似性。

  4. 机器翻译

    • 跨语言词向量对齐(如中英文词向量映射)。

4.Spark 实现示例

Spark MLlib 内置了 Word2vec 模型,适合分布式大规模数据处理。

from pyspark.sql import SparkSession
from pyspark.ml.feature import Word2Vec

# 初始化 Spark
spark = SparkSession.builder.appName("Word2VecExample").getOrCreate()

# 示例数据(每行为一个分词后的句子)
data = [
    ("cat dog mouse".split(" "),),
    ("dog lion tiger".split(" "),),
    ("mouse cat elephant".split(" "),)
]
df = spark.createDataFrame(data, ["text"])

# 训练 Word2vec 模型
word2vec = Word2Vec(
    vectorSize=100,    # 向量维度
    windowSize=2,      # 上下文窗口大小
    numPartitions=4,   # 并行度
    minCount=1         # 最小词频
)
model = word2vec.fit(df)

# 获取词向量
word_vectors = model.getVectors()
word_vectors.show()

# 查找相似词
similar_words = model.findSynonyms("cat", 2)
similar_words.show()

spark.stop()

5.TensorFlow 实现示例

TensorFlow 提供灵活的低阶 API,可自定义模型结构(以下以 Skip-gram 为例)。

1. 数据预处理

import tensorflow as tf
import numpy as np

# 示例语料库
corpus = "cat dog mouse dog lion tiger mouse cat elephant".split()
vocab = list(set(corpus))
word2idx = {word: idx for idx, word in enumerate(vocab)}
idx2word = {idx: word for idx, word in enumerate(vocab)}

# 生成训练数据(中心词-上下文词对)
window_size = 2
pairs = []
for i in range(window_size, len(corpus)-window_size):
    center = word2idx[corpus[i]]
    context = [word2idx[corpus[j]] for j in range(i-window_size, i+window_size+1) if j != i]
    pairs.extend([(center, ctx) for ctx in context])

# 转换为 TensorFlow Dataset
centers, contexts = zip(*pairs)
dataset = tf.data.Dataset.from_tensor_slices((np.array(centers), np.array(contexts)))
dataset = dataset.shuffle(1000).batch(64)

2. 定义模型(Skip-gram + 负采样)

class Word2Vec(tf.keras.Model):
    def __init__(self, vocab_size, embedding_dim, num_ns=5):
        super().__init__()
        self.target_embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim, name="embedding")
        self.context_embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
        self.num_ns = num_ns  # 负采样数量

    def call(self, center, context):
        # 中心词向量 [batch, dim]
        center_emb = self.target_embedding(center)
        # 上下文词向量 [batch, dim]
        context_emb = self.context_embedding(context)
        # 计算点积相似度 [batch]
        logits = tf.reduce_sum(center_emb * context_emb, axis=1)
        return logits

# 初始化模型
vocab_size = len(vocab)
embedding_dim = 128
model = Word2Vec(vocab_size, embedding_dim)
optimizer = tf.keras.optimizers.Adam()

# 自定义损失函数(带负采样)
def loss_fn(center, context):
    # 正样本对
    positive_logits = model(center, context)
    # 负采样(随机选择非上下文词)
    negative_samples = tf.random.uniform(
        shape=(tf.shape(center)[0], model.num_ns),
        maxval=vocab_size,
        dtype=tf.int64
    )
    negative_logits = tf.reduce_sum(
        model.target_embedding(center) * model.context_embedding(negative_samples),
        axis=1
    )
    # 损失计算
    positive_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(positive_logits), logits=positive_logits)
    negative_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.zeros_like(negative_logits), logits=negative_logits)
    return tf.reduce_mean(positive_loss + negative_loss)

3. 训练模型

# 训练循环
for epoch in range(10):
    total_loss = 0
    for batch_centers, batch_contexts in dataset:
        with tf.GradientTape() as tape:
            loss = loss_fn(batch_centers, batch_contexts)
        gradients = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))
        total_loss += loss.numpy()
    print(f"Epoch {epoch}, Loss: {total_loss:.4f}")

# 获取词向量矩阵
word_vectors = model.target_embedding.weights[0].numpy()
print("Vector for 'cat':", word_vectors[word2idx['cat']])

6.关键点总结

  1. Spark 优势:分布式计算,适合海量数据,但自定义能力有限。

  2. TensorFlow 优势:灵活支持模型调参(如负采样数、向量维度),但需手动实现训练逻辑。

  3. 应用技巧

    • 增大 vectorSize 可提升语义表达能力,但需权衡计算资源。

    • 调整 windowSize 控制上下文范围(小窗口捕捉语法,大窗口捕捉语义)。

  4. 评估方法

    • 直接评估:通过相似词检索(如 findSynonyms)。

    • 间接评估:在下游任务(如文本分类)中测试词向量效果。

http://www.dtcms.com/a/29628.html

相关文章:

  • 【Mastering Vim 2_05】第四章:深入理解 Vim 的结构化文本
  • AI回答:Linux C/C++编程学习路线
  • php重写上传图片成jpg图片
  • Sui 如何支持各种类型的 Web3 游戏
  • UI 自动化测试框架介绍
  • vue项目启动时报错:error:0308010C:digital envelope routines::unsupported
  • 火语言RPA--Excel插入空行
  • SpringCloud-使用FFmpeg对视频压缩处理
  • MyBatis中的日志和映射器说明
  • nvm安装、管理node多版本以及配置环境变量【保姆级教程】
  • 详解分布式ID实践
  • 解决 Ubuntu 中 Docker 安装时“无法找到软件包”错误
  • 现场可以通过手机或者pad实时拍照上传到大屏幕的照片墙现场大屏电子照片墙功能
  • Renesas RH850 IAR编译时变量分配特定内存
  • Python的那些事第二十八篇:数据分析与操作的利器Pandas
  • OpenMetadata Service与Ingestion模块接口交互全解析
  • 【开关电源】汽车前端电源保护电路设计
  • DeepSeek安装部署笔记(一)
  • upload-labs
  • 直播美颜SDK的底层技术解析:图像处理与深度学习的结合
  • 双重差分学习笔记
  • 一文了解大模型性能评测数据、指标以及框架
  • 计算机视觉(CV)
  • DeepSeek 新注意力架构NSA
  • ASP.NET Core 下载文件
  • 如何基于transformers库通过训练Qwen/DeepSeek模型的传统分类能力实现文本分类任务
  • cs106x-lecture13(Autumn 2017)-SPL实现
  • 【Linux网络编程】IP协议格式,解包步骤
  • 模拟实现Java中的计时器
  • C++17中的std::scoped_lock:简化多锁管理的利器