如何用TensorFlow版Word2Vec处理含动物类复合与非复合名词的语料?
用TensorFlow实现Word2Vec处理含复合/非复合动物名词的语料
第一步:语料预处理(核心:复合名词合并为独立token)
这是确保复合词(如"red panda")和独立词(如"panda")都被当作独立token的关键环节,必须在模型训练前完成。
具体操作:
- 先整理一份英文动物复合名词映射表,把复合词映射为单个token(用下划线连接):
compound_animal_map = { "red panda": "red_panda", "flying fox": "flying_fox", "elephant seal": "elephant_seal", # 可根据你的语料扩展更多复合动物名 } - 对原始文本进行精准替换,注意按复合词的单词数量倒序排序,避免短词优先匹配(比如先替换"elephant seal"再替换"elephant"):
import re # 按复合词包含的单词数从多到少排序 sorted_compounds = sorted(compound_animal_map.keys(), key=lambda x: len(x.split()), reverse=True) # 构建正则匹配模式,确保匹配完整单词 match_pattern = re.compile(r'\b(' + '|'.join(re.escape(c) for c in sorted_compounds) + r')\b') def replace_compound_terms(text): return match_pattern.sub(lambda m: compound_animal_map[m.group()], text) # 示例处理 raw_corpus = "Red panda and panda share similar habitats; flying fox is often mistaken for fox." processed_corpus = replace_compound_terms(raw_corpus.lower()) # 输出:"red_panda and panda share similar habitats; flying_fox is often mistaken for fox." - 最后做常规分词(直接按空格分割即可),得到训练用的token列表:
token_list = processed_corpus.split()
第二步:用TensorFlow构建Skip-Gram版Word2Vec
TensorFlow没有现成的Word2Vec封装,我们基于Skip-Gram架构手动实现(Skip-Gram适合小语料,对低频词友好,复合动物名通常是低频词,更适用):
1. 构建词汇映射与训练样本
from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import skipgrams import numpy as np # 用Tokenizer生成词汇表与索引映射 tokenizer = Tokenizer() tokenizer.fit_on_texts([token_list]) word_to_idx = tokenizer.word_index vocab_size = len(word_to_idx) + 1 # Tokenizer从1开始索引,加1适配Embedding层 # 生成Skip-Gram训练样本(目标词+上下文词+标签:1表示正样本,0表示负样本) pairs, labels = skipgrams( sequence=tokenizer.texts_to_sequences([token_list])[0], vocabulary_size=vocab_size, window_size=3, # 上下文窗口大小,可根据需求调整 negative_samples=5.0 # 负采样比例,控制负样本数量 ) # 转换为模型可接受的numpy数组格式 target_arr = np.array([p[0] for p in pairs], dtype=np.int32) context_arr = np.array([p[1] for p in pairs], dtype=np.int32) label_arr = np.array(labels, dtype=np.int32)
2. 定义Skip-Gram模型结构
import tensorflow as tf from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, Embedding, Dot, Reshape # 词向量维度,可根据语料大小调整 embedding_dim = 100 # 目标词输入分支 target_input = Input(shape=(1,)) target_embedding = Embedding(vocab_size, embedding_dim, name="word_embedding_layer")(target_input) target_embedding = Reshape((embedding_dim,))(target_embedding) # 上下文词输入分支 context_input = Input(shape=(1,)) context_embedding = Embedding(vocab_size, embedding_dim)(context_input) context_embedding = Reshape((embedding_dim,))(context_embedding) # 计算点积并输出二分类概率 dot_product = Dot(axes=1)([target_embedding, context_embedding]) output = tf.keras.layers.Dense(1, activation="sigmoid")(dot_product) # 编译模型 model = Model(inputs=[target_input, context_input], outputs=output) model.compile(loss="binary_crossentropy", optimizer=tf.keras.optimizers.Adam(learning_rate=0.001))
3. 训练模型
model.fit([target_arr, context_arr], label_arr, epochs=50, batch_size=32, verbose=1)
4. 提取词向量
训练完成后,从Embedding层提取所有词的向量:
word_vectors = model.get_layer("word_embedding_layer").get_weights()[0] # 示例:获取"red_panda"的词向量 red_panda_idx = word_to_idx["red_panda"] red_panda_vector = word_vectors[red_panda_idx]
第三步:验证复合词与独立词的独立性
可以通过计算词向量的余弦相似度验证效果:
from sklearn.metrics.pairwise import cosine_similarity # 计算"red_panda"与"panda"的相似度 panda_idx = word_to_idx["panda"] panda_vector = word_vectors[panda_idx] similarity_score = cosine_similarity([red_panda_vector], [panda_vector])[0][0] print(f"red_panda 和 panda 的词向量相似度:{similarity_score:.4f}")
这样就能保证"red_panda"、"flying_fox"等复合动物名和"panda"、"fox"等独立词都被当作独立token训练,各自学习到符合语义的词向量。
内容的提问来源于stack exchange,提问作者DS14
相关产品推荐
相关产品推荐

