竞赛 基于CNN实现谣言检测 - python 深度学习 机器学习

文章目录

  • 1 前言
    • 1.1 背景
  • 2 数据集
  • 3 实现过程
  • 4 CNN网络实现
  • 5 模型训练部分
  • 6 模型评估
  • 7 预测结果
  • 8 最后

1 前言

🔥 优质竞赛项目系列,今天要分享的是

基于CNN实现谣言检测

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1.1 背景

社交媒体的发展在加速信息传播的同时,也带来了虚假谣言信息的泛滥,往往会引发诸多不安定因素,并对经济和社会产生巨大的影响。

2 数据集

本项目所使用的数据是从新浪微博不实信息举报平台抓取的中文谣言数据,数据集中共包含1538条谣言和1849条非谣言。

如下图所示,每条数据均为json格式,其中text字段代表微博原文的文字内容。

在这里插入图片描述

每个文件夹里又有很多新闻文本。

在这里插入图片描述
每个文本又是json格式,具体内容如下:

在这里插入图片描述

3 实现过程

步骤入下:

*(1)解压数据,读取并解析数据,生成all_data.txt
*(2)生成数据字典,即dict.txt
*(3)生成数据列表,并进行训练集与验证集的划分,train_list.txt 、eval_list.txt
*(4)定义训练数据集提供器train_reader和验证数据集提供器eval_reader

import zipfile
import os
import io
import random
import json
import matplotlib.pyplot as plt
import numpy as np
import paddle
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import Conv2D, Linear, Embedding
from paddle.fluid.dygraph.base import to_variable#解压原始数据集,将Rumor_Dataset.zip解压至data目录下
src_path="/home/aistudio/data/data36807/Rumor_Dataset.zip" #这里填写自己项目所在的数据集路径
target_path="/home/aistudio/data/Chinese_Rumor_Dataset-master"
if(not os.path.isdir(target_path)):z = zipfile.ZipFile(src_path, 'r')z.extractall(path=target_path)z.close()#分别为谣言数据、非谣言数据、全部数据的文件路径
rumor_class_dirs = os.listdir(target_path+"非开源数据集") # 这里填写自己项目所在的数据集路径
non_rumor_class_dirs = os.listdir(target_path+"非开源数据集")
original_microblog = target_path+"非开源数据集"
#谣言标签为0,非谣言标签为1
rumor_label="0"
non_rumor_label="1"#分别统计谣言数据与非谣言数据的总数
rumor_num = 0
non_rumor_num = 0
all_rumor_list = []
all_non_rumor_list = []#解析谣言数据
for rumor_class_dir in rumor_class_dirs: if(rumor_class_dir != '.DS_Store'):#遍历谣言数据,并解析with open(original_microblog + rumor_class_dir, 'r') as f:rumor_content = f.read()rumor_dict = json.loads(rumor_content)all_rumor_list.append(rumor_label+"\t"+rumor_dict["text"]+"\n")rumor_num +=1
#解析非谣言数据
for non_rumor_class_dir in non_rumor_class_dirs: if(non_rumor_class_dir != '.DS_Store'):with open(original_microblog + non_rumor_class_dir, 'r') as f2:non_rumor_content = f2.read()non_rumor_dict = json.loads(non_rumor_content)all_non_rumor_list.append(non_rumor_label+"\t"+non_rumor_dict["text"]+"\n")non_rumor_num +=1print("谣言数据总量为:"+str(rumor_num))
print("非谣言数据总量为:"+str(non_rumor_num))#全部数据进行乱序后写入all_data.txt
data_list_path="/home/aistudio/data/"
all_data_path=data_list_path + "all_data.txt"
all_data_list = all_rumor_list + all_non_rumor_listrandom.shuffle(all_data_list)#在生成all_data.txt之前,首先将其清空
with open(all_data_path, 'w') as f:f.seek(0)f.truncate() with open(all_data_path, 'a') as f:for data in all_data_list:f.write(data) 
print('all_data.txt已生成')

在这里插入图片描述

接下来就是生成数据字典。


