【python实战】机器学习微博情感分类

发布于:2025-03-28 ⋅ 阅读:(29) ⋅ 点赞:(0)

个人主页@大数据蟒行探索者 

源代码+数据集:机器学习自然语言处理-微博情感分类(源代码+数据集)

        随着社交媒体的普及,微博文本成为舆情分析、品牌监控和用户行为研究的重要数据源。情感分类旨在通过机器学习和自然语言处理(NLP)技术自动判断文本的情感倾向(如正面、负面、中性),对商业决策和社会治理具有重要意义。微博文本具有短文本、口语化、噪声多(如表情符号、话题标签、错别字)等特点,给情感分类带来挑战。 

一、数据与预处理

数据集

自行爬取的微博文本,标注情感标签(如正向、负向、中性),

导入库代码

import pandas as pd
from sklearn.model_selection import train_test_split
import jieba
from sklearn.metrics import accuracy_score
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
import warnings
warnings.filterwarnings("ignore", category=UserWarning)

查看数据

data_path = 'weibo_comment.csv'
pd_all = pd.read_csv(data_path)

# 假设评论列名为 'comment',分数列名为 'score'
# 创建一个新的列 'sentiment' 来存储情感类别
def classify_sentiment(score):
    if score in [1, 2]:
        return 0
    elif score == 3:
        return 1
    elif score in [4, 5]:
        return 2
    else:
        return 0  # 处理异常情况

pd_all["label"] = pd_all["分数"].apply(classify_sentiment)

pd_all = pd_all.sample(frac=1.0) # 随机打乱样本
print('评论数目(总体):%d' % pd_all.shape[0])
print('评论数目(正向):%d' % pd_all[pd_all.label==2].shape[0])
print('评论数目(中性):%d' % pd_all[pd_all.label==1].shape[0])
print('评论数目(负向):%d' % pd_all[pd_all.label==0].shape[0])

运行结果

 

 文本清洗:去除停用词、标点符号、URL、@提及等噪声。


import re
from bs4 import BeautifulSoup


# 定义清洗函数
def clean_text(text):
    if pd.isnull(text):  # 处理缺失值
        return ""
    
    # 移除 HTML 标签
    text = BeautifulSoup(text, "html.parser").get_text()
    
    # 移除 URL
    text = re.sub(r'http[s]?://\S+', '', text)
    
    # 移除表情、特殊字符等
    text = re.sub(r'<[^>]+>', '', text)  # 移除残留的 HTML 标签
    text = re.sub(r'\[.*?\]', '', text)  # 移除表情符号占位符
    text = re.sub(r'\s+', ' ', text).strip()  # 移除多余空格
    
    return text

# 应用清洗
pd_all["cleaned_comment"] = pd_all["评论内容"].astype(str).apply(clean_text)


review = pd_all['cleaned_comment']
label = pd_all['label']
print(review[:10])
print(label[:10])

运行结果

 二、特征提取

通过CountVectorizer将文本转换为向量矩阵。定义函数代码如下。


def covectorize(train_words,test_words):
    # 建立分词器
    comma_tokenizer = lambda x: "/".join(jieba.cut(x))
    # 读取停用词表
    with open('stop_word.txt','r',encoding='utf8') as f: 
        stopwords = f.read()
    stopwords_list = stopwords.split('\n')
    # 转换为向量
    v = CountVectorizer(tokenizer=comma_tokenizer,min_df=3, max_df=0.8, stop_words = list(frozenset(stopwords_list)),token_pattern=u'(?u)\\b[^\\d\\W]\\w+\\b')
    train_data = v.fit_transform(train_words)
    test_data = v.transform(test_words)
    return train_data,test_data

拆分数据集,80%训练集,20%预测集

# 分割数据集
train_data,test_data,train_label,test_label = train_test_split(review, label,
                                                           test_size=0.2,random_state=2022)

调用前面特征函数将文本数据向量化。

# 中文转向量
train_data_emb, test_data_emb = covectorize(train_data,test_data)

三、训练模型

3.1支持向量机(SVM)模型 

 

from sklearn.svm import SVC
# svm训练
svc = SVC(kernel='rbf')
svc.fit(train_data_emb, np.asarray(train_label))
svc_predic = svc.predict(test_data_emb)
svc_score = accuracy_score(test_label, svc_predic)
print('SVM准确率:', svc_score)

运行结果

 

3.2贝叶斯模型

from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
nb.fit(train_data_emb,train_label)
nb_predic = nb.predict(test_data_emb)
nb_score = accuracy_score(test_label, nb_predic)
print('贝叶斯准确率:', nb_score)

运行结果

3.3决策树模型

