序列数据与神经网络预处理:从文本到词向量
约 1692 字大约 6 分钟
序列数据与神经网络预处理:从文本到词向量
一、 序列数据与动机
- 核心观点:某些数据(如语言、股票、气温)在时间维度上具有强关联性,这与图像在空间维度上的关联性类似。
- 典型示例:
- 语音/文字:需按时间顺序接收完整序列才能理解含义。
- 应用场景:需要神经网络处理此类具有时间关联性的数据,例如文本情感分类(区分正面/负面评论)。
二、 文本数据的数字化表示
1. 基本单位:词(Word)
- 自然语言处理(NLP)中,通常以词而非单个字符作为基本处理单位。
- 原因:词承载更明确的语义(例如:
adoptvsadapt)。
2. 初步方法:词典索引
- 思路:为每个词在词典中分配一个唯一的位置索引,将句子转化为索引数字序列。
- 流程:
- 英文:按空格分词。
- 中文:需先进行分词操作。
- 为每个词查找词典索引,构成向量。
- 问题:索引接近的词(如“开心”和“开除”)在数值上相似,但语义可能完全不同,会给模型带来干扰。
3. 改进方法:One-Hot 编码
- 定义:对于一个包含
V个词的词典,每个词表示为一个V维向量,其中只有该词对应索引位置的值为1,其余全为0。 - 优点:彻底区分了每个词。
- 缺点:
- 无法体现词间关联:所有词向量相互正交,忽略了语义相似性(如“猫”与“狗”)。
- 维度灾难:词典很大时,向量维度过高,导致输入数据非常稀疏和庞大。
三、 词向量(Word Embedding)
1. 核心思想
- 将每个词表示为一个稠密、低维的实数向量(例如50维、300维)。
- 向量的每一维度代表词的某个潜在语义或语法特征(如:词性、是否动物、是否有皮毛等,但这些特征是模型自动学习的抽象表示)。
- 目标:语义相近的词,其词向量在向量空间中的距离也更接近。
2. 词向量的优势
- 保留语义关系:相似的词聚集在一起。
- 具备推理能力:词向量间可进行类比运算(例:
vector(“国王”) - vector(“男人”) + vector(“女人”) ≈ vector(“女王”))。 - 数据更高效:低维稠密向量比高维稀疏的 One-Hot 向量更利于模型训练和泛化。
3. 词嵌入矩阵与嵌入层
- 词嵌入矩阵(Embedding Matrix):一个可学习的参数矩阵
W,形状为(embedding_dim, vocab_size)。- 每一列对应词典中一个词的词向量。
- 嵌入层(Embedding Layer):神经网络中的一层,其前向传播操作实质上是:
- 输入:词的 One-Hot 编码向量
[1 x V]。 - 操作:
词向量 = W · One-Hot向量。根据矩阵乘法性质,此操作等效于从W中选取出该词对应的列(即词向量)。
- 输入:词的 One-Hot 编码向量
- 训练:嵌入层可参与神经网络的整体训练。通过反向传播,词嵌入矩阵
W会得到更新,从而学习到更合适的词向量表示。
4. 迁移学习与预训练词向量
- 问题:要训练出高质量的词向量,通常需要海量的文本数据。
- 解决方案:迁移学习。
- 使用在大规模语料库(如维基百科、网页爬取数据)上预训练好的词向量(如 Word2Vec, GloVe 等算法训练的成果)。
- 在具体任务中,用预训练的词向量初始化嵌入矩阵,并通常冻结(freeze)嵌入层,使其在任务训练时不更新,或仅进行微调(fine-tune)。
- 优点:能显著提升在小数据集任务上的模型性能。
四、 文本分类实战流程(基于 Keras)
以下代码展示了使用嵌入层进行文本情感分类的关键步骤:
# 1. 数据读取与预处理
import shopping_data # 假设的辅助工具
X_train, y_train, X_test, y_test = shopping_data.load_data()
# 2. 构建词典(词汇表)
word_index, vocab_size = shopping_data.create_word_index(X_train, X_test)
# 3. 将文本句子转换为词索引序列
X_train_index = shopping_data.words_to_index(X_train, word_index)
X_test_index = shopping_data.words_to_index(X_test, word_index)
# 4. 序列对齐(填充/截断)
from tensorflow.keras.preprocessing import sequence
max_len = 25 # 设定句子最大长度
X_train_pad = sequence.pad_sequences(X_train_index, maxlen=max_len)
X_test_pad = sequence.pad_sequences(X_test_index, maxlen=max_len)
# 5. 构建神经网络模型(包含Embedding层)
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, Flatten, Dense
model = Sequential()
# 添加嵌入层
model.add(Embedding(input_dim=vocab_size, # 词典大小
output_dim=300, # 词向量维度
input_length=max_len, # 输入序列长度
trainable=False)) # 是否训练词嵌入矩阵
model.add(Flatten()) # 将词向量序列平铺
model.add(Dense(256, activation='relu'))
model.add(Dense(256, activation='relu'))
model.add(Dense(256, activation='relu'))
model.add(Dense(1, activation='sigmoid')) # 二分类输出
# 6. 编译与训练
model.compile(loss='binary_crossentropy',
optimizer='adam', # 适用于序列任务的优化器
metrics=['accuracy'])
model.fit(X_train_pad, y_train, epochs=200, batch_size=512)
# 7. 评估
test_loss, test_acc = model.evaluate(X_test_pad, y_test)
print(f'Test accuracy: {test_acc}')关键参数说明:
Embedding层:input_dim:词汇表大小。output_dim:词向量的维度。input_length:每个输入序列(句子)的长度(经过对齐后)。trainable:是否在训练中更新词嵌入矩阵。设为True时,词向量会随任务一起优化;设为False时,通常使用预训练且冻结的词向量。
实验对比:
- 在情感分类任务中,设置
trainable=True(更新词向量)比trainable=False(使用随机初始化且冻结)获得了更高的测试准确率(示例中从79%提升至85.6%),说明针对任务优化词向量是有效的。
五、 当前方法的局限性与展望
- 局限性:将词向量序列平铺后送入全连接网络,未能显式建模词与词之间的时序依赖关系。
- 示例问题:模型可能因“好看”而将“非常不好看”误判为正面,因为它忽略了“不”对后续词的修饰作用。
- 解决方案:需要能够处理序列时序关联性的神经网络结构。
- 下步方向:循环神经网络(RNN) 及其变体(如LSTM、GRU),专门为序列数据设计。
总结
本节课重点介绍了神经网络处理文本等序列数据的数据预处理核心方法——词向量。通过将词表示为稠密、低维的实数向量,并利用嵌入层在训练中学习或加载预训练的语义关系,为模型提供了高质量的特征输入。实战部分演示了使用Keras构建文本分类模型的完整流程。然而,简单的“词向量+全连接”结构无法有效捕捉序列中的长期依赖,这引出了对循环神经网络(RNN) 的需求,为下节课的内容做了铺垫。
