文章目录

  • 1. Sklearn 实现朴素贝叶斯
    • 1.1 数据导入
    • 1.2 数据预处理
    • 1.3 拆分训练集和测试集
    • 1.4 Bag of Words
      • 1.4.1 Sklearn 实现 Bag of Words:CountVectorizer
        • 1.4.1.1 count_vector = CountVectorizer(lowercase='True', token_pattern, stop_words)
        • 1.4.1.2 count_vector.fit(data)
        • 1.4.1.3 count_vector.transform(data)
        • 1.4.1.4 结果可视化:
    • 1.5 使用 Scikit-learn 实现朴素贝叶斯
    • 1.6 评估模型
  • 2. 总结
  • 参考资料

相关文章:

机器学习 | 目录

监督学习 | 朴素贝叶斯原理及Python实现

1. Sklearn 实现朴素贝叶斯

1.1 数据导入

使用来自 UCI 机器学习资源库中的数据集,该资源库有大量供实验性研究的数据集。这是直接数据链接。

下面是该数据的预览:

数据集中的列目前没有命名,可以看出有 2 列。

第一列有两个值:“ham”,表示信息不是垃圾信息,以及“spam”,表示信息是垃圾信息。

第二列是被分类的信息的文本内容。

首先导入数据:

import pandas as pd
df = pd.read_csv('smsspamcollection/SMSSpamCollection',sep='\t', header=None, names=['label', 'sms_message'])
df.head(5)
label sms_message
0 ham Go until jurong point, crazy.. Available only ...
1 ham Ok lar... Joking wif u oni...
2 spam Free entry in 2 a wkly comp to win FA Cup fina...
3 ham U dun say so early hor... U c already then say...
4 ham Nah I don't think he goes to usf, he lives aro...

1.2 数据预处理

我们已经大概了解数据集的结构,现在将标签转换为二元变量,0 表示“ham”(即非垃圾信息),1表示“spam”,这样比较方便计算。

由于Scikit-learn 只处理数字值,因此如果标签值保留为字符串,scikit-learn 会自己进行转换(更确切地说,字符串标签将转型为未知浮点值)。

如果标签保留为字符串,模型依然能够做出预测,但是稍后计算效果指标(例如计算精确率和召回率分数)时可能会遇到问题。因此,为了避免稍后出现意外的陷阱,最好将分类值转换为整数,再传入模型中。

说明:

  • 使用映射方法将“标签”列中的值转换为数字值,如下所示:
    {‘ham’:0, ‘spam’:1} 这样会将“ham”值映射为 0,将“spam”值映射为 1。
  • 此外,为了知道我们正在处理的数据集有多大,使用“shape”输出行数和列数
df['label'] = df.label.map({'ham':0, 'spam':1})
print(df.shape)
df.head(5)
(5572, 2)
label sms_message
0 0 Go until jurong point, crazy.. Available only ...
1 0 Ok lar... Joking wif u oni...
2 1 Free entry in 2 a wkly comp to win FA Cup fina...
3 0 U dun say so early hor... U c already then say...
4 0 Nah I don't think he goes to usf, he lives aro...

1.3 拆分训练集和测试集

说明:
通过在 sklearn 中使用 train_test_split 方法,将数据集拆分为训练集和测试集。使用以下变量拆分数据:

  • X_train 是 ‘sms_message’ 列的训练数据。
  • y_train 是 ‘label’ 列的训练数据
  • X_test 是 ‘sms_message’ 列的测试数据。
  • y_test 是 ‘label’ 列的测试数据。
    输出每个训练数据和测试数据的行数。
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(df['sms_message'], df['label'], random_state=1)print('Number of rows in the total set: {}'.format(df.shape[0]))
print('Number of rows in the training set: {}'.format(X_train.shape[0]))
print('Number of rows in the test set: {}'.format(X_test.shape[0]))
Number of rows in the total set: 5572
Number of rows in the training set: 4179
Number of rows in the test set: 1393

1.4 Bag of Words

我们的数据集中有大量文本数据(572 行数据)。大多数机器学习算法都要求传入的输入是数字数据,而电子邮件/信息通常都是文本。

