机器学习之朴素贝叶斯(附垃圾邮件分类)

朴素贝叶斯分类器介绍概述

 朴素贝叶斯分类器技术基于贝叶斯定理,特别适用于输入维数较高的情况。尽管朴素贝叶斯方法简单,但它通常比更复杂的分类方法更胜一筹。

                                                                    

 为了演示朴素贝叶斯分类的概念,请考虑上面插图中显示的示例。如前所述,这些物体可以分为绿色或红色。我们的任务是对新事件进行分类,即根据当前对象,判定它们属于哪个类标签。

由于绿色样本的数量是红色样本的两倍,因此我们就可以知道,一个新实例(尚未观察到)是绿色的可能性是2倍红色的可能性。在贝叶斯分析中,这种概率预测被称为先验概率。先验概率是基于之前的经验,在这种情况下,绿色和红色物体的百分比,通常用于实际发生之前的预测。

因此我们可以写:

P(green)=\frac{greenNumber}{totalNumber}

P(red)=\frac{redNumber}{totalNumber}

因为总共有60个对象,其中40个是绿色的,20个是红色的,所以类成员的先验概率是

在阐述了我们的先验概率之后,我们现在可以对一个新对象(白圈)进行分类了。由于对象是很好地聚集在一起的,因此可以合理地假设X附近的绿色(或红色)对象越多,新的情况就越有可能属于那个特定的颜色。为了度量这种可能性,我们在X周围画一个圆,它包含一个点的数字(要预先选择),而不考虑它们的类标签。然后我们计算属于每个类标签的圆中的点数。由此我们计算了可能性:

从上面式子中可以清楚地看出,给定绿色的X的可能性比给定红色的X的可能性小,因为圆包含1个绿色物体和3个红色物体。因此有

虽然先验概率表明X可能属于绿色(假设绿色的数量是红色的两倍),但可能性表明并非如此;X的类成员是红色的(假设X附近的红色对象比绿色对象多)。在贝叶斯分析中,最终的分类是将两种信息源结合起来得到的,即根据所谓的贝叶斯规则来形成后验概率。

最后,我们将X分类为红色,因为它的类隶属度达到最大的后验概率。

请注意。上述概率没有标准化。但是,这并不影响分类结果,因为它们的标准化常数是相同的。

朴素贝叶斯理论

