二维卷积中文微博情感分类项目

简介: 这里完成一个中文微博情感分类项目。这里我使用的数据集是从新浪微博收集的 12 万条数据,正负样本各一半。标签中 1 表示正面评论,0 表示负面评论。数据来源为[https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/weibo_sen ti_100k/intro.ipynb。](https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/weibo_sen%20ti_100k/intro.ipynb%E3%80%82)如果你有其他数据的话,

1、数据集说明

  这里完成一个中文微博情感分类项目。这里我使用的数据集是从新浪微博收集的 12 万条数据,正负样本各一半。标签中 1 表示正面评论,0 表示负面评论。数据来源为https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/weibo_sen ti_100k/intro.ipynb。如果你有其他数据的话,也可以使用其他数据。
  这一次我们使用的数据需要自己做处理,所以我们需要对句子进行分词,分词后再对每 个词根据频率来进行编号。这里我们要使用的分词工具是结巴分词,结巴分词是一个很好用 的中文分词工具,安装方式为打开命令提示符,然后输入命令:

pip install jieba

  安装好以后在 python 程序中直接 import jieba 就可以使用了。

2、二维卷积中文情感分类实战

# 安装结巴分词
# pip install jieba
import jieba 
import pandas as pd 
import numpy as np 
from tensorflow.keras.layers import Dense, Input, Dropout
from tensorflow.keras.layers import Conv2D, GlobalMaxPool2D, Embedding, concatenate
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Model
import tensorflow.keras.backend as K
from sklearn.model_selection import train_test_split
import json
# pip install plot_model
from plot_model import plot_model
from matplotlib import pyplot as plt
# 批次大小
batch_size = 128
# 训练周期
epochs = 3
# 词向量长度
embedding_dims = 128
# 滤波器数量
filters = 32
# 这个数据前半部分都是正样本,后半部分都是负样本
data = pd.read_csv('weibo_senti_100k.csv')
# 查看数据前5行
data.head(),data.tail()

image-20220719232001405

# 计算正样本数量
poslen = sum(data['label']==1)
# 计算负样本数量
neglen = sum(data['label']==0)
print('正样本数量:', poslen)
print('负样本数量:', neglen)

image-20220719231944228

# 测试一下结巴分词的使用
print(list(jieba.cut('做父母一定要有刘墉这样的心态,不断地学习,不断地进步')))

image-20220719232036786

#定义分词函数,对传入的x进行分词
cw = lambda x: list(jieba.cut(x))
# apply传入一个函数,把cw函数应用到data['review']的每一行
# 把分词后的结果保存到data['words']中
data['words'] = data['review'].apply(cw)
# 再查看数据前5行
data.head()

image-20220719232106371

# 计算一条数据最多有多少个词汇
max_length = max([len(x) for x in data['words']])
# 打印看到结果为202,最长的句子词汇数不算太多
# 后面就以202作为标准,把所有句子的长度都填充到202的长度
# 比如最长的句子为2000,那么说明有些句子太长了,我们可以设置一个小一点的值作为所有句子的标准长度
# 比如设置1000,那么超过1000的句子只取前面1000个词,不足1000的句子填充到1000的长度
print(max_length)

image-20220719232119356

# 把data['words']中所有的list都变成字符串格式
texts = [' '.join(x) for x in data['words']]
texts

image-20220719232139893

# 查看一条评论,现在数据变成了字符串格式,并且词与词之间用空格隔开
# 这是为了满足下面数据处理对格式的要求,下面要使用Tokenizer对数据进行处理
texts[4]

image-20220719232151418

# 实例化Tokenizer,设置字典中最大词汇数为30000
# Tokenizer会自动过滤掉一些符号比如:!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n
tokenizer = Tokenizer(num_words=30000)
# 传入我们的训练数据,建立词典,词的编号根据词频设定,频率越大,编号越小,
tokenizer.fit_on_texts(texts) 
# 把词转换为编号,编号大于30000的词会被过滤掉
sequences = tokenizer.texts_to_sequences(texts) 
# 把序列设定为max_length的长度,超过max_length的部分舍弃,不到max_length则补0
# padding='pre'在句子前面进行填充,padding='post'在句子后面进行填充
X = pad_sequences(sequences, maxlen=max_length, padding='pre')  
# X = np.array(sequences)
# 获取字典
dict_text = tokenizer.word_index
# 在字典中查询词dui yi
dict_text['梦想']

