nlp-文本转向量的三种核心技术详解:从One-Hot到Word2Vec

194 阅读8分钟

文本转向量的三种核心技术详解:从One-Hot到Word2Vec

在自然语言处理(NLP)领域,计算机无法直接理解人类语言的文本内容,需要将文本转换为数值向量才能进行处理。文本转向量(Text to Vector)技术是NLP任务的基础,直接影响着后续模型的性能表现。本文将深入解析三种主流的文本向量表示方法:One-Hot编码、Word2Vec和Word Embedding,帮助你全面理解它们的原理、优劣和应用场景。

背景介绍:为什么需要文本向量表示?

在机器学习和深度学习中,模型只能处理数值数据,而不能直接处理文本字符串。因此,我们需要将文本转换为数值向量,这个过程被称为文本向量化或文本表示。好的文本向量表示应该具备以下特点:

  1. 语义相似性:语义相近的词在向量空间中距离较近
  2. 语义差异性:语义不同的词在向量空间中距离较远
  3. 低维度:向量维度不宜过高,避免维度灾难
  4. 计算效率:转换过程应高效,便于大规模应用

一、One-Hot编码:最基础的文本向量表示方法

One-Hot编码是最简单直观的文本向量表示方法,它将每个词表示为一个只包含0和1的稀疏向量。

原理介绍

One-Hot编码为词汇表中的每个词分配一个唯一的索引,然后创建一个与词汇表大小相同的向量,向量中只有对应词索引位置的值为1,其余位置都为0。

例如,对于词汇表['鹿晗', '周杰伦', '王力宏', '吴亦凡', '李宗盛', '陈奕迅'],各个词的One-Hot编码为:

  • 鹿晗:[1, 0, 0, 0, 0, 0]
  • 周杰伦:[0, 1, 0, 0, 0, 0]
  • 王力宏:[0, 0, 1, 0, 0, 0]
  • ...

代码实现

import joblib
# 导包
from tensorflow.keras.preprocessing.text import Tokenizer

def dm_one_hot():
    names = {'周杰伦', '陈奕迅', '王力宏', '李宗盛', '吴亦凡', '鹿晗'}

    token = Tokenizer()

    token.fit_on_texts(names)

    print(token.word_index, 'word2index')
    print(token.index_word, 'index2word')

    for name in names:
        temp = [0] * len(names)

        idx = token.word_index[name] -1

        temp[idx] = 1

        print(temp)

    joblib.dump(token, './data/token')
    print('下载token成功')
def load_token():
    pass
    token = joblib.load('./data/token')

    s = '王力宏'
    index = token.word_index[s] -1
    print(index)

    names = {'周杰伦', '陈奕迅', '王力宏', '李宗盛', '吴亦凡', '鹿晗'}
    temp = [0] * len(names)

    temp[index] = 1

    print(temp, '王力宏')


if __name__ == '__main__':
    dm_one_hot()
    load_token()
{'鹿晗': 1, '周杰伦': 2, '王力宏': 3, '吴亦凡': 4, '李宗盛': 5, '陈奕迅': 6} word2index
{1: '鹿晗', 2: '周杰伦', 3: '王力宏', 4: '吴亦凡', 5: '李宗盛', 6: '陈奕迅'} index2word
[1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0]
[0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 1]
下载token成功
2
[0, 0, 1, 0, 0, 0] 王力宏

优势与劣势分析

优势:

  1. 简单直观:实现简单,易于理解和使用
  2. 无歧义:每个词都有唯一的向量表示
  3. 计算快速:向量生成过程简单快速

劣势:

  1. 语义缺失:完全割裂了词与词之间的语义联系,任意两个词的余弦相似度都是0
  2. 维度灾难:向量维度等于词汇表大小,在大规模语料中维度极高
  3. 存储浪费:向量极度稀疏,存储效率低下
  4. 计算低效:高维稀疏向量在计算时效率低下

正是因为One-Hot编码的明显劣势,这种编码方式在实际应用中越来越少,取而代之的是稠密向量表示方法。

二、Word2Vec:开启语义向量时代

Word2Vec是由Google在2013年提出的一种词向量表示方法,它通过神经网络模型学习词汇的向量表示,使得语义相近的词在向量空间中距离较近。Word2Vec包含两种模型架构:CBOW和Skip-gram。

CBOW模型(Continuous Bag-of-Words)

CBOW模型通过上下文词汇预测目标词汇,即"通过两边预测中间"。

原理详解

CBOW模型将一定窗口内的上下文词汇作为输入,预测窗口中心的词汇。例如,对于句子"请跟我上楼吧",如果窗口大小为3,会产生以下训练样本:

  • ['请跟我'] → 预测"跟"
  • ['跟我上'] → 预测"我"
  • ['我上楼'] → 预测"上"
  • ['上楼吧'] → 预测"楼"

模型结构包含输入层、隐藏层和输出层:

  1. 输入层:上下文词汇的One-Hot向量
  2. 隐藏层:词向量投影层,将输入向量映射到低维空间
  3. 输出层:通过softmax函数预测目标词汇
