自然语言处理中的文本分类可以做很多事情,比如情感极性的分析、新闻内容的分类,今天要实现的是垃圾邮件的识别。垃圾邮件有一些共同的特征,尤其是表现在一系列词汇上,如"free","discount"等等。有监督的机器学习能从大量预标注的语料中分别学习垃圾邮件和正常邮件的用词规律,从而对新邮件做出预测。

机器学习离不开对对象的形式化表示。而向量化则是其形式化表示的核心。把文档转化成机器能看懂的“语言”——向量和矩阵,才能使机器读得懂、学得会。在表达文本的向量中有两种代表性的向量:词频向量和tf-idf向量。本文分别用词频向量和tf_idf方法建立特征,用朴素贝叶斯分类器给英文的垃圾/非垃圾邮件分类,准确率达到97%。其中,词频向量(98%)的效果比tf_idf方法(96%)准确率更高。这和我一开始想的不一样,毕竟tf-idf方法更高级,计算方法也比机械的词频计数更复杂。所以这也说明,没有一个模型在任何情况下都是最好的,要多次验证选取最好的模型。

本文用到的垃圾邮件预标注数据集:http://www.dt.fee.unicamp.br/~tiago/smsspamcollection/smsspamcollection.zip​www.dt.fee.unicamp.br

解压后把txt文件复制到excel表格中,在两列之间插入一列,写if函数用0和1表示ham/spam,便于作为标签。再在第一列添加列标签:type和Text。把表格存成csv文件。

# 读取csv文件

import pandas as pd

df = pd.read_csv("hamspam", encoding='latin')#因为是英文文本,编码统一为latin防止乱码

df.head()初始数据长这样

什么是词频向量和tf-idf向量?

词频向量是把训练文档中所有的词项拿出来形成集合,如{'apple', 'sale', 'monday', 'business',......},这个集合每个位置上的词是确定的。再用这个集合表示每一篇文档的用词情况。如果该文档中有10个apple,1个sale,3个monday,5个business,那么对于这篇文档,词频向量为{10,1,3,5...}。

tf-idf是另一种获得文档向量的方法,和机械地词频计数不同,它能“智能”地识别出哪些词是能体现这篇文档的特殊性的,而哪些词是无足轻重的。词语之于文档,并不是出现的越多就越有区别性,也并不是出现得越少就越不重要。比如说,虚词、人称代词在任何文档里都是很多的,比如a, an, the, she, it...,但是它们对于区分邮件是否为垃圾邮件起不到作用,有时甚至会干扰真正重要的词汇的识别,tf-idf方法正好屏蔽了这样的干扰。它让在所有文档中都频繁出现的词变得毫无意义,秘诀在于“逆文档频率”——也就是N/N(w)上。N表示文档总数,我们有5572个邮件。N(w)表示包含词w的文档数量。某个词的tf-idf,也就是这个词的重要性,是词频乘以逆文档频率。

我们假设一个极端情况:假如每个文档里都有个“you”,那么you的“逆文档频率”就是5572/5572=1。

一般来说,为了平滑起见,“逆文档频率”一般还要取log(默认以2为底)。这样一来'you'的逆文档频率就是log1=0。

那么如果假设you在邮件中的总词频是6800,但是因为它的逆文档频率为0,那么'you'的tf-idf就是6800*0=0。这就是我们所假设的极端情况:如果一个词在每一个文档中都出现,那么它对于区分文档的作用为0。

接下来用代码实现着两种获得向量表示的方法吧~

#声明两种构建文本特征的模型

#方法一:基于词频的文本向量

from sklearn.feature_extraction.text import CountVectorizer

vectorizer1 = CountVectorizer(binary=True)

#方法2:tfidf方法

from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer2=TfidfVectorizer(binary=True)

分别用两种方法构建文本向量

X1 = vectorizer1.fit_transform(df.Text)

X2 = vectorizer2.fit_transform(df.Text)

y = df.type

把数据分为训练和测试数据

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X1, y, test_size=0.20, random_state=100)

print ("训练数据中的样本个数: ", X_train.shape[0], "测试数据中的样本个数: ", X_test.shape[0])

