当前位置: 首页 > article >正文

股民情绪识别的LSTM-NBM混合模型

      大家好,我是带我去滑雪!

      利用之前爬取2023年10月17日至2024年7月13日的65万余条东方财富网的上证指数股吧的股民评论数据,基于jieba库对股民情绪进行识别,在进行中文分词、去除停用词、合并同义词和长短句分离后,对长文本使用长短期记忆网络(LSTM)情绪分类,对短文本使用朴素贝叶斯(NBM)情绪分类,建立了股民情绪识别的LSTM-NBM混合模型。混合模型的正向文本和负向文本的识别准确率分别为77%、88%。下面开始代码实战。

目录

(1)基于jieba库的文本处理

(2)长文本LSTM情绪分类模型

(3)短文本NBM的模型构建


(1)基于jieba库的文本处理

        识别股民情绪时,机器学习模型的选择因句子长度的不同而异。长句子依赖于词汇间的相互作用和逻辑关系来传达意义,而短句子则能通过极少的词语直接明确其含义。为了能够更加高效的代入后续训练模型中,需要对股民评论中非结构化的文本要进行相应的预处理,本文采用jieba分词方法。jieba是一种流行的中文分词工具,它可以将文本切分成有意义的单词,是目前Python中最常用的中文分词库之一,具有简单易用、高效准确的特点。下面依次进行:

  • 去除停用词
  • 合并同义词
  • 长短句分离:将经过分词、去停用词、合并同义词后的文本数据,按照10字节大小分为长短文本,对于不同长短的文本数据采取不同的情感分析模型。
import pandas as pd
all_data=pd.read_csv('E:\工作\硕士\博客\朴素贝叶斯与LSTM情感分类代码与数据(2)\data.csv',encoding="ANSI")
all_data
all_data['PL']

输出结果:

import pandas as pd
import jieba
stop_list  = pd.read_csv("E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\停用词.txt",index_col=False,quoting=3,sep="\t",names=['stopword'], encoding='utf-8')
#Jieba分词函数
def txt_cut(juzi):
    lis=[w for w in jieba.lcut(juzi) if w not in stop_list.values]
    return (" ").join(lis)
df=pd.read_csv('E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\data.csv',encoding="ANSI")
df['cutword']=df['PL'].astype('str').apply(txt_cut)
df=df[['date','PL','cutword']]
df
df.to_excel('E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\分词后的评论.xlsx',index=False)
import pandas as pd
df = pd.read_csv('E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\分词后的评论.csv',encoding="ANSI")
df.set_index('date', inplace=True)
long_texts = df[df['cutword'].str.len() > 10]
short_texts = df[df['cutword'].str.len() <= 10]
long_texts.to_csv('E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\分词后的长文本.csv',encoding="ANSI")  # 保存长文本
short_texts.to_csv('E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\分词后的短文本.csv',encoding="ANSI")  # 保存短文本

(2)长文本LSTM情绪分类模型

       长短期记忆网络能比CNN能更好地处理时间序列任务;同时LSTM解决了RNN的长期依赖问题,并缓解了在训练过程中反向传播造成的“梯度消失”问题。因此对于长文本,本文利用LSTM进行建模分析:建立股票领域的情感词典,当长文本在经过文本分词后,利用python 中gensim的Word2Vec方法将其转换成词向量,再将样本按照一定的比例划分为训练集和测试集,通过LSTM模型得到最终的长文本情绪识别结果。

import pandas as pd
all_data= pd.read_csv(r'E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\长文本带标签汇总评论.csv',encoding="ANSI")
all_data
text_list = all_data["cutword"]
text_list.head(10) 
#训练词向量word2vec
from gensim.models import Word2Vec

w2vmodel = Word2Vec(vector_size=100) #训练n_dim为100
w2vmodel.build_vocab(text_list)
%time w2vmodel.train(text_list,\
                     total_examples = w2vmodel.corpus_count, epochs = 10)