# 生成数据字典
def create_dict(data_path, dict_path):
with open(dict_path, ‘w’) as f:
f.seek(0)
f.truncate()

    dict_set = set()# 读取全部数据with open(data_path, 'r', encoding='utf-8') as f:lines = f.readlines()# 把数据生成一个元组for line in lines:content = line.split('\t')[-1].replace('\n', '')for s in content:dict_set.add(s)# 把元组转换成字典,一个字对应一个数字dict_list = []i = 0for s in dict_set:dict_list.append([s, i])i += 1# 添加未知字符dict_txt = dict(dict_list)end_dict = {"": i}dict_txt.update(end_dict)# 把这些字典保存到本地中with open(dict_path, 'w', encoding='utf-8') as f:f.write(str(dict_txt))print("数据字典生成完成!",'\t','字典长度为:',len(dict_list))

我们可以查看一下dict_txt的内容

在这里插入图片描述

接下来就是数据列表的生成


# 创建序列化表示的数据,并按照一定比例划分训练数据与验证数据
def create_data_list(data_list_path):

    with open(os.path.join(data_list_path, 'dict.txt'), 'r', encoding='utf-8') as f_data:dict_txt = eval(f_data.readlines()[0])with open(os.path.join(data_list_path, 'all_data.txt'), 'r', encoding='utf-8') as f_data:lines = f_data.readlines()i = 0with open(os.path.join(data_list_path, 'eval_list.txt'), 'a', encoding='utf-8') as f_eval,\open(os.path.join(data_list_path, 'train_list.txt'), 'a', encoding='utf-8') as f_train:for line in lines:title = line.split('\t')[-1].replace('\n', '')lab = line.split('\t')[0]t_ids = ""if i % 8 == 0:for s in title:temp = str(dict_txt[s])t_ids = t_ids + temp + ','t_ids = t_ids[:-1] + '\t' + lab + '\n'f_eval.write(t_ids)else:for s in title:temp = str(dict_txt[s])t_ids = t_ids + temp + ','t_ids = t_ids[:-1] + '\t' + lab + '\n'f_train.write(t_ids)i += 1print("数据列表生成完成!")

定义数据读取器


def data_reader(file_path, phrase, shuffle=False):
all_data = []
with io.open(file_path, “r”, encoding=‘utf8’) as fin:
for line in fin:
cols = line.strip().split(“\t”)
if len(cols) != 2:
continue
label = int(cols[1])

            wids = cols[0].split(",")all_data.append((wids, label))if shuffle:if phrase == "train":random.shuffle(all_data)def reader():for doc, label in all_data:yield doc, labelreturn readerclass SentaProcessor(object):def __init__(self, data_dir,):self.data_dir = data_dirdef get_train_data(self, data_dir, shuffle):return data_reader((self.data_dir + "train_list.txt"), "train", shuffle)def get_eval_data(self, data_dir, shuffle):return data_reader((self.data_dir + "eval_list.txt"), "eval", shuffle)def data_generator(self, batch_size, phase='train', shuffle=True):if phase == "train":return paddle.batch(self.get_train_data(self.data_dir, shuffle),batch_size,drop_last=True)elif phase == "eval":return paddle.batch(self.get_eval_data(self.data_dir, shuffle),batch_size,drop_last=True)else:raise ValueError("Unknown phase, which should be in ['train', 'eval']")

总之在数据处理这一块需要我们注意的是一共生成以下的几个文件。

在这里插入图片描述

4 CNN网络实现

接下来就是构建以及配置卷积神经网络(Convolutional Neural Networks,
CNN),开篇也说了,其实这里有很多模型的选择,之所以选择CNN是因为让我们熟悉CNN的相关实现。 输入词向量序列,产生一个特征图(feature
map),对特征图采用时间维度上的最大池化(max pooling over
time)操作得到此卷积核对应的整句话的特征,最后,将所有卷积核得到的特征拼接起来即为文本的定长向量表示,对于文本分类问题,将其连接至softmax即构建出完整的模型。在实际应用中,我们会使用多个卷积核来处理句子,窗口大小相同的卷积核堆叠起来形成一个矩阵,这样可以更高效的完成运算。另外,我们也可使用窗口大小不同的卷积核来处理句子。具体的流程如下:

