对本文标题进行分词和提取关键词,本文关键词如下:分类、垃圾邮件分类(spam)、Bayes、SVM、改进版(体现在哪里?)。本文不对Bayes、SVM原理做过多的摄入和解释,主要是使用这些算法做一个基础的baseline以供后续学习和查阅。本文主要内容是讲解以下五方面的内容:
···1.分类中混淆矩阵的本质
···2.垃圾邮件分类原理
···3.对原始垃圾邮件内容的全套数据处理过程实现
···4.垃圾邮件分类代码实现
···5.分类结果的简单说明
1. 分类中混淆矩阵的本质
初学分类算法,算法用得相对比较熟练了,但是以前从来没有考虑过混淆矩阵的数学含义。分类中**混淆矩阵的本质即:假设检验中的两类错误。假设检验中的两类错误**是指在假设检验中,由于样本信息的局限性,势必会产生错误,错误无非只有两种情况,在统计学中,我们一般称为Ⅰ类错误,Ⅱ类错误。具体如下图所示:
2. 垃圾邮件分类原理
2.1.简单的算法原理
a.Bayes公式:
b.SVM
落在分类间隔上的支持向量作为分类的特征。SVM的数学原理很优美,具体内容可以点击给出的链接进行学习和查看,亦或者查阅周志华老师的西瓜书都是很好的选择。
2.2.应用背景
文本挖掘(Text Mining,从文字中获取信息)是一个比较宽泛的概念,这一技术在如今每天都有海量文本数据生成的时代越来越受到关注。目前,在机器学习模型的帮助下,包括情绪分析,文件分类,话题分类,文本总结,机器翻译等在内的诸多文本挖掘应用都已经实现了自动化。
在这些应用中,垃圾邮件过滤算是初学者实践文件分类的一个很不错的开始,例如 Gmail 账户里的“垃圾邮箱”就是一个垃圾邮件过滤的现实应用。下面我们将基于一份公开的邮件数据集 Ling-spam,编写一个垃圾邮件的过滤器。Ling-spam 数据集的下载地址如下:
http://t.cn/RKQBl9c
这里我们已经从 Ling-spam 中提取了相同数量的垃圾邮件和非垃圾邮件,具体下载地址如下:
http://t.cn/RKQBkRu ·····//这里需要注册一下才能够成功下载数据集。
下面我们将通过以下几个步骤,编写一个现实可用的垃圾邮件过滤器。
1>. 准备文本数据;
2>. 创建词典(word dictionary);
3>. 特征提取;
·······a.以词表中对应词汇的词频作为特征;
·······b.以词表中对应词汇的是否出现的标记情况作为特征;
4>. 训练分类器。
最后,我们会通过一个测试数据集对过滤器进行验证。
3. 对原始垃圾邮件内容的全套数据处理过程实现
在大部分的文本挖掘问题中,文本清理都是第一步,即首先要清理掉那些与我们的目标信息无关的词句,本例中也一样。通常邮件里一般都会包含很多无用的字符,比如标点符号,停用词,数字等等,这些字符对检测垃圾邮件没什么帮助,因此我们需要将它们清理掉。文本数据预处理的过程通常包含以下主要步骤:
a.清除停用词 — 像 “and”, “the”, “of” 等这些停用词在英语语句中非常常见。然而,这些停用词对于判定邮件的真实身份并没有什么卵用,所以这些词已经从邮件中被移除。
b.词形还原
c.还需要移除一些非文字类的符号(non-words),比如标点符号或者特殊字符之类的。要实现这一步有很多方法,这里,我们将首先创建一个词典(creating a dictionary),之后再移除这些非文字类的符号。需要指出的是,这种做法其实非常方便,因为当你手上有了一个词典之后,对于每一种非文字类符号,只需要移除一次就 ok 了。
d.词表(dictionary)中自定义的需要过滤掉的无意义词汇
e.以HTML为组织结构的文本数据
from bs4 import BeautifulSoup
import re
import nltk
import os
import os
import numpy as np
from collections import Counter #集合
from sklearn.naive_bayes import MultinomialNB
from sklearn.svm import LinearSVC
from sklearn.metrics import confusion_matrix
from nltk.corpus import stopwords
def mail_text_preprocessing(mail,remove_stopwords):
#1.任务1:去掉html标记
raw_text=BeautifulSoup(mail,'html').get_text()
#2.任务2:去掉非字母字符
letters=re.sub('[^a-zA-Z-]',' ',raw_text) #e-mail这样的形式被分割开了,需要改进。'-'可以排除在外.
words=letters.lower().split() #将英文词汇转换为小写形式
#3.清除停用词====如果remove_stopwords被激活,则进一步去掉评论中的停用词
if remove_stopwords:
stop_words=set(stopwords.words('english'))
#4.初始化stemmer寻找各个词汇的最原始的词根
#stemmer=nltk.stem.PorterStemmer()
#words=[stemmer.stem(w) for w in words if w not in stop_words]
words=[w for w in words if w not in stop_words]
#处理上面保留短'-'引发的问题,去掉单独的短'-'数据。
result=[]
for item in words:
if item=='-':
continue
elif len(item)==1:
#过滤掉单个字母形式的词汇
continue
else:
result.append(item)
return result
#准备文本数据
content1="""Subj