# 用各个词向量直接平均的方式生成整句对应的向量
def m_avgvec(words, w2vmodel):
    return pd.DataFrame([w2vmodel.wv[w]
                         for w in words if w in w2vmodel.wv]).agg("mean")
# 生成建模用矩阵
%time train_vec = pd.DataFrame([m_avgvec(s, w2vmodel) for s in text_list])
train_vec.head()
import os

from keras.preprocessing.text import Tokenizer
from keras_preprocessing.sequence import pad_sequences
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.utils import np_utils
from keras.layers.core import Dropout, Activation, Lambda

from keras.layers import Dense, Embedding, LSTM
from keras.utils.np_utils import to_categorical
from keras.callbacks import ModelCheckpoint
from keras.models import load_model
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split

x_train_lstm, x_test_lstm, y_train_lstm, y_test_lstm = train_test_split(text_list, all_data['label'], test_size = 0.4)
embedding_matrix = w2vmodel.wv.vectors

#使用embedding_matrix的长度作为top_words
top_words_w2v = embedding_matrix.shape[0]

#以下参数设置同上
maxlen = 100 
batch_size = 32
nb_classes = 2
nb_epoch =1

tokenizer1 = Tokenizer(nb_words = top_words_w2v) 
tokenizer1.fit_on_texts(x_train_lstm)

sequences_train1 = tokenizer1.texts_to_sequences(x_train_lstm)
sequences_test1 = tokenizer1.texts_to_sequences(x_test_lstm)

x_train_seq1 = pad_sequences(sequences_train1, maxlen=maxlen)
x_test_seq1 = pad_sequences(sequences_test1, maxlen=maxlen)

y_train_seq1 = np_utils.to_categorical(y_train_lstm, nb_classes)
y_test_seq1 = np_utils.to_categorical(y_test_lstm, nb_classes)
# 设置Word2Vec为embedding layer
embedding_layer = Embedding(embedding_matrix.shape[0], 
                            embedding_matrix.shape[1],
                            weights=[embedding_matrix])


# 基于Word2Vec embedding建立LSTM 
model_w2v_lstm = Sequential()
model_w2v_lstm.add(embedding_layer) #选择上面设置好的Word2Vec为embedding layer
model_w2v_lstm.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2))  
model_w2v_lstm.add(Dense(nb_classes))
model_w2v_lstm.add(Activation('softmax'))
model_w2v_lstm.summary()
# 编译模型
model_w2v_lstm.compile(loss='binary_crossentropy',
                       optimizer='adam',
                       metrics=['accuracy'])
model_w2v_lstm.fit(x_train_seq1, y_train_seq1, batch_size=batch_size, epochs=nb_epoch, verbose=1)

输出结果:

(3)短文本NBM的模型构建

       对于短文本,本文采用NBM模型进行建模分析,短文本进行分词、去停用词等预处理后,能得到较短的核心词汇,将核心词汇代入情感词典后,代入NBM模型即可得到最终的短文本的情绪识别结果。同样按照一定比例分为训练集和测试集。

        NBM 模型基于其原理,初步通过对两变量的联合分布进行概率估算,利用现有数据集的训练来掌握此计算方法。首先是先验概率的学习,然后是条件概率分布的学习,目的是实现概率分布的匹配。由于NBM模型在处理稀疏数据时可能遇到零概率问题,这会导致朴素贝叶斯公式的计算失误,本文采用拉普拉斯平滑来解决这一问题,假设每个特征的出现频率高于实际观测值。

import pandas as pd
data1 = pd.read_csv('E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\分词后的短文本.csv',encoding="ANSI")
data1
from snownlp import SnowNLP
data1['emotion'] = data1['cutword'].apply(lambda x:SnowNLP(x).sentiments)
data1
#计算积极评论与消极评论各自的数目
pos = 0
neg = 0
for i in data1['emotion']:
    if i >= 0.5:
        pos += 1
    else:
        neg += 1
