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

简介: 这里完成一个中文微博情感分类项目。这里我使用的数据集是从新浪微博收集的 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)如果你有其他数据的话,

@toc

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%这么高的准确率。
目录
相关文章
|
12月前
|
机器学习/深度学习 测试技术 算法框架/工具
Python案例|使用卷积网络对星系图片进行分类
星系动物园(galaxy zoo)是由牛津大学等研究机构组织并邀请公众协助的志愿者科学计划,目的是为超过100万个星系图像进行分类。这是天文学中一次规模浩大的公众星空普查活动,大众参与热情高涨,在近十万名志愿者的积极参与下,只用了175天就完成了第一阶段的星系动物园项目:对95万个星系进行了分类,而且平均每个星系被分类了38次。 根据星系动物园的研究结果,星系图像可以分为4大类:圆形星系、中间星系、侧向星系和旋涡星系。图1显示了随机挑选的4类星系的图像。第1行是圆形星系,即星系形状是边缘平滑的圆形。第2行是中间星系,即星系形状是椭圆,之所以称之为中间星系,是指它的形状介于第1行的圆形星系与
104 0
Python案例|使用卷积网络对星系图片进行分类
|
2月前
|
机器学习/深度学习 计算机视觉
【论文速递】CVPR2022 - 学习 什么不能分割:小样本分割的新视角
【论文速递】CVPR2022 - 学习 什么不能分割:小样本分割的新视角
|
10月前
|
人工智能 关系型数据库 Serverless
向量加成,基于ChatGLM6B生成专属图片
基于ChatGLM6B 提供的能力,可以通过在线对话的方式与用户进行交互,接收用户的问题,并根据问题内容做出相应的回答。基于用户上传语料内容,语言大模型会对问题进行理解,并生成相应回答,提供用户所需的各种知识和信息,AI 知识库问答应用可适用于多种场景,例如在线教育、智能客服、信息查询等。
101 0
|
存储 计算机视觉
涨点Trick | ReLabel超越LabelSmoothing解决单图多类单标签问题(附论文与源码下载)(二)
涨点Trick | ReLabel超越LabelSmoothing解决单图多类单标签问题(附论文与源码下载)(二)
144 0
|
机器学习/深度学习 计算机视觉
涨点Trick | ReLabel超越LabelSmoothing解决单图多类单标签问题(附论文与源码下载)(一)
涨点Trick | ReLabel超越LabelSmoothing解决单图多类单标签问题(附论文与源码下载)(一)
91 0
|
机器学习/深度学习 算法
【论文写作分析】之五《融合类别特征扩展与N-gram子词过滤的fastText短文本分类》
【论文写作分析】之五《融合类别特征扩展与N-gram子词过滤的fastText短文本分类》
【论文写作分析】之五《融合类别特征扩展与N-gram子词过滤的fastText短文本分类》
|
自然语言处理 TensorFlow 数据处理
一维卷积英语电影评论情感分类项目
使用一 维卷积对英语文本进行情感分类。我们要使用的数据集是 IMDB 电影评论数据集,数 据分为正面评论和负面评论。这个数据集直接从 Tensorflow 中获得:
135 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)如果你有其他数据的话,也可以使用其他数据。
197 0
双向LSTM中文微博情感分类项目
|
Python
如何通过分割模型完成证件照制作
语义分割或者抠图完之后,我们会获取一个带有alpha通道的png图像。可以通过该图像进一步加工,更换前景的背景图片,从而实现证件照制作、换背景、换天等的玩法。本文主要介绍如何对alpha通道进行原图加工,从而实现证件照功能。
论文赏析[EMNLP18]用序列标注来进行成分句法分析(二)
本文定义了一种新的树的序列化方法,将树结构预测问题转化为了序列预测问题。该序列用相邻两个结点的公共祖先(CA)数量和最近公共祖先(LCA)的label来表示一棵树,并且证明了这个树到序列的映射是单射但不是满射的,但是提出了一系列方法来解决这个问题。
114 0
论文赏析[EMNLP18]用序列标注来进行成分句法分析(二)