现在我们要介绍 Bag of Words (BoW) 这个概念,它用来表示要处理的问题具有“大量单词”或很多文本数据。BoW 的基本概念是拿出一段文本,计算该文本中单词的出现频率。注意:BoW 平等地对待每个单词,单词的出现顺序并不重要。

利用我们将介绍的流程,我们可以将文档集合转换成矩阵,每个文档是一行,每个单词(令牌)是一列,对应的(行,列)值是每个单词或令牌在此文档中出现的频率。

例如:

X_train.head()
710     4mths half price Orange line rental & latest c...
3740                           Did you stitch his trouser
2711    Hope you enjoyed your new content. text stop t...
3155    Not heard from U4 a while. Call 4 rude chat pr...
3748    Ü neva tell me how i noe... I'm not at home in...
Name: sms_message, dtype: object

我们的目标是将这组文本转换为频率分布矩阵,如下所示:

从图中可以看出,文档在行中进行了编号,每个单词是一个列名称,相应的值是该单词在文档中出现的频率。

我们详细讲解下,看看如何使用一小组文档进行转换。

1.4.1 Sklearn 实现 Bag of Words:CountVectorizer

from sklearn.feature_extraction.text import CountVectorizer# Instantiate the CountVectorizer method
count_vector = CountVectorizer(token_pattern='(?u)\\b\\w\\w+\\b', stop_words='english')# 拟合并转换训练集(不能将测试集也fit,这违背了基本原则)
training_data = count_vector.fit_transform(X_train)# Transform testing data and return the matrix. Note we are not fitting the testing data into the CountVectorizer()
testing_data = count_vector.transform(X_test)

1.4.1.1 count_vector = CountVectorizer(lowercase=‘True’, token_pattern, stop_words)

要处理这一步,我们使用 sklearns
count vectorizer 方法,该方法的作用如下所示:

  • 它会令牌化字符串(将字符串划分为单个单词)并为每个令牌设定一个整型 ID。
  • 它会计算每个令牌的出现次数。

参数设置:

  • lowercase='True':CountVectorizer 方法会自动将所有令牌化单词转换为小写形式,避免区分“He”和“he”等单词。
  • token_pattern:CountVectorizer 方法会自动忽略所有标点符号,避免区分后面有标点的单词(例如“hello!”)和前后没有标点的同一单词(例如“hello”)token_pattern 参数具有默认正则表达式值 (?u)\\b\\w\\w+\\b,它会忽略所有标点符号并将它们当做分隔符,并将长度大于等于 2 的字母数字字符串当做单个令牌或单词。
  • stop_words:停用词是指某个语言中最常用的字词,包括“am”、“an”、“and”、“the”等。 通过将此参数值设为 english,CountVectorizer 将自动忽略(输入文本中)出现在 scikit-learn 中的内置英语停用词列表中的所有单词。这非常有用,因为当我们尝试查找表明是垃圾内容的某些单词时,停用词会使我们的结论出现偏差。

1.4.1.2 count_vector.fit(data)

fit() 将文档数据集与 CountVectorizer 对象进行拟合

1.4.1.3 count_vector.transform(data)

transform() 方法会返回一个 numpy 整数矩阵,可以使用 toarray() 将其转换为数组

1.4.1.4 结果可视化:

get_feature_names() 方法会返回此数据集的特征名称,即组成数据词汇表的单词集合。

transform() 方法会返回一个 numpy 整数矩阵,可以使用 toarray() 将其转换为数组

doc_array = count_vector.transform(X_train).toarray()
count_vector.get_feature_names()
frequency_matrix = pd.DataFrame(doc_array, columns=count_vector.get_feature_names())
frequency_matrix.head(5)
00 000 008704050406 0121 01223585236 01223585334 0125698789 02 0207 02072069400 ... zed zeros zhong zindgi zoe zoom zouk zyada èn 〨ud
0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 1 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0

5 rows × 7204 columns

1.5 使用 Scikit-learn 实现朴素贝叶斯

  • GaussianNB[1]:应用于任意连续数据

  • Bernoullinb:假定输入数据为二分类数据(主要用于文本数据分类)

  • MultinomialNB:假定输入数据为计数数据(主要用于文本数据分类)

