使用RNN与LSTM做亚马逊评论情感分类,预测输出非0/1值的问题
亚马逊评论情感分析:单条文本预测问题排查与解决
背景与问题
我正在用RNN和LSTM做亚马逊评论情感分析,df2['Text']是客户评论,df2['label']是0/1的二元标签。预处理、模型训练流程如下,模型验证准确率约0.86,但单条文本预测时输出的是多个概率值数组,而非预期的0或1。
预处理代码
tokenizer = Tokenizer(num_words=5000, split=' ') tokenizer.fit_on_texts(df2['Text'].values) encoded_docs = tokenizer.texts_to_sequences(df2['Text'].values) X = pad_sequences(encoded_docs, maxlen = 1000) X.shape # (3872, 1000)
y = df2['label'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42)
模型定义与训练代码
model = tf.keras.Sequential() model.add(Embedding(1000, 64, input_length = X.shape[1])) model.add(LSTM(176, dropout=0.4, recurrent_dropout=0.4)) model.add(tf.keras.layers.Dropout(0.3)) model.add(tf.keras.layers.Dense(32, activation='relu')) model.add(tf.keras.layers.Dense(1, activation='sigmoid')) print(model.summary()) model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.01), loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy']) batch_size=128 history = model.fit(X_train, y_train, epochs=13, batch_size=batch_size, validation_data=(X_test, y_test))
单条预测代码与问题
def anal_sent(my_text, my_model, my_tokenizer): encoded_text = my_tokenizer.texts_to_sequences(my_text) X = pad_sequences(encoded_text, maxlen = 1000) return (my_model.predict(X)) ex_review = "I bought it for my son and he says he likes it." print(anal_sent(ex_review, model, tokenizer))
输出为类似[[0.73], [0.68], ...]的多元素数组,而非单个0或1标签。
问题原因
- 输入格式错误:
Tokenizer.texts_to_sequences()需要接收文本列表(如["文本1", "文本2"]),但你传入的是单个字符串。此时函数会把字符串拆成单个字符,将每个字符当作一条独立文本处理,最终生成多条序列,导致模型输出多个预测结果。 - 输出未转换为标签:模型最后一层用了
sigmoid激活函数,输出的是0到1之间的概率值(表示属于类别1的概率),而非直接的0/1标签。
正确的预测方式
修改anal_sent函数,解决上述两个问题:
def anal_sent(my_text, my_model, my_tokenizer, threshold=0.5): # 将单条文本包装成列表,符合texts_to_sequences的输入要求 encoded_text = my_tokenizer.texts_to_sequences([my_text]) # 填充序列,保证长度与训练时一致 X = pad_sequences(encoded_text, maxlen=1000) # 获取概率预测值,关闭进度条输出 prob = my_model.predict(X, verbose=0)[0][0] # 根据阈值转换为0/1标签 return 1 if prob >= threshold else 0 ex_review = "I bought it for my son and he says he likes it." print(anal_sent(ex_review, model, tokenizer))
说明
- 把单条文本用
[]包裹成列表,确保texts_to_sequences将其当作一条完整文本处理。 - 添加
verbose=0可以关闭预测时的进度条输出,让结果更简洁。 - 用
threshold=0.5作为分界(可根据需求调整),将概率值转换为二元标签:概率≥0.5时判定为类别1,否则为类别0。
内容的提问来源于stack exchange,提问作者Lorry Zou
相关产品推荐
相关产品推荐