image-20220719232220074

# 把token_config保存到json文件中,模型预测阶段可以使用
file = open('token_config.json','w',encoding='utf-8')
# 把tokenizer变成json数据
token_config = tokenizer.to_json()
# 保存json数据
json.dump(token_config, file)
print(X[4])

image-20220719232245270

# 定义标签
# 01为正样本,10为负样本
positive_labels = [[0, 1] for _ in range(poslen)]
negative_labels = [[1, 0] for _ in range(neglen)]
# 合并标签
Y = np.array(positive_labels + negative_labels)
print(Y)
# 切分数据集
x_train,x_test,y_train,y_test = train_test_split(X, Y, test_size=0.2)

image-20220719232258286

# 定义函数式模型
# 定义模型输入,shape-(batch, 202)
sequence_input = Input(shape=(max_length,))
# Embedding层,30000表示30000个词,每个词对应的向量为128维
embedding_layer = Embedding(input_dim=30000, output_dim=embedding_dims)
# embedded_sequences的shape-(batch, 202, 128)
embedded_sequences = embedding_layer(sequence_input)
# embedded_sequences的shape变成了(batch, 202, 128, 1)
embedded_sequences = K.expand_dims(embedded_sequences, axis=-1)

# 卷积核大小为3,列数必须等于词向量长度
cnn1 = Conv2D(filters=filters, kernel_size=(3,embedding_dims), activation='relu')(embedded_sequences)
cnn1 = GlobalMaxPool2D()(cnn1)

# 卷积核大小为4,列数必须等于词向量长度
cnn2 = Conv2D(filters=filters, kernel_size=(4,embedding_dims), activation='relu')(embedded_sequences)
cnn2 = GlobalMaxPool2D()(cnn2)

# 卷积核大小为5,列数必须等于词向量长度
cnn3 = Conv2D(filters=filters, kernel_size=(5,embedding_dims), activation='relu')(embedded_sequences)
cnn3 = GlobalMaxPool2D()(cnn3)

# 合并
merge = concatenate([cnn1, cnn2, cnn3], axis=-1)
# 全链接层
x = Dense(128, activation='relu')(merge)
# Dropout层
x = Dropout(0.5)(x)
# 输出层
preds = Dense(2, activation='softmax')(x)
# 定义模型
model = Model(sequence_input, preds)

plot_model(model, dpi=200)

# 定义代价函数,优化器
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['acc'])

# 训练模型
history=model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          validation_data=(x_test, y_test))

image-20220719232338890

# 保存模型
model.save('cnn_model.h5') 

3、模型预测

from keras.models import load_model
from keras.preprocessing.text import tokenizer_from_json
from keras.preprocessing.sequence import pad_sequences
import jieba
import numpy as np
import json
# 载入tokenizer
json_file=open('token_config.json','r',encoding='utf-8')
token_config=json.load(json_file)
tokenizer=tokenizer_from_json(token_config)
#载入模型
model=load_model('cnn_model.h5')
#情感预测
def predict(text):
    # 对句子分词
    cw=list(jieba.cut(text))# ['今天天气', '真', '好', ',', '我要', '去', '打球']
    # list转字符串,元素之间用' '隔开
    texts=' '.join(cw) # 字符串 '今天天气 真 好 , 我要 去 打球'
    # print([texts])# ['今天天气 真 好 , 我要 去 打球']
    # 把词转换为编号,编号大于30000的词会被过滤掉
    sequences=tokenizer.texts_to_sequences([texts]) # [texts] 是把字符串变成列表
    # model.input_shape为(None, 202),202为训练模型时的序列长度
    # 把序列设定为202的长度,超过202的部分舍弃,不到202则补0
    sequences=pad_sequences(sequences=sequences
                            ,maxlen=model.input_shape[1] # 202
                            ,padding = 'pre')
    # 模型预测 shape(1,2)
    predict_result=model.predict(sequences)
    # 取出predict_result中元素最大值所对应的索引
    result=np.argmax(predict_result)
    if(result==1):
        print('正面情绪')
    else:
        print('负面情绪')

