掘金 人工智能 07月28日 18:00
机器学习:使用LSTM训练情感分析模型
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了如何利用LSTM神经网络模型对电商平台的用户评论进行情感分析。通过数据加载、预处理、序列化,构建了一个包含Embedding、Bidirectional LSTM、Dropout和Dense层的模型。模型经过训练和优化,并保存了模型、tokenizer和label encoder,以便后续进行预测。文中还提供了一个`SentimentPredictor`类,封装了预测功能,并展示了如何对多条评论进行批量情感评分和准确率评估,实现了对用户反馈的自动化、实时分析,为电商平台提供了有效的预警和提醒机制。

⚙️ **数据处理与序列化**:首先,文章详细阐述了数据加载和预处理的步骤,包括读取CSV文件、提取评论文本和评分,并利用`LabelEncoder`将评分转换为数值标签(1-5映射为0-4)。随后,使用`Tokenizer`将文本转化为序列,并通过`pad_sequences`确保所有序列具有统一的长度(200),为模型输入做好了准备。

🧠 **LSTM模型构建与训练**:文章构建了一个基于LSTM的深度学习模型,该模型包含了`Embedding`层用于词向量表示,`Bidirectional(LSTM)`层捕捉双向上下文信息,`Dropout`层防止过拟合,以及`Dense`层进行分类。模型使用`Adam`优化器和`sparse_categorical_crossentropy`损失函数进行编译。训练过程中,设置了`epochs`和`batch_size`,并引入`EarlyStopping`回调函数以监控验证集损失,防止模型过拟合。

💾 **模型与工具的保存与加载**:训练完成后,模型、`tokenizer`和`label_encoder`被分别保存到`sentiment_lstm_5class.h5`、`tokenizer.pickle`和`label_encoder.pickle`文件中。这使得后续可以方便地加载这些组件,并构建`SentimentPredictor`类,该类封装了文本预处理和情感预测的逻辑。

🚀 **情感预测与应用**:`SentimentPredictor`类能够接收评论文本,经过预处理后输入到已加载的模型中进行预测,输出情感分值(1-5)及各分值的概率。文章通过示例展示了如何对单条或多条评论进行预测,并评估其准确率,为电商平台实时分析用户情感、进行预警和提醒提供了技术支持。

背景:电商平台收到了许多关于宝贝的评论,需要自动从大量的数据中分析出各种情感的用户评论,并实时给出预警和提醒。

数据格式:

数据中最重要的两列:Review Text 和Rating,一个是评论内容一个是评分。

第一步:先进行数据处理:

def load_and_preprocess_data(filepath):    """加载并预处理数据"""    df = pd.read_csv(filepath)    texts = df['Review Text'].values    labels = df['Rating'].values    # 标签编码 (1-5 -> 0-4)    le = LabelEncoder()    labels = le.fit_transform(labels)    # 文本序列化    tokenizer = Tokenizer(num_words=20000, oov_token="<OOV>")    tokenizer.fit_on_texts(texts)    sequences = tokenizer.texts_to_sequences(texts)    padded_sequences = pad_sequences(sequences, maxlen=200, truncating='post')    return padded_sequences, labels, tokenizer, le

加载数据,并将数据序列化。

第二步:利用LSTM建立模型的结构,设置数据嵌入的向量维度:

def build_model(vocab_size, max_len, embedding_dim=128):    """构建LSTM模型"""    model = Sequential([        Embedding(vocab_size, embedding_dim, input_length=max_len),        Bidirectional(LSTM(64, return_sequences=True)),        Dropout(0.5),        LSTM(32),        Dropout(0.5),        Dense(64, activation='relu'),        Dropout(0.5),        Dense(5, activation='softmax')    ])    model.compile(        optimizer=Adam(learning_rate=0.001),        loss='sparse_categorical_crossentropy',        metrics=['accuracy']    )    return model

第三步:训练并保存模型:

def main():    # 加载数据    X, y, tokenizer, le = load_and_preprocess_data('Clothing_Reviews.csv')    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)    # 构建模型    model = build_model(vocab_size=20000, max_len=200)    model.summary()    # 训练模型    history = model.fit(        X_train, y_train,        validation_data=(X_test, y_test),        epochs=10,        batch_size=64,        callbacks=[EarlyStopping(monitor='val_loss', patience=3)],        verbose=1    )    print(f"history: {history}")    # 评估模型    # plot_history(history)    loss, accuracy = model.evaluate(X_test, y_test, verbose=0)    print(f'测试集准确率: {accuracy:.2f}')    # 保存模型和tokenizer    model.save('sentiment_lstm_5class.h5')    with open('tokenizer.pickle', 'wb') as handle:        pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)    print("模型和tokenizer已保存")    # 保存label encoder    with open('label_encoder.pickle', 'wb') as handle:        pickle.dump(le, handle, protocol=pickle.HIGHEST_PROTOCOL)

至此,根据训练集训练的模型保存完毕。要想使用训练保持好的模型进行数据预测,需要新建一个预测的方法:

import numpy as npimport picklefrom keras.src.saving import load_modelfrom keras.src.utils import pad_sequencesfrom sklearn.preprocessing import LabelEncoderclass SentimentPredictor:    def __init__(self, model_path, tokenizer_path, label_encoder_path=None, max_len=200):        """初始化预测器"""        self.model = load_model(model_path)        with open(tokenizer_path, 'rb') as handle:            self.tokenizer = pickle.load(handle)        with open(label_encoder_path, 'rb') as handle:            self.label_encoder = pickle.load(handle)        self.max_len = max_len    def preprocess_text(self, text):        """预处理文本"""        sequence = self.tokenizer.texts_to_sequences([text])        padded = pad_sequences(sequence, maxlen=self.max_len, truncating='post')        return padded    def predict_sentiment(self, text, verbose=False):        """预测情感分值(1-5)"""        # 预处理        padded_sequence = self.preprocess_text(text)        # 预测        prediction = self.model.predict(padded_sequence, verbose=0)        predicted_class = np.argmax(prediction, axis=1)        # 转换回原始标签(1-5)        predicted_score = self.label_encoder.inverse_transform(predicted_class)[0]        if verbose:            print(f"评论: {text}")            print(f"预测情感分值: {predicted_score}")            print("各类别概率:")            for i, prob in enumerate(prediction[0]):                print(f"{i + 1}分: {prob:.4f}")            print("-" * 50)        return predicted_score, prediction[0]

这个类封装了读取加载模型、使用模型进行预测的方法,调用是传入已经保持的模型路径即可。使用实例:

# 初始化预测器predictor = SentimentPredictor(    model_path='sentiment_lstm_5class.h5',    tokenizer_path='tokenizer.pickle',    label_encoder_path='label_encoder.pickle')# 测试评论test_reviews = [    "This product is absolutely amazing! Best purchase ever!",    "The item was okay, but not worth the price.",    "Terrible quality. Would not recommend to anyone.",    "It's decent for the price, though it has some flaws.",    "I'm completely satisfied with this purchase. It exceeded all my expectations!"]# 批量预测for review in test_reviews:    score, probs = predictor.predict_sentiment(review, verbose=True)    print(f"{review}: 预测情感分值: {score},准确率: {np.max(probs) * 100:.2f}%")# 预测单个评论sample_review = "The product was good but the delivery took too long."score, probs = predictor.predict_sentiment(sample_review, verbose=True)print(f"{sample_review}: 预测情感分值: {score},准确率: {np.max(probs) * 100:.2f}%")

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

情感分析 LSTM 深度学习 电商评论 自然语言处理
相关文章