python数据分析与挖掘学习笔记-垃圾邮件自动识别
Posted 小胖子小胖子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python数据分析与挖掘学习笔记-垃圾邮件自动识别相关的知识,希望对你有一定的参考价值。
这是第四节的内容,主要为垃圾邮件自动识别与分类算法。
简单来说,对于垃圾邮件的预测实际上就是一个分类问题,要实现垃圾邮件的预测,我们可以对垃圾邮件进行特征提取,然后进行分类实现。
具体来说:
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("是垃圾邮件")
训练和测试
后面这部分为什么怎么都删不掉。。%>_<%
以上是关于python数据分析与挖掘学习笔记-垃圾邮件自动识别的主要内容,如果未能解决你的问题,请参考以下文章
python数据分析与挖掘学习笔记-交通路标自动识别实战与神经网络算法
python 和 scikit-learn 实现垃圾邮件过滤
python数据分析与挖掘学习笔记-电商网站数据分析及商品自动推荐实战与关联规则算法
python数据分析与挖掘学习笔记-电商网站数据分析及商品自动推荐实战与关联规则算法