from sklearn.naive_bayes import MultinomialNB
naive_bayes = MultinomialNB()
naive_bayes.fit(training_data, y_train)
predictions = naive_bayes.predict(testing_data)

1.6 评估模型

我们已经对测试集进行了预测,下一个目标是评估模型的效果。我们可以采用各种衡量指标,但首先快速总结下这些指标。

准确率衡量的是分类器做出正确预测的概率,即正确预测的数量与预测总数(测试数据点的数量)之比。

精确率指的是分类为垃圾信息的信息实际上是垃圾信息的概率,即真正例(分类为垃圾内容并且实际上是垃圾内容的单词)与所有正例(所有分类为垃圾内容的单词,无论是否分类正确)之比,换句话说,是以下公式的比值结果:

[True Positives/(True Positives + False Positives)]

召回率(敏感性)表示实际上为垃圾信息并且被分类为垃圾信息的信息所占比例,即真正例(分类为垃圾内容并且实际上是垃圾内容的单词)与所有为垃圾内容的单词之比,换句话说,是以下公式的比值结果:

[True Positives/(True Positives + False Negatives)]

对于偏态分类分布问题(我们的数据集就属于偏态分类),例如如果有 100 条信息,只有 2 条是垃圾信息,剩下的 98 条不是,则准确率本身并不是很好的指标。我们将 90 条信息分类为非垃圾信息(包括 2 条垃圾信息,但是我们将其分类为非垃圾信息,因此它们属于假负例),并将 10 条信息分类为垃圾信息(所有 10 条都是假正例),依然会获得比较高的准确率分数。对于此类情形,精确率和召回率非常实用。可以通过这两个指标获得 F1 分数,即精确率和召回率分数的加权平均值。该分数的范围是 0 到 1,1 表示最佳潜在 F1 分数

我们将使用所有四个指标确保我们的模型效果很好。这四个指标的值范围都在 0 到 1 之间,分数尽量接近 1 可以很好地表示模型的效果如何。

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
print('Accuracy score: ', format(accuracy_score(y_test, predictions)))
print('Precision score: ', format(precision_score(y_test, predictions)))
print('Recall score: ', format(recall_score(y_test, predictions)))
print('F1 score: ', format(f1_score(y_test, predictions)))
Accuracy score:  0.9877961234745154
Precision score:  0.9615384615384616
Recall score:  0.9459459459459459
F1 score:  0.9536784741144414

2. 总结

和其他分类算法相比,朴素贝叶斯具有的一大主要优势是能够处理大量特征。在我们的示例中,有数千个不同的单词,每个单词都被当做一个特征。此外,即使存在不相关的特征也有很好的效果,不容易受到这种特征的影响。另一个主要优势是相对比较简单。朴素贝叶斯完全可以直接使用,很少需要调整参数,除非通常分布数据已知的情况需要调整。
它很少会过拟合数据。另一个重要优势是相对于它能处理的数据量来说,训练和预测速度很快。总之,朴素贝叶斯是非常实用的算法!

参考资料

[1] ls秦.Python机器学习 — 朴素贝叶斯算法(Naive Bayes)[EB/OL].https://blog.csdn.net/qq_38328378/article/details/80771469, 2018-07-10.