#上下两种每次只运行一种

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X2, y, test_size=0.20, random_state=100)

print ("训练数据中的样本个数: ", X_train.shape[0], "测试数据中的样本个数: ", X_test.shape[0])

利用朴素贝叶斯做训练

任务是求状态序列X(X1,X2,X3...),使它最好地解释观察值Y(是否垃圾邮件)。也就是求Y在已知X情况下的概率P(Y|X)为最大值时,X为多少。(就相当于是哪些关键词使得Y是垃圾邮件/非垃圾邮件)

根据贝叶斯公式:

P(Y∣X)=P(Y)P(X∣Y)​/P(X)

由于P(X)、P(Y)是定值,可以从数据中直接计算获得,因此只需要算出P(X|Y)的最大值。注意,里面的X不是一个事件,而是一系列属性(X1,X2,....Xn),在垃圾邮件识别的任务中,X的每一个属性相当于单词集合中的每一个词。因此:

P(X|Y)=P(X1|Y)P(X2|Y)...P(Xn|Y)

在实际情况中,条件都是互相依赖的,一个词出现的概率与它的所有前序词相关:P(Xn)=P(Xn|X1,X2,...Xn-1)。但是如果这样代进去计算,所需要的时间复杂度就会成指数级上升,而且不能保证效果好。尤其是在当前的邮件分类任务中,由于形成的向量中,词与词之间本身就是独立的,其中的依赖关系已经在构建向量的时候被取消了,因此朴素贝叶斯法在这个任务中再合适不过了。

因此朴素贝叶斯在这里做了个重要的事:它把这个式子简化为每一个自变量都是独立的,不必依赖前序属性。P(Xn)=P(Xn), P(X)=P(X1)P(X2)...P(Xn)。这就是“朴素”的含义。

因此: P(X|Y)=P(X1|Y)P(X2|Y)...P(Xn|Y)

要求的就是上式取得最大值时X的序列(X1,X2...Xn)

总结一下朴素贝叶斯为什么朴素:假定每一个属性条件Xi是独立的。每个自变量特征都只与y值有直接关联,而互相之间没有关联。在垃圾邮件任务里面,向量里面的每个词项就相当于每个特征,它只和邮件是不是垃圾邮件相关,但互相之间没有关系。比如“sale”这个词只和预测值“垃圾/非垃圾邮件”有关,和其中的另一个词“Christmas”无关。(尽管它们有可能一起出现)。这样大大简化了后验概率的计算,节省了算力。

原理讲完了,现在用sklearn实现朴素贝叶斯吧:

from sklearn.naive_bayes import MultinomialNB#选取多项式分布贝叶斯,适用于多项式

from sklearn.metrics import accuracy_score

clf = MultinomialNB(alpha=1, fit_prior=True)#alpha用于平滑化,默认为1即可;fit_prior:是否学习类的先验概率,默认是True

clf.fit(X_train, y_train)

y_pred = clf.predict(X_test)

print("accuracy on test data: ", accuracy_score(y_test, y_pred))

打印混淆矩阵

from sklearn.metrics import confusion_matrix

confusion_matrix(y_test, y_pred, labels=[0, 1])

结果显示,两种获得属性序列的方法(词频向量 vs. tf-idf)获得的准确率分别是0.98和0.96。有了这个分类器,对于新输入的文本(邮件内容),它就可以帮你判断是不是垃圾邮件啦~

