使用朴素贝叶斯过滤垃圾邮件

简介: 使用朴素贝叶斯过滤垃圾邮件

使用朴素贝叶斯过滤垃圾邮件


1.问题描述:

现有50封电子邮件,存放在数据集task1中,试基于朴素贝叶斯分类器原理,用Python编程实现对垃圾邮件和正常邮件的分类。采用交叉验证方式并且输出分类的错误率及分类错误的文档。


2.实验原理:

朴素贝叶斯:


基于概率论的分类方法:朴素贝叶斯,要求分类器给出一个最优的类别猜测结果,同时给出这个猜测的概率估计值。一种有效计算条件概率的方法称为贝叶斯准则,贝叶斯准则告诉我们如何交换条件概率中的条件与结果,即如果已知$ P(x|c)$,要求 P ( c ∣ x ) ,那么可以使用下面的计算方法:

image.png

于是,可以定义贝叶斯分类准则为:若那么属于类别若$ P(c1|x,y)>P(c2|x,y)$, 那么属于类别 C1


若那么属于类别若 P ( c 1 ∣ x , y ) < P ( c 2 ∣ x , y ) , 那么属于类别 C2


使用贝叶斯准则,可以通过已知的三个概率值来计算未知的概率值。


由词向量计算:


由于这里的特征是词向量,于是重写贝叶斯准则,将之前的x、y 替换为w。粗体w表示这是一个向量,即它由多个数值组成,长度N为词典长度。在词袋模型中,数值个数与词典中的词个数相同,贝叶斯准则公式如下:

P ( c i ∣ w ) = P ( w ∣ c i ) P ( c i ) P ( w )


我们使用上述公式,对每个类别计算该值,然后比较这两个概率值的大小。首先通过类别(垃圾邮件或正常邮件)中样本数除以总的样本数来计算概率$ P(ci)$,接下里计算 P ( w ∣ c i )  ,这里使用朴素贝叶斯假设,若将w展开为一个个独立特征,那么就可以将上述概率写作$ P(w0,w1,w2,…wN|ci)$ ,这里假设所有词都互相独立,该假设也称作条件独立性假设,它意味着可以使用 如下公式计算上述概率:

P ( w ∣ c i ) = P ( w 0 ∣ c i ) P ( w 1 ∣ c i ) P ( w 2 ∣ c i ) . . . P ( w N ∣ c i )


这样就极大的简化了计算过程。


具体步骤:


1.设D是词向量集合,每个词向量用一个N维向量 $w={w0,w1,w2,…,wN} $表示。


2.假定有m个类 c i = { c 1 , c 2 , . . . , c m },给定词向量w,分类法将预测w属于最高后验概率的类,即,朴素贝叶斯分类法预测w属于类ci,当且仅当

P ( c i ∣ w ) > P ( c j ∣ w ) , 1 ≤ j ≤ m , j ≠ i


其中,P(ci|w) 最大的类 ci 称为最大后验概率。


3.做条件独立性假设,于是将公式简化:

image.png


4.训练:利用公式,对每个词向量每个类别分别计算条件概率,得出 P 0 v , P 1 v , P s p a m P0v,P1v,PspamP0v,P1v,Pspam ,分类器训练完成。


5.应用:利用贝叶斯分类准则,对预测词向量分别计算$ P0,P1$ ,选择最大概率对应的分类作为目标预测结果。


3.代码实现:

1.数据处理:


1)需要从文本中获取特征,需要拆分文本,分成词条


2)获取数据字典


3)向量化处理,方便进行特征提取


实现:


分词:

def textParse(bigString):
    import re
    listOfTokens=re.split('\W',bigString)
    #匹配非字母数字下划线
    return [tok.lower() for tok in listOfTokens if len(tok)>2] 
  #取出掉长度过短的单词


获取数据字典:

def creatVocabList(dataset):
    vocabSet=set([])
    for document in dataset:
         vocabSet=vocabSet|set(document)  #两个集合的并集
    return list(vocabSet)


向量化处理:


这里可以使用词集模型或者词袋模型:


1)词集模型:只关注token是否出现,并不关注出现的次数。

def setOfWords2Vec(vocabList, inputSet):
  returnVec = [0]*len(vocabList)
  for word in inputSet:
    if word in vocabList:
      return Vec[vocabList.index(word)] = 1
  return returnVec


2)词袋模型:关注token的出现次数,有较好的处理结果

#词袋模型
def bagOfWords2Vec(vocabList,inputSet): #参数分别为词汇表,输入文档
    returnVec=[0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)]+=1
    return returnVec


2.训练模型:


朴素贝叶斯是基于概率的分类器,其训练过程就是计算各个概率的过程。


流程为:

对每篇训练文档:
===对每个类别:
======如果词条出现在文档中,则增加该词条的计数
======增加所有出现词条的计数值
===对每个类别:
======对每个词条:
=========将该词条的数目除以总词条的数目得到条件概率
===返回每个类别的条件概率


代码:

#朴素贝叶斯分类函数
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass): #参数分别为:要分类的向量以及使用trainNB0()计算得到的三个概率
    p1=sum(vec2Classify*p1Vec)+np.log(pClass)
    p0=sum(vec2Classify*p0Vec)+np.log(1-pClass)
    if p1>p0:
        return 1  
    else:
        return 0


3.测试:


在50封邮件中,正常邮件和垃圾邮件各占25,在在其中随机抽取10封电子邮件,预测其所在的类别。

