为何训练集无法将词转为Word2Vec NumPy向量?Keras LSTM情感分析遇阻
解决推特情感分析中Word2Vec词汇替换失效的问题
嘿,我看你在做推特句子级情感分析的LSTM模型时,碰到了把token替换成Word2Vec索引的问题——代码跑了但输出还是原token列表,完全没变化对吧?咱们来一步步解决这个问题。
问题出在哪?
先拆解你原来的代码逻辑:
for k, v in vocabul.items(): vectorz[x_train==k] = v
这里有两个核心bug:
- numpy二维数组的比较逻辑不适用:
x_train是二维数组(每个元素是一条推特的token列表),直接用x_train==k做比较,numpy会尝试把单个字符串k和整个二维数组做广播匹配,根本没法定位到每个子列表里的单个token,自然找不到任何匹配项,vectorz也就完全没被修改。 - 赋值对象错误:你赋值的
v是Word2Vec的Vocab对象,而不是我们需要的词汇索引值,就算匹配成功,也没法得到可用的模型输入数据。
修正后的解决方案
咱们换个高效且准确的方式处理,核心是先建立词到索引的映射字典,再逐个处理每条推特的token:
- 首先创建词到索引的映射(兼容新旧版本gensim):
# 新版本gensim(4.x+)用index_to_key word_to_idx = {word: idx for idx, word in enumerate(tweet_w2v.wv.index_to_key)} # 如果是旧版本gensim(3.x及以下),换成index2word # word_to_idx = {word: idx for idx, word in enumerate(tweet_w2v.wv.index2word)}
- 写一个辅助函数,把单条推特的token列表转换成索引列表(对不在词汇表中的词,用默认索引0表示未知词):
def convert_tokens_to_indices(tokens, word_map, default_idx=0): return [word_map.get(token, default_idx) for token in tokens]
- 批量处理训练集和测试集:
# 处理训练集 x_train_indices = np.array([convert_tokens_to_indices(tweet_tokens, word_to_idx) for tweet_tokens in x_train]) # 处理测试集 x_test_indices = np.array([convert_tokens_to_indices(tweet_tokens, word_to_idx) for tweet_tokens in x_test])
现在你再打印x_train_indices[1],就能看到对应的索引数组,而不是原来的token字符串了。
额外提示(针对Keras LSTM模型)
处理完索引后,还需要两步适配LSTM的操作:
- 序列填充:因为每条推特的长度不一样,需要用
pad_sequences统一序列长度:
from keras.preprocessing.sequence import pad_sequences max_seq_len = 50 # 根据你的数据设置合适的最大长度 x_train_padded = pad_sequences(x_train_indices, maxlen=max_seq_len, padding='post', truncating='post') x_test_padded = pad_sequences(x_test_indices, maxlen=max_seq_len, padding='post', truncating='post')
- 加载预训练Word2Vec嵌入矩阵:在Keras里用Embedding层加载预训练向量,避免从头训练:
embedding_dim = tweet_w2v.wv.vector_size embedding_matrix = tweet_w2v.wv.vectors embedding_layer = Embedding( input_dim=len(word_to_idx), output_dim=embedding_dim, weights=[embedding_matrix], input_length=max_seq_len, trainable=False # 不想微调预训练向量就设为False,反之设为True )
这样处理后,就能把规整的输入喂给LSTM模型做情感分析啦。
内容的提问来源于stack exchange,提问作者Ishwar
相关产品推荐
相关产品推荐