python发邮件被认定为垃圾邮件_【python文本分类】20行代码识别垃圾邮件相关推荐

  1. Python用20行代码实现完整邮件功能 [完整代码+建议收藏]

    大家好,我是Lex 喜欢欺负超人那个Lex 擅长领域:python开发.网络安全渗透.Windows域控Exchange架构 今日重点:python脚本实现发送邮件,邮件添加附件,读取接收邮件等功能. ...

  2. python爬取付费直播的视频_教你用20行代码爬取直播平台弹幕(附源码)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. Python爬虫.数据分析.网站开发等案例教程视频免费在线观看 https://space. ...

  3. python获取虎牙弹幕_教你用20行代码爬取直播平台弹幕(附源码)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. Python爬虫.数据分析.网站开发等案例教程视频免费在线观看 https://space. ...

  4. python黑科技:Python大佬用20行代码带你打造一个微信聊天机器人,真神了~

    如何用20行Python代码打造一个微信群聊助手? 1.安装python环境 2.安装python的itchat库 3.安装itchat库 4.Linux 5.申请图灵机器人API和key 6.编写p ...

  5. Python用20行代码实现一个验证码的输入与验证(完整源码)

    我们平常上网处处可见需要输入验证码的地方,利用Python的random()模块,其实我们只用简单20行代码就能实现.下为效果图,能识别是否正确: 其中也没有复杂的函数嵌套.函数递归,逻辑也比较简单, ...

  6. 女神相册密码忘记了,我只用Python写了20行代码

    ​视频地址 我用20行代码,帮女神破解相册密码 一.事情是这样的 今早上班,公司女神小姐姐说,她去年去三亚旅游的照片打不开了 好奇问了一下才知道. 原来是,她把照片压缩了,而且还加了密码. 但是密码不 ...

  7. Python 教你训练一个98%准确率的微博抑郁文本分类模型(含数据)

    Paddle是一个比较高级的深度学习开发框架,其内置了许多方便的计算单元可供使用,我们之前写过PaddleHub相关的文章: 1.Python 识别文本情感就这么简单 2.比PS还好用!Python ...

  8. python人物抠图算法_比PS还好用!Python 20行代码批量抠图

    抠图前 vs Python自动抠图后 在日常的工作和生活中,我们经常会遇到需要抠图的场景,即便是只有一张图片需要抠,也会抠得我们不耐烦,倘若遇到许多张图片需要抠,这时候你的表情应该会很有趣. Pyth ...

  9. python开发ps插件_你还在用PS?Python 20行代码批量抠图

    抠图前 vs Python自动抠图后 在日常的工作和生活中,我们经常会遇到需要抠图的场景,即便是只有一张图片需要抠,也会抠得我们不耐烦,倘若遇到许多张图片需要抠,这时候你的表情应该会很有趣. Pyth ...

  10. python随机生成大写字母_python随机生成大小写字母数字混合密码(仅20行代码)

    用简单的方法生成随机性较大的密码 仅用20行代码随机生成密码 核心思路:利用random模块 random模块随机生成数字,大小写字母,循环次数 while循环+随机生成的循环次数-->随机pl ...

最新文章

  1. Java的死锁的例子
  2. 通过修改EIP寄存器实现强行跳转并且注入DLL到目标进程里
  3. 006_logback体系结构
  4. MQTT+ActiveMQ实现消息推送
  5. cisco交换机命令大全(5)
  6. python mysql 错误处理_Python-MySQL中的错误处理
  7. EDM邮件营销时应该远离的8大不良做法
  8. LINUX 第六章 Open WebMail完全安装手册
  9. 西铁院云计算机室与应用,关于开展“云桌面应用”技术服务的通知
  10. cacti mysql-bin_Cacti环境搭建(LNMP环境)
  11. Android开发:Menu选项菜单
  12. 《Android Design》 4.4 中文版
  13. Linux内核入门(二)——用户态向内核态切换
  14. 视频直播源代码,视频文件当中的存储方法
  15. linux取ip地址命令,linux下命令取IP地址的多种方法
  16. 绝地反击 我的战胜贫困的经历01 转载 整理
  17. 【游戏程序设计】鼠标交互
  18. 操作系统-为什么进程之间的通信必须借助操作系统内核功能?
  19. T007V-采购订单税码对应的税率所在后台表
  20. java循环输出abcd_java 输 abcd 输出其所有排列情况 permutate

热门文章

  1. 2019年中国锂电池产业竞争格局
  2. (转载)基于Overfeat的图片分类、定位、检测
  3. 项目开发设计文档怎么写,范文。
  4. Sklearn 划分训练集和测试集
  5. PMP第十章:项目沟通管理
  6. 见微知著:语义分割中的弱监督学习
  7. slitaz linux 包管理器,SliTaz
  8. DOS+DNS放大攻击工具编写
  9. 51单片机实战教程基础硬件篇(三 51单片机开发板设计)
  10. 集成运算放大器及其应用