以上,提供了一个使用朴素贝叶斯理解分类的直观示例。接下来将进一步详细介绍所涉及的技术问题。朴素贝叶斯分类器可以处理任意数量的自变量,无论是连续的还是分类的。给定一组变量,X = {x1,x2, X…,我们想在一系列可能的结果C = {c1,c2, C…,cd}中构造事件Cj的后验概率。换句话说,X是预测因子,C是因变量中存在的类别级别的集合。使用贝叶斯规则

 p(Cj | x1,x2,x...,xd)是事件的后验概率,也就是X属于Cj的概率。

虽然对于预测器(独立)变量是独立的这一假设并不总是准确的,但它极大地简化了分类任务,因为它允许对每个变量分别计算类的条件密度p(x_{k} | Cj),即它将一个多维任务简化为多个一维任务。实际上,朴素贝叶斯将高维密度估计任务简化为一维核密度估计。此外,该假设对后验概率影响不大,尤其是在决策边界附近的区域,因此分类任务不受影响。

朴素贝叶斯可以用几种不同的方法建模,包括正规、对数正规、伽马和泊松密度函数:

请注意!泊松变量在这里被认为是连续的,因为它们是有序的,而不是真正的分类。对于分类变量,使用离散概率,分类级别的值与训练数据中的条件频率成正比。

垃圾邮件分类实现

我们将与scikit一起使用Python 3—学习为SMS消息构建一个非常简单的垃圾邮件检测器(对于年轻人来说,这是我们在中世纪时用于消息传递的工具)。您可以从这个链接找到并下载数据集。我们需要三个库来简化编码:scikit-learn、pandas和nltk。您可以使用pip或conda来安装它们。

短信垃圾邮件收集v.1是一组SMS标记的消息,已收集用于SMS垃圾邮件研究。它包含一组英语短信,包含5574条短信,按照ham(合法)或spam标记。其中,短信合法信息4827条(86.6%),垃圾短信747条(13.4%)。要加载数据,可以使用pandas的Dataframe read_table方法。这允许我们定义分隔符(在本例中是选项卡)并相应地重命名列。 要加载数据,可以使用pandas的Dataframe read_table方法。这允许我们定义一个分隔符(在本例中是一个选项卡),并相应地重命名列:

import pandas as pd 
df = pd.read_table('SMSSpamCollection', sep='\t', header=None, names=['label', 'message'])

一旦我们准备好了数据,就该做一些预处理了。我们将专注于为手头的任务消除无用的差异。首先,我们必须为我们的分类器将标签从字符串转换为二进制值: 

df['label'] = df.label.map({'ham': 0, 'spam': 1})  

其次,将消息中的所有字符转换为小写:

df['message'] = df.message.map(lambda x: x.lower()) 

第三,去掉标点符号:

df['message'] = df.message.str.replace('[^\w\s]', '')  

第四,使用nltk将消息标记为单个单词。首先,我们必须从控制台导入和下载记号赋予器:

import nltk  
nltk.download() 

将出现一个安装窗口。转到“Models”选项卡,从“Identifier”列中选择“punkt”。然后点击“下载”,它将安装必要的文件。那它就应该工作了!现在我们可以应用记号化:

df['message'] = df['message'].apply(nltk.word_tokenize)  

第五,我们将执行词干提取。词干提取的思想是使我们的文本规范化,因为不管时态如何,词的所有变体都具有相同的含义。最流行的词干提取算法之一是PorterStemmer:

from nltk.stem import PorterStemmer

stemmer = PorterStemmer()

df['message'] = df['message'].apply(lambda x: [stemmer.stem(y) for y in x]) 

最后,我们将数据转换为事件,这些特征将被输入到我们的模型中:

from sklearn.feature_extraction.text import CountVectorizer

# This converts the list of words into space-separated strings
df['message'] = df['message'].apply(lambda x: ' '.join(x))

count_vect = CountVectorizer()  
counts = count_vect.fit_transform(df['message'])  

我们可以让它作为每条消息的简单字数,但最好使用术语频率逆文档频率,即tf-idf:


from sklearn.feature_extraction.text import TfidfTransformer

transformer = TfidfTransformer().fit(counts)

counts = transformer.transform(counts)  

模型训练

现在我们已经从数据中执行了特征提取,现在是构建模型的时候了。我们将从将我们的数据分割为训练和测试集开始:


from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(counts, df['label'], test_size=0.1, random_state=69)  

然后,我们所要做的就是初始化朴素贝叶斯分类器并对数据进行拟合。对于文本分类问题,多项式朴素贝叶斯分类器非常适合:

from sklearn.naive_bayes import MultinomialNB

model = MultinomialNB().fit(X_train, y_train) 

模型评估

一旦我们把分类器放在一起,我们可以在测试集中评估它的性能:

import numpy as np

predicted = model.predict(X_test)

print(np.mean(predicted == y_test))  

我们简单朴素的贝叶斯分类器有98.2%的准确性与这个具体的测试集!但是仅仅提供准确性是不够的,因为我们的数据集在标签方面是不平衡的(86.6%合法,而垃圾邮件占13.4%)。我们的分类器可能在忽略垃圾邮件类的同时过于适合合法类。为了解决这个不确定性,让我们来看看混淆矩阵:

from sklearn.metrics import confusion_matrix

print(confusion_matrix(y_test, predicted))  

confsion_matrix方法将打印如下内容:

[[478   4]
[   6  70]]

正如我们所看到的,错误的数量在合法和垃圾邮件之间是相当平衡的,4条合法消息被分类为垃圾邮件,6条合法消息被分类为垃圾邮件。总的来说,这些对于我们简单的分类器来说都是非常好的结果。

本文从朴素贝叶斯分类器的理论和实践两个方面对朴素贝叶斯分类器进行了介绍。我们设计了一个简单的多模态朴素贝叶斯分类器,该分类器对短信垃圾邮件的检测准确率达到了98.2%。

猜你喜欢

转载自blog.csdn.net/qinguanggai9953/article/details/84965276