# 决策树
from sklearn.tree import DecisionTreeClassifier
decision_tree = DecisionTreeClassifier(random_state=1)
decision_tree.fit(train_data_emb,train_label)
decision_tree_predic = decision_tree.predict(test_data_emb)
decision_tree_score = accuracy_score(test_label,decision_tree_predic)
print('决策树准确率:',decision_tree_score)

运行结果

3.4K 近邻(KNN)模型

# KNN
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()    #实例化KNN模型
knn.fit(train_data_emb, train_label)      #放入训练数据进行训练
knn_predic = knn.predict(test_data_emb)
knn_score = accuracy_score(test_label,knn_predic)
print('KNN准确率:',knn_score)

运行结果

3.5随机森林模型

# 随机森林
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=10)
clf.fit(train_data_emb,train_label)
clf_predic = clf.predict(test_data_emb)
clf_score = accuracy_score(test_label,clf_predic)
print('随机森林准确率:',clf_score)

运行结果

 

 3.6逻辑回归模型

# 逻辑回归
from sklearn import linear_model
logreg = linear_model.LogisticRegression()
logreg.fit(train_data_emb, train_label)
logreg_predic = logreg.predict(test_data_emb)
logreg_score = accuracy_score(test_label,logreg_predic)
print('逻辑回归准确率:',logreg_score)

运行结果

 

3.7TextLSTM模型模型

向量矩阵转为密集矩阵

# train_label 和 test_label 是对应的标签
train_data_emb = train_data_emb.toarray()  # 转换为密集矩阵
test_data_emb = test_data_emb.toarray()  # 转换为密集矩阵
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.metrics import accuracy_score

# 假设你已经有了以下数据:
# train_texts:训练集文本
# test_texts:测试集文本
# train_labels:训练集标签
# test_labels:测试集标签

# 1. 文本数据预处理
max_words = 10000  # 词汇表大小
max_len = 100  # 每个句子的最大长度

# 使用Tokenizer对文本进行编码
tokenizer = Tokenizer(num_words=max_words)
tokenizer.fit_on_texts(train_data)

# 将文本转换为序列
train_sequences = tokenizer.texts_to_sequences(train_data)
test_sequences = tokenizer.texts_to_sequences(test_data)

# 填充序列
train_data_pad = pad_sequences(train_sequences, maxlen=max_len, padding='post', truncating='post')
test_data_pad = pad_sequences(test_sequences, maxlen=max_len, padding='post', truncating='post')

# 2. 构建TextLSTM模型
model = Sequential()
model.add(Embedding(input_dim=max_words, output_dim=100, input_length=max_len))  # 100维的嵌入层
model.add(LSTM(128, dropout=0.3, recurrent_dropout=0.3))  # LSTM层,128个隐藏单元
model.add(Dropout(0.5))  # Dropout层,防止过拟合
model.add(Dense(1, activation='sigmoid'))  # 输出层,二分类使用sigmoid激活函数

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# 3. 设置早停策略
early_stopping = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)

# 4. 训练模型
model.fit(train_data_pad, train_label, epochs=10, batch_size=64, validation_data=(test_data_pad, test_label), callbacks=[early_stopping])

# 5. 预测
textlstm_pred = model.predict(test_data_pad)
textlstm_pred = (textlstm_pred > 0.5).astype(int)  # 二分类预测阈值为0.5

# 6. 计算准确率
textlstm_accuracy = accuracy_score(test_label, textlstm_pred)
print(f"TextLSTM模型准确率:{textlstm_accuracy}")

运行结果

 四、情感类别分布可视化

import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib
#设置matplotlib正常显示中文和符号
matplotlib.rcParams["font.sans-serif"]=['SimHei'] #用黑体显示中文
matplotlib.rcParams['axes.unicode_minus']=False

# 计算每个情感标签的数量
sentiment_counts = pd_all['label'].value_counts()

# 绘制条形图
plt.figure(figsize=(8, 6))
sns.barplot(x=sentiment_counts.index, y=sentiment_counts.values,  hue=sentiment_counts.index,palette='coolwarm')
plt.title('情感类别分布')
plt.xlabel('情感类别')
plt.ylabel('数量')
plt.show()

运行结果

  五、总结

 提供上面7种模型准确率对比,模型效果最好是逻辑回归模型

目录

一、数据与预处理

 二、特征提取

三、训练模型

3.1支持向量机(SVM)模型 

​编辑 

3.2贝叶斯模型

3.3决策树模型

3.4K 近邻(KNN)模型

3.5随机森林模型

 3.6逻辑回归模型

3.7TextLSTM模型模型

​编辑  五、总结


        效果最差的是贝叶斯模型,因此,对于该数据集情感分类结果最好的模型为逻辑回归模型。注意,每次运行代码准确率存在差异,由于在划分数据时加入了随机种子每次划分预测集与测试集存在差异,因此每次运行代码准确率不一样。

需要数据集+源代码:机器学习自然语言处理-微博情感分类(源代码+数据集)