if __name__ == '__main__':
    predict('今天天气真好,我要去打球')
    predict("一大屋子人,结果清早告停水了,我崩溃到现在[抓狂]")
    predict("今天我很高兴")
    # pass

image-20220719232428480

  原始数据中有大量表情符号,如[爱你],[哈哈],[鼓掌],[可爱]等,这些表情符号中对应的文字从较大程度上代表了这一句话的情感。所以我们做的这个项目之所以得到这么高的准确率,跟这里的表情符号是有很大关系。大家如果使用其他数据集来做情感分类, 应该也会得到不错的结果,但是应该很难得到 98%这么高的准确率。
目录
相关文章
|
7月前
|
机器学习/深度学习 算法 Python
【Siamese】手把手教你搭建一个孪生神经网络,比较两张图像的相似度
【Siamese】手把手教你搭建一个孪生神经网络,比较两张图像的相似度
732 0
|
7月前
|
机器学习/深度学习 数据挖掘 计算机视觉
【论文速递】WACV2022 - 从边界框标注学习小样本分割
【论文速递】WACV2022 - 从边界框标注学习小样本分割
|
人工智能 关系型数据库 Serverless
向量加成,基于ChatGLM6B生成专属图片
基于ChatGLM6B 提供的能力,可以通过在线对话的方式与用户进行交互,接收用户的问题,并根据问题内容做出相应的回答。基于用户上传语料内容,语言大模型会对问题进行理解,并生成相应回答,提供用户所需的各种知识和信息,AI 知识库问答应用可适用于多种场景,例如在线教育、智能客服、信息查询等。
123 0
|
机器学习/深度学习 算法
【论文写作分析】之五《融合类别特征扩展与N-gram子词过滤的fastText短文本分类》
【论文写作分析】之五《融合类别特征扩展与N-gram子词过滤的fastText短文本分类》
【论文写作分析】之五《融合类别特征扩展与N-gram子词过滤的fastText短文本分类》
|
算法 Serverless
基于朴素贝叶斯算法对新闻文本进行分类
基于朴素贝叶斯算法对新闻文本进行分类
245 0
基于朴素贝叶斯算法对新闻文本进行分类
|
机器学习/深度学习 存储 缓存
【34】文本文档分类实战(哈希编码/权重编码提取特征 + 卡方过滤 + 搭建神经网络分类)
【34】文本文档分类实战(哈希编码/权重编码提取特征 + 卡方过滤 + 搭建神经网络分类)
192 0
【34】文本文档分类实战(哈希编码/权重编码提取特征 + 卡方过滤 + 搭建神经网络分类)
|
自然语言处理 TensorFlow 数据处理
一维卷积英语电影评论情感分类项目
使用一 维卷积对英语文本进行情感分类。我们要使用的数据集是 IMDB 电影评论数据集,数 据分为正面评论和负面评论。这个数据集直接从 Tensorflow 中获得:
157 0
一维卷积英语电影评论情感分类项目
|
机器学习/深度学习 自然语言处理 数据处理
双向LSTM中文微博情感分类项目
这里完成一个中文微博情感分类项目。这里我使用的数据集是从新浪微博收集的 12 万条数据,正负样本各一半。标签中 1 表示正面评论,0 表示负面评论。数据来源为[https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/weibo_sen ti_100k/intro.ipynb](https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/weibo_sen%20ti_100k/intro.ipynb)如果你有其他数据的话,也可以使用其他数据。
226 0
双向LSTM中文微博情感分类项目
|
自然语言处理
|
机器学习/深度学习 自然语言处理