虚假新闻检测
原文链接:https://blog.csdn.net/weixin_51206814/article/details/121688294
一、项目主题
针对媒体出现的虚假新闻和真实新闻进行检测识别。
动机:在这个社交媒体和互联网的世界中,我们接触到各种新闻和文章,但其中一些新闻和文章是假的,是为了好玩或出于恶意而制作的,这对社会是非常有害的。想对媒体产生的新闻进行鉴别,实现对虚假新闻和真实新闻的检测分类识别,以便用户对获取到的新闻进行清晰的认知,排除虚假新闻对用户的影响。
方法:采用监督学习模式,使用 \(TfidfVectorizer,CountVectorizer,PassiveAggressiveClassifier\) ,贝叶斯分类器对文本进行分类。
数据集dataset:https://download.csdn.net/download/weixin_51206814/54260176
代码链接:https://download.csdn.net/download/weixin_51206814/55499702
项目实例:在实验过程中,参考以下论文实例。
- [1]许丽,焦博,赵章瑞.基于TF-IDF的加权朴素贝叶斯新闻文本分类算法[J].网络安全技术与应用,2021(11):31-33.
- [2]陈翠娟.改进的多项朴素贝叶斯分类算法和Python实现[J].景德镇学院学报,2021,36(03):92-95.
二、实验报告
2.1 方法介绍
2.1.1 贝叶斯分类文本
贝叶斯分类算法是一种以统计学为基础的分类算法。朴素贝叶斯分类算法是对传统贝叶斯分类算法进行朴素的假设,所谓朴素就是假设数据类别之间彼此独立,互不产生任何影响。首先要计算属于某一 类的先验概率,然后再利用贝叶斯定理计算其属于此类的后验概率,对各类后验概率的大小进行比较就可进行分类。贝叶斯公式也称为贝叶斯法则,它是关于随机事件\(A\) 和\(B\) 的条件概率和边缘概率的。任何事件的发生都不是完全偶然的,往往都是以其他事件的发生为基础的。条件概率研究的就是在事件 \(A\) 发生的基础上,事件 \(B\) 发生的概率。贝叶斯法则是根据已知先验概率求后验概率。后验概率就是一种条件概率,一般的条件概率是由因求果,后验概率则是知果求因。
在对新闻文本的表示中,使用一个 \(n\) 维向量的形式在多维空间进行表示,对文本的每个词赋予一个权重,在本实验中采用 \(TF-IDF\) 来计算特征词的权重,下一部分将对这个 \(TF-IDF\) 进行详细解释。特征权重就是该词对应空间向量的一个维度坐标,可以进行如下表示:
新闻文本 \(f_i\) 在向量空间中就可以表示为:
其中,\(f_i\) 是数据集中第 \(i\) 篇新闻文本,\(i=1,2,\cdots,m;n\) 是 \(f_i\) 中含有的特征词个数, \(W_{ij}\) 是新闻文本 \(f_i\) 中特征词 \(t_j\) 的特征权重,\(j =1,2,\cdots,n\)。
对于文本分类来说,设训练数据集 \(F =\{f_1,f_2,\cdots,f_m\}\),训练集数据分为 \(k\) 类,记为 \(C_i,i=1,2,\cdots,k\)。类 \(C_i\) 的先验概率为 \(P(C_i)\) ,则文本 \(d\) 的后验概率为:
有朴素贝叶斯算法的独立性假设:各个特征词之间是相互独立。可以得到条件概率:
由于 \(P(d)\) 是确定不变的,因此在比较后验概率的时候只需要比较分子部分即可。即:
在 \(P(W_{in}|C_k)\) 中,实际可以将其看作是 \(TF-IDF\) 的值,用 \(TF-IDF\) 的值代替概率进行计算。(个人理解)
2.1.2 采用TF-IDF文本特征提取
\(TF\) 指词频,表示某个词在文章中出现的频次;\(IDF\) 指逆文档频率,表示包含该词的文档数占语料库文档数的比例。
对于不单独使用词频是由于一些普遍出现的词,在文章出现的次数一般也越高,那么词频就会较高,从词频角度分析,看起来似乎是更重要的特征,但因为这个词普遍出现,这个词可能不是非常的重要,那么单独采用词频 \((TF)\) 进行向量化特征表示就无法反应这一点。
使用 \(TF-IDF\) 的基本思想:如果某个词语在某篇文档中出现的频率很高,从 \(TF\) 的角度来说就是,\(TF\) 很高,但是在语料库内的其他文档中出现的频率很低,从 \(IDF\) 角度来说,就是 \(IDF\) 高,则认定此词语在某种程度上可作为该文档的特征词,具备类别区分能力,可作为分类的依据。一个字词的重要性与它在某份文件中出现的次数正相关,字词在文件中出现的次数越多重要性越大,但同时与它在语料库中出现的频率呈负相关,语料库中出现的次数越多,则该字词的重要性越小。
在对文本特征提取的过程中,可以采用 \(TfidfVectorizer\) 或者 \(CountVectorizer\) ,两种方法区别不大,本实验主要采用\(TfidfVectorizer\) ,下面介绍一下在使用 \(TfidfVectorizer\) 对文本特征进行提取的过程。
-
使用 \(TfidfVectorizer\) 需要调用机器学习 \(sklearn\) 的库,下面是调库语句。
from sklearn.feature_extraction.text import TfidfVectorizer
-
定义语料库的语句,为了便于观察原理过程,语料库加入了两个句子。
corpus=["I come to China to travel", "This is a car polupar in China"]
-
定义完语料库后,调用 \(TfidfVectorizer\) ,出于数据集是英文文本,设置停用词 "\(english\)",将包含在 \(nltk.corpus\) 的英语停止词中的单词进行删除,这些词包括介词、连词、冠词、to be 等没有意义的词。对语料库根据 \(TfidfVectorizer\) 参数规则进行操作,比如滤除停用词等,拟合原始数据,生成文档中有价值的词汇表,结合 \(fit\_tranform\) 完成向量化。
上图是滤除停用词后的结果,可以看见将语料库中的一些冠词、连词等删除,同时对这些词语按字母序排序,得到一个"vocabulary" ,得到这个后,对语料库里的句子文本进行处理,结合 \(fit\_tranform\) 对词语进行向量化。结果如下:
\((0,4)\) 表示第 \(0\) 个字符串,词汇表里第 \(4\) 个单词的 \(TF-IDF\) 值。计算过程为:单词 \(travel\) 在第 \(0\) 个字符串也就是语料库的第一个句子中,词频为 \(TF=1\) ,逆文档频率 \(IDF = log\frac{2+1}{1+1}+1 = log\frac{3}{2}+1=1.40546108\),\(TF-IDF=TF\times IDF=1\times 1.40546 = 1.40546108\)。其他单词同理。
结合 \(toarray()\) 转成数据矩阵形式进行显示,这个矩阵是一个稀疏矩阵,如图,\((0,0)\)位置的值为 \(0\) ,解释为第 \(0\) 个字符串,词汇表里第 \(0\) 个单词,也就是 \(car\),实际中根本没有在语料库第一句中出现,因此值为 \(0\)。由于当文本量庞大的时候,矩阵将会变得十分巨大,不利于显示,因此后续不做输出。
下面是实现上述过程的示例代码。tv_fit = tv.fit_transform(corpus) tv.get_feature_names_out()#生成提取的文本滤除停用词后的单词 print("tv.get_feature_names_out") print(tv.get_feature_names_out())#将单词输出 # print("tv.vocabulary") dict = tv.vocabulary_#生成词汇表 print(dict)#输出词汇表 print("tv_fit") print(tv_fit)#输出向量化后的结果 re = tv_fit.toarray() print(re)#输出转矩阵后的结果
2.1.3 PassiveAggressiveClassifier 分类模型
\(Passive\ Aggressive\),是经典的 \(online\) 线性分类器,它可以不断的整合新样本去调整分类模型,增强模型的分类能力。这样的模型在处理数据量庞大的数据集时,能够解决对数据读取时占用大量内存,使内存受限的情况,避免内存占用过大,解决内存问题。
\(Passive\ Aggressive\ Classifier\) 的具体实现和参考算法。
算法伪代码:
\(Input: aggressiveness\ parameter\ C > 0\)
\(Initialize: W = (0,0,\cdots ,0)\)
$For \ t =1,2,\cdots $
-
\(recive \ instance : X_t \in R\)
-
\(predict\ correct \ label :y_t\in\{-1,+1\}\)
-
\(suffer \ loss : \ell_t=\max\{0,1-y_t(W_t\cdot X_t)\}\)
-
$update \ $
-
$1. \ set $
\[\tau_t = \frac{\ell_t}{||X_t||^2} \\ \tau_t = \min\{C,\frac{\ell_t}{||X_t||^2}\} \\ \tau_t = \frac{\ell_t}{||X_t||^2+\frac{1}{2C}} \] -
\(2.\ update\)
\[W_{t+1} = W_t+\tau_t y_t X_t \]
-
2.2 实验设计
2.2.1 数据处理
对数据集进行读取,并且对数据集的列表数和个数进行统计,输出数据集中的前五行数据进行展示。
观察数据可以看见,有 \(4\) 列数据共 \(6335\) 条,标签 \(label\) 分为 "\(FAKE\)" 和 "\(REAL\)" 两类,获取标签。然后对数据集进行分割,分割为训练集和测试集,采用对 "\(text\)" 和 "\(label\)" 列数据进行分割,分割的测试集大小为 \(0.2\),\(random\_state\) 是随机数种子,设置的数字相同能保证每次拆分的数据集是一样的。
x_train,x_test,y_train,y_test=train_test_split(df['text'], labels, test_size=0.2, random_state=12)
对数据集进行分类后,对 "\(title\)" 内容进行文本特征提取,采取 \(TfidfVectorizer\) 或者 \(CountVectorizer\) 建立特征权重。拟合和变换训练集,变换测试集,建立数据特征矩阵。使用"\(fit\_transform\)" 加载数据并将数据转化为数据矩阵形式。
# TfidfVectorizer 形式
# tfidf_vectorizer = TfidfVectorizer(analyzer = 'word',stop_words = 'english',norm = None)
# CountVectorizer 形式
tfidf_vectorizer = CountVectorizer()
tfidf_train=tfidf_vectorizer.fit_transform(x_train)
tfidf_test=tfidf_vectorizer.transform(x_test)
上图为生成的词汇表和特征向量化、矩阵的结果。
2.2.2 调用模型
了解到有两种模型可供使用对于新闻文本分类,两种分类模型都能避免内存爆炸的情况出现,两种模型都能不断的整合新数据调整分类模型,能达到提高分类能力的结果。
2.2.2.1 PassiveAggressiveClassifier 分类模型
调用机器学习 "\(sklearn\)" 里的 "\(linear\_model\)" 里的 "\(PassiveAggressiveClassifier\)" 分类模型,设置参数 \(max\_iter\) ,可以调整迭代次数观察对于最后准确率的影响(迭代次数设置越大,分类准确率越大)。
#max_iter 迭代次数越大,分类准确率就越大
pac = PassiveAggressiveClassifier(max_iter=50)
2.2.2.2 贝叶斯分类模型对文本进行分类
贝叶斯分类模型分为三种,\(GaussianNB\) 就是先验为高斯分布的朴素贝叶斯,\(MultinomialNB\) 就是先验为多项式分布的朴素贝叶斯,\(BernoulliNB\) 就是先验为伯努利分布的朴素贝叶斯。
-
\(GaussianNB\) 贝叶斯
-
pac = GaussianNB() #由于TF-IDF得到的是稀疏矩阵,使用todense变得密集 tfidf_train = tfidf_train.todense() tfidf_test = tfidf_test.todense()
-
-
\(MultinomialNB\) 贝叶斯
-
pac = MultinomialNB()
-
-
\(BernoulliNB\) 贝叶斯
-
pac = BernoulliNB()
-
这是贝叶斯三种模型的调用代码,分别调用完模型后,进行模型训练。
pac.fit(tfidf_train,y_train)
2.2.2.3 使用模型进行预测
在调用模型对训练集进行训练过后,需要对测试集进行预测,然后将实际结果与预测结果进行对比。
y_pred=pac.predict(tfidf_test)#预测测试集
#print(y_pred)
#print(y_test)
在数据量小的时候,可以将测试集的实际结果与预测结果进行输出观察预测情况对比。
完成预测后,比较测试集实际结果,计算正确率和混淆矩阵并对结果进行分析。
2.3 结果与分析
2.3.1 准确率对比
-
\(PassiveAggressiveClassifier\) 分类模型
采用 \(TfidfVectorizer\) 的情况,调整 \(test\_size\) 、\(random\_state\)、\(max\_iter\) 三个参数比较最后分类正确率。
\(number\) \(test\_size\) \(random\_state\) \(max\_iter\) \(accuracy\) 1 0.2 7 50 91.32% 2 0.3 7 50 90.22% 3 0.4 7 50 89.94% 4 0.2 12 50 90.45% 5 0.2 20 50 92.19% 6 0.2 30 50 90.84% 7 0.2 7 100 91.55% 8 0.2 7 150 91.79% 9 0.2 7 200 91.63% 分析上表格可以看出,在训练集较少的情况下对测试集进行测试,可能会得到不太好的预测结果,另外 \(random\_state\)、\(max\_iter\) 两个参数从上表来看对结果的影响并无太大关系,但从实际分析,迭代次数会影响分类效果。
绘出准确率与迭代次数之间的折线图。观察下图可以看出迭代次数会影响分类效果。
-
贝叶斯模型
-
\(GaussianNB\) 贝叶斯
\(number\) \(test\_size\) \(accuracy\) 1 0.2 80.98% 2 0.3 79.22% 3 0.4 79.95% -
\(MultinomialNB\) 贝叶斯
\(number\) \(test\_size\) \(accuracy\) 1 0.2 90.13% 2 0.3 89.37% 3 0.4 88.6% -
\(BernoulliNB\) 贝叶斯
\(number\) \(test\_size\) \(accuracy\) 1 0.2 82.08% 2 0.3 82.22% 3 0.4 82.56%
-
从上述三种模型分类的结果分析,采用 \(MultinomialNB\) 多项式贝叶斯分类的准确率最高,主要跟先验概率的分布有关系。
通过上述四种模型准确率对比,绘出四种模型准确率柱状图,可以清晰看出四种模型的差异。
2.3.2 混淆矩阵
在结果的部分,采用混淆矩阵的形式对模型预测结果进行可视化以及结果呈现。
混淆矩阵(\(confusion\ matrix\)),又称为可能性表格或是错误矩阵。它是一种特定的矩阵用来呈现算法性能的可视化效果,通常是监督学习,其每一列代表预测值,每一行代表的是实际的类别。这个名字来源于它可以非常容易的表明多个类别是否有混淆(也就是一个\(class\) 被预测成另一个 \(class\))。
在预测分析中,混淆表格(有时候也称为混淆矩阵),是由 \(false \ positives\),\(false\ negatives\),\(true \ positives\) 和 \(true \ negatives\) 组成的两行两列的表格。它允许我们做出更多的分析,而不仅仅是局限在正确率。准确率对于分类器的性能分析来说,并不是一个很好地衡量指标,因为如果数据集不平衡(每一类的数据样本数量相差太大),很可能会出现误导性的结果。
在二分类的模型中,混淆矩阵把预测情况与实际情况的所有结果进行组合,形成了真正 \((true \ positive)\)、假正 \((false\ positive)\)、真负 \((true \ negative)\) 和假负 \((false\ negative)\) 四种情形,分别由 \(TP、FP、TN、FN\) 表示(\(T\) 代表预测正确,\(F\) 代表预测错误)。
-
\(PassiveAggressiveClassifier\) 分类模型的混淆矩阵
-
\(MultinomialNB\)贝叶斯分类模型的混淆矩阵
2.3.3 分析
使用贝叶斯模型的优点:
- 在于能够使用较小的空间获得更好的算法效率,空间开销小,具有稳定的分类效率,占用比较小的空间内存量,并且对缺失数据不太敏感。
使用贝叶斯模型的缺点:
- 需要提前知道先验概率,同时贝叶斯的假设是每个特征属性是独立,因此在属性有关联时就会使分类效果不好。