在这里插入图片描述
首先我们构建单层CNN神经网络。

#单层class SimpleConvPool(fluid.dygraph.Layer):def __init__(self,num_channels, # 通道数num_filters,  # 卷积核数量filter_size,  # 卷积核大小batch_size=None): # 16super(SimpleConvPool, self).__init__()self.batch_size = batch_sizeself._conv2d = Conv2D(num_channels = num_channels,num_filters = num_filters,filter_size = filter_size,act='tanh')self._pool2d = fluid.dygraph.Pool2D(pool_size = (150 - filter_size[0]+1,1),pool_type = 'max',pool_stride=1)def forward(self, inputs):# print('SimpleConvPool_inputs数据纬度',inputs.shape) # [16, 1, 148, 128]x = self._conv2d(inputs)x = self._pool2d(x)x = fluid.layers.reshape(x, shape=[self.batch_size, -1])return xclass CNN(fluid.dygraph.Layer):def __init__(self):super(CNN, self).__init__()self.dict_dim = train_parameters["vocab_size"]self.emb_dim = 128   #emb纬度self.hid_dim = [32]  #卷积核数量self.fc_hid_dim = 96  #fc参数纬度self.class_dim = 2    #分类数self.channels = 1     #输入通道数self.win_size = [[3, 128]]  # 卷积核尺寸self.batch_size = train_parameters["batch_size"] self.seq_len = train_parameters["padding_size"]self.embedding = Embedding( size=[self.dict_dim + 1, self.emb_dim],dtype='float32', is_sparse=False)self._simple_conv_pool_1 = SimpleConvPool(self.channels,self.hid_dim[0],self.win_size[0],batch_size=self.batch_size)self._fc1 = Linear(input_dim = self.hid_dim[0],output_dim = self.fc_hid_dim,act="tanh")self._fc_prediction = Linear(input_dim = self.fc_hid_dim,output_dim = self.class_dim,act="softmax")def forward(self, inputs, label=None):emb = self.embedding(inputs) # [2400, 128]# print('CNN_emb',emb.shape)  emb = fluid.layers.reshape(   # [16, 1, 150, 128]emb, shape=[-1, self.channels , self.seq_len, self.emb_dim])# print('CNN_emb',emb.shape)conv_3 = self._simple_conv_pool_1(emb)fc_1 = self._fc1(conv_3)prediction = self._fc_prediction(fc_1)if label is not None:acc = fluid.layers.accuracy(prediction, label=label)return prediction, accelse:return prediction

接下来就是参数的配置,不过为了在模型训练过程中更直观的查看我们训练的准确率,我们首先利用python的matplotlib.pyplt函数实现一个可视化图,具体的实现如下:


def draw_train_process(iters, train_loss, train_accs):
title=“training loss/training accs”
plt.title(title, fontsize=24)
plt.xlabel(“iter”, fontsize=14)
plt.ylabel(“loss/acc”, fontsize=14)
plt.plot(iters, train_loss, color=‘red’, label=‘training loss’)
plt.plot(iters, train_accs, color=‘green’, label=‘training accs’)
plt.legend()
plt.grid()
plt.show()

5 模型训练部分