#测试算法:使用朴素贝叶斯交叉验证。同时保存分类模型的词汇表以及三个概率值,避免判断时重复求值
def spamTest():
    docList = []  # 文档(邮件)矩阵
    classList = []  # 类标签列表
    for i in range(1, 26):
        wordlist = textParse(open('spam/{}.txt'.format(str(i))).read())
        docList.append(wordlist)
        classList.append(1)
        wordlist = textParse(open('ham/{}.txt'.format(str(i))).read())
        docList.append(wordlist)
        classList.append(0)
    vocabList = creatVocabList(docList)  # 所有邮件内容的词汇表
    import pickle
    file=open('vocabList.txt',mode='wb')  #存储词汇表
    pickle.dump(vocabList,file)
    file.close()
    # 对需要测试的邮件,根据其词表fileWordList构造向量
    # 随机构建40训练集与10测试集
    trainingSet = list(range(50))
    testSet = []
    for i in range(10):
        randIndex = int(np.random.uniform(0, len(trainingSet)))
        testSet.append(trainingSet[randIndex])
        del (trainingSet[randIndex])
    trainMat = []  # 训练集
    trainClasses = []  # 训练集中向量的类标签列表
    for docIndex in trainingSet:
        # 使用词袋模式构造的向量组成训练集
        trainMat.append(bagOfWords2Vec(vocabList, docList[docIndex]))
        trainClasses.append(classList[docIndex])
    p0v,p1v,pAb=trainNB0(trainMat,trainClasses)
    file=open('threeRate.txt',mode='wb') #用以存储分类器的三个概率
    pickle.dump([p0v,p1v,pAb],file)
    file.close()
    errorCount=0
    for docIndex in testSet:
        wordVector=bagOfWords2Vec(vocabList,docList[docIndex])
        if classifyNB(wordVector,p0v,p1v,pAb)!=classList[docIndex]:
            errorCount+=1
    return float(errorCount)/len(testSet)


4.测试结果:

由于测试集的生成是随机的,所以分类器误分率每次运行结果不一致。通过运行10次的平均值作为分类器的分类效果:


机器学习导论代码地址:


机器学习导论

目录
相关文章
|
机器学习/深度学习 存储 自然语言处理
简单聊一聊大模型微调技术-LoRA
LoRA(Low-Rank Adaptation)是一种用于减少大模型微调中参数数量和计算资源的技术。通过引入低秩分解,LoRA 仅更新少量参数,从而显著降低显存消耗和计算需求。适用于大规模预训练模型的微调、跨领域迁移学习、低资源设备部署和多任务学习等场景。例如,在微调 BERT 模型时,LoRA 可以仅调整约 0.1% 的参数,保持与全量微调相近的性能。
3090 0
|
网络协议 测试技术 应用服务中间件
|
机器学习/深度学习 算法 Python
python与朴素贝叶斯算法(附示例和代码)
朴素贝叶斯算法以其高效性和优良的分类性能,成为文本处理领域一项受欢迎的方法。提供的代码示例证明了其在Python语言中的易用性和实用性。尽管算法假设了特征之间的独立性,但在实际应用中,它仍然能够提供强大的分类能力。通过调整参数和优化模型,你可以进一步提升朴素贝叶斯分类器的性能。
671 0
|
存储 关系型数据库 分布式数据库
PolarDB PG 版冷热数据分层功能介绍
本文介绍了云原生数据库PolarDB PG版的冷热数据分层存储功能,涵盖其原理、特性及最佳实践。冷热分层存储通过将冷数据归档至OSS(对象存储服务),实现低成本高效存储,同时保持SQL操作透明性和性能优化。支持多种分层模式,如表与索引分层、大字段独立归档等,并提供压缩和缓存机制以提升访问速度。此外,还介绍了如何通过DDL语句轻松转存数据至OSS,以及一系列最佳实践,包括自动冷热分层、无锁表转存和一键转存等功能。
1116 36
|
负载均衡 监控 网络虚拟化
|
人工智能 自然语言处理 搜索推荐
10分钟构建AI客服:阿里云技术解决方案评测
在数字化转型的浪潮中,企业对客户服务的即时性和个性化需求愈发迫切。阿里云推出的“10分钟构建AI客服并应用到网站、钉钉、微信中”的技术解决方案,为企业提供了一个快速、低成本的AI客服部署方案。本文将从部署流程、用户体验、成本效益等方面对这一方案进行深入评测。
1419 4
|
传感器 机器学习/深度学习 算法
Nvidia Isaac Sim介绍 入门教程 2024(1)
Nvidia Isaac Sim是一个为NVIDIA Omniverse平台开发的机器人仿真工具包,提供高保真度的物理仿真和多传感器RTX渲染,支持ROS2并能够生成合成数据集,用于机器人的设计、调试、训练和部署。
3389 0
|
机器学习/深度学习 算法 数据挖掘
Python实现聚类(Kmeans)分析客户分组
Python实现聚类(Kmeans)分析客户分组
Python实现聚类(Kmeans)分析客户分组
|
算法 Serverless
使用朴素贝叶斯算法过滤垃圾邮件
使用朴素贝叶斯算法过滤垃圾邮件
244 2
计算机网络——计算机网络的性能指标(上)-速率、带宽、吞吐量、时延
计算机网络——计算机网络的性能指标(上)-速率、带宽、吞吐量、时延
1824 1

热门文章

最新文章