监督学习 | 朴素贝叶斯之Sklearn实现相关推荐

  1. 监督学习 | 朴素贝叶斯原理及Python实现

    文章目录 1. 贝叶斯理论 1.1 贝叶斯定理 1.2 贝叶斯分类算法 1.3 朴素贝叶斯分类算法 1.3.1 朴素贝叶斯分类器实例 学习过程 预测过程 2. Python实现 2.1 拉普拉斯修正 ...

  2. 朴素贝叶斯算法Sklearn实现的学习笔记

    import numpy as np#导入数据集生成器 from sklearn.datasets import make_blobs #随机生成500个类别数是5的分类数据 X,y = make_b ...

  3. sklearn中的朴素贝叶斯

    1 概述 1.1 真正的概率分类器 在许多分类算法应用中,特征和标签之间的关系并非是决定性的.如想预测一个人究竟是否能在泰坦尼克号海难中生存下来,可以建一棵决策树来学习训练集.在训练中,其中一个人的特 ...

  4. ML————朴素贝叶斯原理和SKlearn相关库

    二师兄养成记正式开始, 以后就写这了.  写的不对的.有疑问的,恳请大佬指出来. 一. 贝叶斯定理 1.  条件概率: P(A | B) = P(A B) / P(B) = P(A U B)/ P(B ...

  5. python 机器学习 sklearn 朴素贝叶斯

    首先介绍一个非常好的博主和博客,大家可以去这学习,我收获很大优秀的博客 朴素贝叶斯下面包括三个方法 分别是高斯朴素贝叶斯.多项式朴素贝叶斯.伯努利朴素贝叶斯 这三种方式都有不同的应用场所,比如你要预测 ...

  6. 使用Sklearn学习朴素贝叶斯算法

    目录 1,sklearn中的贝叶斯分类器 1.1,高斯朴素贝叶斯GaussianNB 1.1.1,认识高斯朴素贝叶斯 1.1.2,参数说明 1.1.3,高斯朴素贝叶斯建模案例 1.1.4,探索高斯朴素 ...

  7. sklearn中的朴素贝叶斯算法

    sklearn中的朴素贝叶斯分类器 之前理解朴素贝叶斯中的结尾对sklearn中的朴素贝叶斯进行了简单的介绍. 此处对sklearn中的则对sklearn中的朴素贝叶斯算法进行比较详细介绍.不过手下还 ...

  8. sklearn——朴素贝叶斯

    以下文章为一位博主翻译自某篇官方文档,在此引用: 在scikit-learn中,提供了3中朴素贝叶斯分类算法:GaussianNB(高斯朴素贝叶斯).MultinomialNB(多项式朴素贝叶斯).B ...

  9. 朴素贝叶斯详解及中文舆情分析(附代码实践)

    作者|杨秀璋  整理|AI科技大本营 本文主要讲述朴素贝叶斯分类算法并实现中文数据集的舆情分析案例,希望这篇文章对大家有所帮助,提供些思路.内容包括: 1.朴素贝叶斯数学原理知识 2.naive_ba ...

最新文章

  1. sqrt()函数的详解和用法
  2. NSUserDefault 的使用
  3. Oracle中的move命令
  4. 8屏 旌宇多屏管理软件_如何选择拼接屏,不能说的秘密,都在这!
  5. 120万人同时在线考试,这么大的流量如何支撑
  6. opensource项目_最佳Opensource.com:法律
  7. 多语言跨平台远程过程调用【Avro】
  8. linux安装bash工具包,Linux 资源监视工具BashTop的安装和使用
  9. 2015蓝桥杯C++A:牌型种数(分配问题)
  10. 环境保护设施运营组织服务认证 认证专业分类及运营设施范围
  11. 微信公众账号调取用户昵称和用户头像
  12. 使用Vivado软件进行硬件调试
  13. 时间“照妖镜”のmanic time
  14. 【小说】玻璃碎片-第二章
  15. Android大厂面试真题解析大全,安卓未来路在何方
  16. docker-compose up:ERROR: Encountered errors while bringing up the project.錯誤及解決方式
  17. ShareSDK iOS端微信如何获取authcode值
  18. 如何使用 PowerShell 锁定、解锁、启用和禁用 AD 帐户
  19. Excel cannot open the file ~$Book.xltx
  20. cad如何修改新的文字注释?

热门文章

  1. 需求、需求工程与需求工程师 — 3. 需求工程的构成
  2. 作者:叶郁文,男,中兴通讯股份有限公司产品规划部长。
  3. 【计算机网络】核心知识归纳总结
  4. 洛谷P5724、P5727、P5728、P5729题题解(Java语言描述)
  5. 在小范围内[打表]验证哥德巴赫猜想(洛谷P1579题题解,Java语言描述)
  6. 【C语言】C语言Code的编译与执行
  7. How to remove ROM cfg in MAME
  8. Spring MVC源码分析(一) 说明
  9. Nginx配置SSL后不能正常访问解决方法
  10. 《开源框架那点事儿14》:教计算机程序解数学题