def train():
with fluid.dygraph.guard(place = fluid.CUDAPlace(0)): # 因为要进行很大规模的训练,因此我们用的是GPU,如果没有安装GPU的可以使用下面一句,把这句代码注释掉即可
# with fluid.dygraph.guard(place = fluid.CPUPlace()):

        processor = SentaProcessor( data_dir="data/")train_data_generator = processor.data_generator(batch_size=train_parameters["batch_size"],phase='train',shuffle=True)model = CNN()sgd_optimizer = fluid.optimizer.Adagrad(learning_rate=train_parameters["adam"],parameter_list=model.parameters())steps = 0Iters,total_loss, total_acc = [], [], []for eop in range(train_parameters["epoch"]):for batch_id, data in enumerate(train_data_generator()):steps += 1#转换为 variable 类型doc = to_variable(np.array([np.pad(x[0][0:train_parameters["padding_size"]],  #对句子进行padding,全部填补为定长150(0, train_parameters["padding_size"] - len(x[0][0:train_parameters["padding_size"]])),'constant',constant_values=(train_parameters["vocab_size"])) # 用  的id 进行填补for x in data]).astype('int64').reshape(-1))#转换为 variable 类型label = to_variable(np.array([x[1] for x in data]).astype('int64').reshape(train_parameters["batch_size"], 1))model.train() #使用训练模式prediction, acc = model(doc, label)loss = fluid.layers.cross_entropy(prediction, label)avg_loss = fluid.layers.mean(loss)avg_loss.backward()sgd_optimizer.minimize(avg_loss)model.clear_gradients()if steps % train_parameters["skip_steps"] == 0:Iters.append(steps)total_loss.append(avg_loss.numpy()[0])total_acc.append(acc.numpy()[0])print("eop: %d, step: %d, ave loss: %f, ave acc: %f" %(eop, steps,avg_loss.numpy(),acc.numpy()))if steps % train_parameters["save_steps"] == 0:save_path = train_parameters["checkpoints"]+"/"+"save_dir_" + str(steps)print('save model to: ' + save_path)fluid.dygraph.save_dygraph(model.state_dict(),save_path)# breakdraw_train_process(Iters, total_loss, total_acc)

训练的过程以及训练的结果如下:

在这里插入图片描述

6 模型评估


def to_eval():
with fluid.dygraph.guard(place = fluid.CUDAPlace(0)):
processor = SentaProcessor(data_dir=“data/”) #写自己的路径

        eval_data_generator = processor.data_generator(batch_size=train_parameters["batch_size"],phase='eval',shuffle=False)model_eval = CNN() #示例化模型model, _ = fluid.load_dygraph("data//save_dir_180.pdparams") #写自己的路径model_eval.load_dict(model)model_eval.eval() # 切换为eval模式total_eval_cost, total_eval_acc = [], []for eval_batch_id, eval_data in enumerate(eval_data_generator()):eval_np_doc = np.array([np.pad(x[0][0:train_parameters["padding_size"]],(0, train_parameters["padding_size"] -len(x[0][0:train_parameters["padding_size"]])),'constant',constant_values=(train_parameters["vocab_size"]))for x in eval_data]).astype('int64').reshape(-1)eval_label = to_variable(np.array([x[1] for x in eval_data]).astype('int64').reshape(train_parameters["batch_size"], 1))eval_doc = to_variable(eval_np_doc)eval_prediction, eval_acc = model_eval(eval_doc, eval_label)loss = fluid.layers.cross_entropy(eval_prediction, eval_label)avg_loss = fluid.layers.mean(loss)total_eval_cost.append(avg_loss.numpy()[0])total_eval_acc.append(eval_acc.numpy()[0])print("Final validation result: ave loss: %f, ave acc: %f" %(np.mean(total_eval_cost), np.mean(total_eval_acc) ))   

评估准确率如下:

在这里插入图片描述

7 预测结果


# 获取数据
def load_data(sentence):
# 读取数据字典
with open(‘data/dict.txt’, ‘r’, encoding=‘utf-8’) as f_data:
dict_txt = eval(f_data.readlines()[0])
dict_txt = dict(dict_txt)
# 把字符串数据转换成列表数据
keys = dict_txt.keys()
data = []
for s in sentence:
# 判断是否存在未知字符
if not s in keys:
s = ‘’
data.append(int(dict_txt[s]))
return data

train_parameters["batch_size"] = 1
lab = [ '谣言', '非谣言']with fluid.dygraph.guard(place = fluid.CUDAPlace(0)):data = load_data('兴仁县今天抢小孩没抢走,把孩子母亲捅了一刀,看见这车的注意了,真事,车牌号辽HFM055!!!!!赶紧散播! 都别带孩子出去瞎转悠了 尤其别让老人自己带孩子出去 太危险了 注意了!!!!辽HFM055北京现代朗动,在各学校门口抢小孩!!!110已经 证实!!全市通缉!!')data_np = np.array(data)data_np = np.array(np.pad(data_np,(0,150-len(data_np)),"constant",constant_values =train_parameters["vocab_size"])).astype('int64').reshape(-1)infer_np_doc = to_variable(data_np)model_infer = CNN()model, _ = fluid.load_dygraph("data/save_dir_900.pdparams")model_infer.load_dict(model)model_infer.eval()result = model_infer(infer_np_doc)print('预测结果为:', lab[np.argmax(result.numpy())])

