您的位置:首页 > 编程语言 > Python开发

python数据分析与挖掘学习笔记(4)-垃圾邮件自动识别

2017-02-08 17:22 966 查看
这是第四节的内容,主要为垃圾邮件自动识别与分类算法。

简单来说,对于垃圾邮件的预测实际上就是一个分类问题,要实现垃圾邮件的预测,我们可以对垃圾邮件进行特征提取,然后进行分类实现。

具体来说:

1. 对邮件进行切词

2. 构造词典

3. 转为稀疏向量

4. 实现贝叶斯算法

5. 通过贝叶斯算法训练数据

6. 通过贝叶斯算法测试数据

贝叶斯算法的原理就是,对于已知类别,通过特征计算该事物分别属于各个类的概率,概率最大的那个类别就是该事物的估计类别。

首先我们使用python实现贝叶斯算法:

class Bayes:
def __init__(self):
self.length = -1
self.labelcount = dict()
self.vectorcount = dict()

def fit(self, dataSet:list, labels:list):
if(len(dataSet) != len(labels)):
raise ValueError("您输入的测试数组跟类别数组长度不一致")
self.length = len(dataSet[0])  # 测试数据特征值的长度
labelsnum = len(labels)  # 类别所有的数量
norlabels = set(labels)  # 不重复类别的数量
for item in norlabels:
thislabel = item
self.labelcount[thislabel] = labels.count(thislabel)/labelsnum  # self,求的当前类别占类别总数的比例
for vector, label in zip(dataSet, labels):
if(label not in self.vectorcount):  # self
self.vectorcount[label] = []
self.vectorcount[label].append(vector)
print("训练结束")
return self

def btest(self, TestData, labelsSet):
if(self.length == -1):
raise ValueError("您还没有进行训练,请先训练")
# 计算testdata分别为各个类别的概率
lbDict = dict()
for thislb in labelsSet:
p = 1
alllabel = self.labelcount[thislb]
allvector = self.vectorcount[thislb]
vnum = len(allvector)
allvector = numpy.array(allvector).T
for index in range(0, len(TestData)):
vector = list(allvector[index])
#if(vector.count(TestData[index])==0):   # 可以考虑去除全为0的特征,避免p为0.如果数据量小,覆盖不全,建议加上这两句,避免出现p为0;如果数据量大,可去掉这两句
#   continue
p *= vector.count(TestData[index])/vnum
print(p)
lbDict[thislb] = p * alllabel
thislabel = sorted(lbDict, key=lambda x: lbDict[x], reverse=True)[0]
return thislabel

第二步是数据的准备,可以考虑自己爬取自己的邮箱邮件,也考虑下载网上的数据。这里数据准备不是很多,全部为txt格式的文本文件,分为垃圾邮件和非垃圾邮件,文件名分别为f_X.txt和t_X.txt,其中X为数字,表示第几个文件。因此,首先,我们从文件名中解析出每一封邮件的分类数字:

# 从文件名中解析分类数字
def seplabel(fname):
fileStr = fname.split('.')[0]
thisclass = fileStr.split('_')[0]
if(thisclass == "t"):
classNumStr = 1
else:
classNumStr = 0
return classNumStr


下面是实现垃圾邮件的分类预测。

原先我们使用的是邮件内容进行分类的,如果数据量不是很大例如几百条,可以考虑使用邮件title内容进行分词和存储,否则分词太多,可能无法覆盖。

首先是训练数据:

# 垃圾邮件识别
from sklearn.feature_extraction.text import CountVectorizer

# 贝叶斯算法实现
import numpy as npy
import numpy
import jieba
from gensim import corpora,models,similarities
from numpy import *
import operator
from os import listdir

# 训练数据
def trainingDataSet():
labels = []
trainingFileList = listdir('D:./train/')   # 获取目录里面所有文件
m = len(trainingFileList)
cutdata2 = []
for i in range(m):
fnameStr = trainingFileList[i]  # 第i个文件
labels.append(seplabel(fnameStr))  # 得到第i个文件的前缀,并添加到labels列表中
data = open("./train/"+fnameStr, "r", encoding="utf-8").read()
cutdata = jieba.cut(data)
newdata = ""
for item in cutdata:
newdata += item+" "
cutdata2.append(newdata)
# print(cutdata2[0])
# 把测试数据也拿出来,与测试数据整合到一起
testdata = open("./test/t_8.txt", "r", encoding="utf-8").read()
cutdata = jieba.cut(testdata)
newdata = ""
for item in cutdata:
newdata += item+" "
cutdata2.append(newdata)
vectorizer = CountVectorizer()   # 使用sklearn中的包直接生成特征向量
x = vectorizer.fit_transform(cutdata2)
alltz = x.toarray()  # 转换成数组的特征向量
print(alltz)
return labels, alltz


# 训练
labels, trainingMat = trainingDataSet()
bys = Bayes()
bys.fit(trainingMat[:len(trainingMat)-1, :], labels)
# 测试
testdata = trainingMat[len(trainingMat)-1:, :]
labels = [0, 1]
rst = bys.btest(testdata[0], labels)
if(rst == 1):
print("不是垃圾邮件")
else:
print("是垃圾邮件")
训练和测试
后面这部分为什么怎么都删不掉。。%>_<%




















                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