优势与适用场景
  • 训练快速:在大规模语料上训练速度较快
  • 适合高频词:对高频词的表示效果较好
  • 适用场景:语料丰富、对训练速度有要求的场景

Skip-gram模型(Skip-Gram Model)

Skip-gram模型与CBOW相反,通过目标词汇预测上下文词汇,即"通过中间预测两边"。

原理详解

Skip-gram模型将窗口中心的词汇作为输入,预测其上下文词汇。例如,对于句子"我爱你中国",如果窗口大小为3,会产生以下训练样本:

  • ['我爱你'] → 预测"我"和"你"
  • ['爱你中'] → 预测"爱"和"中"
  • ['你中国'] → 预测"你"和"国"

模型通过反向传播算法优化参数,使得语义相近的词在向量空间中距离较近。

优势与适用场景
  • 捕捉细节:对低频词和生僻词的表示效果更好
  • 语义丰富:能更好地捕捉词汇间的语义关系
  • 适用场景:语料相对较少、需要捕捉词汇细节语义的场景

代码演示

# 代码演示
# 导包
import fasttext

export_model_path = './data/word.bin'
def train():
    # 导入地址
    path_name = './../data/fil9'
    # 导入对应的语料文件, 默认模型为skipgram
    model = fasttext.train_unsupervised(path_name, epoch=1, dim=10)

    model.save_model(export_model_path)
# train()
# 训练语料向量模型

# 导出向量模型

# 加载本地下载好的模型
def load():
    model = fasttext.load_model(export_model_path)

    vector = model.get_word_vector('what')

    print(vector, 'vec')

    print(model.get_nearest_neighbors('cat'), 'cat nearest')

    return model


model = load()
# 获取对应单词对应的向量

# 获取对应单词临近向量的值
[-0.4181195   0.7981538   0.74462444 -0.26776257 -0.6354898   1.1307845  0.74850386 -0.03156095  0.1167936   0.534194  ] vec
[(0.9901968240737915, 'moodle'), (0.9893420338630676, 'monkey'), (0.9882295727729797, 'nutcracker'), (0.9881566762924194, 'pears'), (0.9866331219673157, 'ladybug'), (0.9864039421081543, 'candied'), (0.9855754375457764, 'flea'), (0.9840317964553833, 'gummi'), (0.9838619232177734, 'monkeybone'), (0.9827979803085327, 'butterbeer')] cat nearest

调参示例

## 调参
def train():
    # 导入地址
    path_name = './../data/fil9'
    # 导入对应的语料文件
    model = fasttext.train_unsupervised(path_name, epoch=1, dim=3, model="cbow")

    print(model.get_word_vector('what'))

train()
[-2.9818518 -2.207409  -5.224645 ]

三、Word Embedding:更广泛的词向量概念

Word Embedding是一个更广泛的概念,指将词汇映射到低维连续向量空间的技术。Word2Vec是Word Embedding的一种具体实现,此外还有GloVe、FastText等方法。

Word Embedding的特点

  1. 稠密向量:向量中大部分元素为非零值
  2. 低维度:通常为几十到几百维
  3. 语义丰富:能够捕捉词汇间的语义和语法关系
  4. 计算高效:便于进行向量运算和相似度计算

应用价值

Word Embedding技术的出现彻底改变了NLP领域,其价值体现在:

  1. 语义计算:可以进行词汇相似度计算、类比推理等操作
  2. 迁移学习:预训练的词向量可以在不同任务间共享
  3. 模型性能:显著提升各类NLP任务的性能表现
  4. 应用广泛:成为现代NLP系统的标准组件

技术对比与选择建议

方法维度语义表示训练速度存储效率适用场景
One-Hot高(词汇表大小)无语义极快简单分类任务
CBOW低(几十到几百)有语义语料丰富场景
Skip-gram低(几十到几百)丰富语义中等语义要求高场景

实际应用场景

  1. 搜索引擎:提升查询理解和文档匹配效果
  2. 推荐系统:基于用户兴趣和物品特征进行推荐
  3. 机器翻译:作为编码器和解码器的输入表示
  4. 情感分析:捕捉文本的情感倾向和强度
  5. 问答系统:理解问题语义并匹配答案
  6. 聊天机器人:理解用户意图并生成合理回复

总结

文本向量表示技术经历了从One-Hot编码到Word2Vec再到现代预训练语言模型的发展历程。每种方法都有其特定的适用场景:

  • One-Hot编码虽然简单,但在实际应用中已逐渐被淘汰
  • Word2Vec开启了语义向量时代,至今仍广泛使用
  • Word Embedding概念为更先进的语言表示方法奠定了基础

在实际项目中,选择合适的文本向量表示方法需要考虑语料规模、计算资源、任务需求等多个因素。随着技术的发展,基于Transformer的预训练语言模型(如BERT、GPT等)已成为当前主流,但理解这些基础方法仍然是深入学习NLP的必要步骤。