在这里插入图片描述

8 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/815228.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

欧姆龙61F系列液位开关使用教程(补水和排水)

欧姆龙61F系列液位开关使用教程(补水和排水) 本文以61F-LS-CP11-NRA型号的液位开关为例进行说明: 具体的选型文档可参考以下链接中的内容: OMRON欧姆龙-无浮标开关(紧凑插入型)61F-LS液位开关-选型样本说明 补水功能(供水) 如下图所示, 电机电源为3相AC220V; 控制电…

SSRF+Redis未授权getshell

SSRFRedis未授权getshell 1.前言 当一个网站具有ssrf漏洞,如果没有一些过滤措施,比如没过滤file协议,gophere协议,dict等协议,就会导致无法访问的内网服务器信息泄露,甚至可以让攻击者拿下内网服务器权限 …

Git分布式版本控制系统——Git常用命令(二)

五、Git常用命令————分支操作 同一个仓库可以有多个分支,各个分支相互独立,互不干扰 分支的相关命令,具体如下: git branch 查看分支 git branch [name] 创建分支&#x…

5. Mysql的binlog介绍

参考:InnoDB学习(三)之BinLog 1. BinLog介绍 BinLog又称为二进制日志,是MySQL服务层的数据日志,MySQL所有的存储引擎都支持BinLog。 BinLog记录了MySQL中的数据更新和可能导致数据更新的事件,可以用于主从…

轻量带屏解决方案之恒玄芯片移植案例

本文章基于恒玄科技BES2600W芯片的欧智通 Multi-modal V200Z-R开发板 ,进行轻量带屏开发板的标准移植,开发了智能开关面板样例,同时实现了ace_engine_lite、arkui_ui_lite、aafwk_lite、appexecfwk_lite、HDF等部件基于OpenHarmony LiteOS-M内…

【联机不卡顿】幻兽帕鲁教你如何低成本0延迟畅玩 云服务器性价比选择方案 16G低至26/月

更新日期:4月14日(腾讯云16G价格回调了!京东云采购季持续进行) 本文纯原创,侵权必究 《最新对比表》已更新在文章头部—腾讯云文档,文章具有时效性,请以腾讯文档为准! 【腾讯文档实…

算法:位运算

算法&#xff1a;位运算 常见位运算操作基本题型模拟加法数字查找总结 常见位运算操作 在C/C中&#xff0c;有比较丰富的位运算操作符&#xff0c;常见的有&#xff1a; &&#xff1a;按位与 |&#xff1a;按位或 ~&#xff1a;按位取反 ^&#xff1a;按位异或 <<&a…

MySQ数据库: MySQL数据库的安装配置 ,图文步骤详细,一篇即可完成安装完成! MySQL数据库如何与客户端连接

LiuJinTao&#xff1a; 2024年4月14日 文章目录 MySQL的安装配置1. 下载2. 安装 三、 MySQL 启动与停止1. 第一种 方式&#xff1a;2. 第二种方式&#xff1a; 四、MySQL 客户端连接2. 方式二&#xff1a; MySQL的安装配置 1. 下载 官方下载网址&#xff1a;https://www.mysq…

代码随想录刷题随记21-回溯1

代码随想录刷题随记21-回溯1 回溯法解决的问题 回溯法&#xff0c;一般可以解决如下几种问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合 切割问题&#xff1a;一个字符串按一定规则有几种切割方式 子集问题&#xff1a;一个N个数的集合里有多少符…

可视化大屏C位图:​地理信息—地球焦点图

Hello&#xff0c;我是大千UI工场&#xff0c;本期可视化大屏的焦点图&#xff08;C位&#xff09;分享将地球作为焦点图的情形&#xff0c;欢迎友友们关注、评论&#xff0c;如果有订单可私信。 将地球作为可视化大屏焦点图可以有以下几个作用&#xff1a; 全球数据展示&…