print('积极评论,消极评论数目分别为:')
pos,neg
#获取消极评论数据
data2=data1[data1['emotion']<0.5]
data2.head(10)
data2.to_excel('E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\短文本消极评论.xlsx',index=False)#保存数据
data3=data1[data1['emotion']>0.5]
data3.head(10)
data3.to_excel('E:\工作\硕士\博客\博客粉丝问题\朴素贝叶斯与LSTM情感分类代码与数据\短文本积极评论.xlsx',index=False)#保存数据
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import networkx as nx
plt.rcParams['font.sans-serif'] = ['KaiTi']  
plt.rcParams['axes.unicode_minus'] = False 
import jieba
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.neural_network import MLPClassifier
pos_df = pd.DataFrame([line.replace('\n', '') for line in open('positive.txt',encoding='UTF-8').readlines()],columns=['text'])
pos_df['label']=1    #正面标签为1
neg_df = pd.DataFrame([line.replace('\n', '') for line in open('negtive.txt',encoding='UTF-8').readlines()],columns=['text'])
neg_df['label']=0    #负面标签为0
#朴素贝叶斯
model1 = MultinomialNB()
model_list=[model1]
model_name=['朴素贝叶斯']
scores=[]
for i in range(len(model_list)):
    model_C=model_list[i]
    name=model_name[i]
    model_C.fit(X_train, y_train)
    s=model_C.score(X_test, y_test)
    scores.append(s)
    print(f'{name}方法在测试集的准确率为{round(s,3)}')
#预测概率
prob = model_C.predict_proba(X_test)
#预测类别
pred = model_C.predict(X_test)
#数据透视表,混淆矩阵
table = pd.crosstab(y_test, pred, rownames=['Actual'], colnames=['Predicted'])
table

输出结果:

需要数据集的家人们可以去百度网盘(永久有效)获取:

链接:https://pan.baidu.com/s/173deLlgLYUz789M3KHYw-Q?pwd=0ly6
提取码:2138 


更多优质内容持续发布中,请移步主页查看。

博主的WeChat:TCB1736732074

   点赞+关注,下次不迷路!


http://www.kler.cn/a/387573.html

相关文章:

  • ZYNQ初识10(zynq_7010)UART通信实验
  • Realsense相机驱动安装及其ROS通讯配置——机器人抓取系统系列文章(四)
  • arcgis中用python脚本批量给多个要素类的相同字段赋值
  • 初学stm32 --- DAC输出三角波和正弦波
  • JuiceFS 2024:开源与商业并进,迈向 AI 原生时代
  • 页面滚动下拉时,元素变为fixed浮动,上拉到顶部时恢复原状,js代码以视频示例
  • Java 泛型详解:参数化类型的强大之处
  • 数字乡村建设方案-5
  • IntelliJ IDEA的快捷键
  • python基础知识及其应用
  • 【抽取数据简单方式】spark实现hive中数据抽取到MySQL
  • 「QT」几何数据类 之 QRectF 浮点型矩形类
  • ORACLE 闪回技术简介
  • 基于promtail+loki+grafana搭建日志系统
  • 【WRF运行报错】segmentation fault (SIGSEGV) 错误原因总结
  • 网站视频过大,加载缓慢解决方法【分段加载视频】
  • 当爱遇见旋律:陆瑶记忆中的音符碎片!
  • 高速光耦——推动工业生产自动化飞跃的关键力量
  • 当今陪玩系统小程序趋势,陪玩系统源码搭建后的适用于哪些平台
  • 《ASP.Net Core技术内幕与项目实战》读书笔记_1
  • 引入 axios,根据 api 文档生成调用接口
  • AI大模型重塑软件开发流程:从自动化编码到智能协作的未来展望
  • 【MM-Align】学习基于输运的最优对齐动力学,快速准确地推断缺失模态序列
  • 【春秋云镜】CVE-2023-2130
  • springboot系列--web相关知识探索七
  • 使用 pd.ExcelWriter 创建多工作表 Excel 文件的详细教程