蓝桥杯嵌入式(G431)备赛笔记——DMA+ADC(单通道+多通道)

单通道&#xff1a; 开启循环模式&#xff0c;两个参数设为word u32 adc_tick0; u32 r37_value0; u32 r38_value0; float r37_volt0; float r38_volt0;//DMAADCvoid DMA_ADC() {if(uwTick-adc_tick<100) return;adc_tick uwTick;HAL_ADC_Start_DMA(&hadc2, &r37_v…

Python学习笔记19 - 类与对象

类的创建 对象的创建 类属性、类方法、静态方法 动态绑定属性和方法 面向对象的三大特征 封装&#xff1a;提高程序的安全性 继承&#xff1a;提高代码的复用性 多态&#xff1a;提高程序的可扩展性和可维护性 类的常用的特殊属性 类的常用的特殊方法 –add–() –len–() –…

Java中创建多线程的方法

继承Thread类&#xff0c;对该类进行new一个实例&#xff0c;对实例调用start方法&#xff0c;重写run方法。 缺点&#xff1a;单继承&#xff0c;无法继承 public class myThread extends Thread {public static void main(String[] args) {myThread myThread new myThread()…

Netty学习——实战篇1 BIO、NIO入门demo 备注

1 BIO 实战代码 Slf4j public class BIOServer {public static void main(String[] args) throws IOException {//1 创建线程池ExecutorService threadPool Executors.newCachedThreadPool();//2 创建ServerSocketServerSocket serverSocket new ServerSocket(8000);log.in…

【嵌入式基础知识学习】AD/DA—数模/模数转换

AD/DA—数模/模数转换概念 数字电路只能处理二进制数字信号&#xff0c;而声音、温度、速度和光线等都是模拟量&#xff0c;利用相应的传感器&#xff08;如声音用话筒&#xff09;可以将它们转换成模拟信号&#xff0c;然后由A/D转换器将它们转换成二进制数字信号&#xff0c…

音视频学习—音视频理论基础(1)

音视频学习—音视频理论基础&#xff08;1&#xff09; 一、音视频处理流程1.1 音频处理流程1.2 视频处理流程1.3 音视频数据流转1.4 为什么音视频采集完之后&#xff0c;不能直接传输&#xff0c;要进行编码&#xff1f;1.5 模数转换1.6 PCM1.7 WAV 总结 一、音视频处理流程 音…

漫途水产养殖水质智能监测方案,科技助力养殖业高效生产!

随着水产养殖业的蓬勃发展&#xff0c;水质和饲料等多重因素逐渐成为影响其持续健康发展的关键因素。由于传统养殖模式因监控和调节手段不足&#xff0c;往往造成养殖环境的恶化。需要通过智能化养殖&#xff0c;调控养殖环境&#xff0c;实现养殖的精细化管理模式&#xff0c;…

Bug的定义生命周期

1、bug的定义 你们觉得bug是什么? 软件的Bug狭义概含是指软件程序的漏洞或缺陷&#xff0c; 广义概念除此之外还包括测试工程师或用户所发现和提出的软件可改进的细节(增强性&#xff0c;建议性)、或 与需求文档存在差异的功能实现等。 我们的职责就是&#xff0c;发现这些B…

Orangepi Zero2 wiringPi外设库SDK安装

文章目录 1. sdk 下载2. sdk 使用 1. sdk 下载 1、使用git 下载 # apt-get update # apt-get install -y git # git clone https://github.com/orangepi-xunlong/wiringOP.git2、手动下载并上传 下载连接 https://github.com/orangepi-xunlong/wiringOP 选master分支 上传到…

【vue】跨组件通信--依赖注入

import { provide,inject } from vue provide&#xff1a;将父组件的数据传递给所有子组件&#xff08;子孙都有&#xff09;inject&#xff1a;接收provide 项目文件结构 App.vue是Header.vue的父组件&#xff0c;Header.vue是Nav.vue的父组件 传值过程 App.vue <tem…