码农小屋 码农小屋
  • 首页
  • 文章
    • Python
    • 计算机基础
    • C语言
    • Java
    • 数据库
    • Linux
  • 资源
  • 随笔
  • 优秀软件
  • 24h新鲜事
  • 专题
  • 留言板
  • 注册 登录
立即登录
0文章
0评论
0获赞
  • 首页
  • 博客中心
    • 文章
    • 资源
  • 随笔
  • 优秀软件
  • 24h新鲜事
  • 专题
  • 留言板
主页 › 文章 › Python › 朴素贝叶斯实战——垃圾邮件过滤
#Python#

朴素贝叶斯实战——垃圾邮件过滤

3月前
145 0 3

以在线社区留言为例,为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标志为内容不当。过滤这类内容是一个很常见的需求。 对此问题建立两个类型:侮辱类和非侮辱类,使用1和0分别表示。
我们把文本看成单词向量或者词条向量,也就是说将句子转换为向量。简单起见,我们先假设已经将本文切分完毕,存放到列表中,并对词汇向量进行分类标注。

示例:使用朴素贝叶斯对电子邮件进行分类

  • (1)收集数据:提供文本文件。
  • (2)准备数据:将文本文件解析成词条向量。
  • (3)分析数据:检查词条确保解析的正确性。
  • (4)训练算法:使用我们之前建立的trainNB0()函数。
  • (5)测试算法:使用classifyNB(),并且构建一个新的测试函数来计算文档集的错误率。
  • (6)使用算法:构建一个完整的程序对一组文档进行分类,将错分的文档输出到屏幕上。

注:本文将不会对朴素贝叶斯算法的具体实现进行详解,如有需要请点击按钮查看:

机器学习——基于概率论的分类方法:朴素贝叶斯

收集数据:从文本文件中读入

对于一个文本字符串,可以使用Python的string.split()将其切分。

另外,我们发现有些句子中的单词是大写的。如果目的是句子查找,那么这个特点会很有用。但这里的文本只看成词袋,所以我们希望所有词的形式都是统一的, 不论它们出现在句子中间、结尾还是开头。

Python中有一些内嵌的方法, 可以将字符串全部转换成小写( .1ower() )或者大写( .upper()),借助这些方法可以达到目的。于是,可以进行如下处理:

函数说明:接收一个大字符串并将其解析为字符串列表

def textParse(bigString):
    import re
    wordList = []
    listOfTokens = re.split(r'\W', bigString)
    for tok in listOfTokens:
        if len(tok) > 2:
            wordList.append(tok.lower())
    return wordList

函数说明:从文件中读取数据

def getDataset():
    postingList = []
    classVec = []
    for i in range(1, 26):
        wordList = textParse(open('email/spam/%d.txt' % i,
                        'r').read())
        postingList.append(wordList)
        classVec.append(1)
        wordList = textParse(open('email/ham/%d.txt' % i,
                       'r').read())
        postingList.append(wordList)
        classVec.append(0)
    return postingList, classVec

做出以上处理后,大致的结果如下:

朴素贝叶斯实战——垃圾邮件过滤-码农小屋

准备数据:将文本文件解析成词条向量

函数说明:将切分的实验样本词条整理成不重复的词条列表,也就是词汇表
Parameters:
dataSet - 整理的样本数据集
Returns:
vocabSet - 返回不重复的词条列表,也就是词汇表

def createVocabList(postingList):
vocabList = set([])
for document in postingList:
vocabList = vocabList | set(document)
vocabList = list(vocabList)
return vocabList

做出以上处理后,大致的结果如下:

朴素贝叶斯实战——垃圾邮件过滤-码农小屋

分析数据:检查词条确保解析的正确性

函数说明:根据vocabList词汇表,将postingList转化成词袋模式数据,数据的每个元素为n,n用来统计该词汇在文中出现的次数

Parameters:

vocabList - createVocabList返回的列表

postingList -整理的样本数据集

Returns:

trainMat – 转化为词袋模式的数据集

def setOfWords2Vec(vocabList, postingList):
trainMat = []
for postinDoc in postingList:
returnVec = [0] * len(vocabList)
for word in postinDoc:
if word in vocabList:
returnVec[vocabList.index(word)] += 1
trainMat.append(returnVec)
return trainMat

做出以上处理后,大致的结果如下:

朴素贝叶斯实战——垃圾邮件过滤-码农小屋

训练算法:使用我们之前建立的trainNB0()函数

函数说明:朴素贝叶斯分类器训练函数
Parameters:
trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵
trainCategory - 训练类别标签向量,即loadDataSet返回的classVec
Returns:
p0Vect - 侮辱类的条件概率数组
p1Vect - 非侮辱类的条件概率数组
pAbusive -文档属于侮辱类的概率

def trainNB0(trainMat, classVec):
numTrainDocs = len(trainMat)
numWords = len(trainMat[0])
pAbusive = sum(classVec)/float(numTrainDocs)
p0Num = np.ones(numWords)
p1Num = np.ones(numWords)
p0Denom = 2.0
p1Denom = 2.0
for i in range(numTrainDocs):
if classVec[i] == 1:
p1Num += trainMat[i]
p1Denom += sum(trainMat[i])
else:
p0Num += trainMat[i]
p0Denom += sum(trainMat[i])
p1Vect = np.log(p1Num/p1Denom)
p0Vect = np.log(p0Num/p0Denom)
return p0Vect, p1Vect, pAbusive

构建算法:实施朴素贝叶斯进行分类

函数说明:实施文本预测的分类
Parameters:
testEntry - 待分类的词条数组
p0Vec - 侮辱类的条件概率数组
p1Vec - 非侮辱类的条件概率数组
pClass1 - 文档属于侮辱类的概率
Returns:
result - 预测结果

def classifyNB(testEntry, p0Vect, p1Vect, pAbusive, vocabList):
    testMat = setOfWords2Vec(vocabList, testEntry)
    p1 = np.sum(testMat * p1Vect, axis=1) + np.log(pAbusive)
    p0 = np.sum(testMat * p0Vect, axis=1) + np.log(1.0-pAbusive)
    result = [0]*len(testEntry)
    for i in range(len(testMat)):
        print("p1=%.2f,p0=%.2f" % (p1[i], p0[i]))
        if p1[i] > p0[i]:
            print("%s属于侮辱类" % testEntry[i])
            result[i] = 1
        else:
            print("%s属于非侮辱类" % testEntry[i])
    return result

使用算法:使用分类器进行分类

函数说明:测试朴素贝叶斯分类器
Parameters:
无
Returns:
无

def testingNB():
    postingList, classVec = getDataset()
    vocabList = createVocabList(postingList)
    trainMat = setOfWords2Vec(vocabList, postingList)
    p0V,p1V,pAb = trainNB0(trainMat, classVec)
    testEntry = [[' program', 'professional', 'connection'],
                          ['volume', 'only']]
    classifyNB(testEntry, p0V, p1V, pAb, vocabList)

做出以上处理后,最终预测结果如下:

朴素贝叶斯实战——垃圾邮件过滤-码农小屋

交叉验证:计算分类器的错误率

函数说明:交叉验证。从实验数据中随机选择一定比例的数据作为测试数据,其余数据作为训练数据
Parameters:
postinglist - 文中读取到的实验数据特征值部分
lasslist - 文中读取到的实验数据目标值部分
testRatio - 测试数据占比,默认为0.20
Returns:
trainSet: - 训练数据特征值部分
testSet - 测试数据特征值部分
trainlasses - 测试数据目标值部分
testClasses - 测试数据分类目标值部分

def getTrainTest(postingList, classList, testRatio=0.20):
m = len(postingList)
numTestVecs = int(m * testRatio)
randomIndex = np. random. randint(0, 50, numTestVecs)
testSet = []
testClasses = []
trainSet = []
trainClasses = []
for i in range(50):
if i in randomIndex:
testSet.append(postingList[i])
testClasses.append(classList[i])
else:
trainSet.append(postingList[i])
trainClasses.append(classList[i])
return trainSet, testSet, trainClasses, testClasses

函数说明:执行5次交叉验证,计算平均错误率
Parameters:
无
Returns:
无

def spanTest():
    relist = []
    for j in range(5):
        postingList, classList = getDataset()
        trainSet, testSet, trainClasses, testClasses
                            = getTrainTest(postingList, classList)
        vocabList = createVocabList(trainSet)
        trainMat = setOfWords2Vec(vocabList, trainSet)
        p0V, p1V, pAb = trainNB0(trainMat, trainClasses)
        errorCount = 0.0
        result = classifyNB(testSet, p0V, p1V, pAb, vocabList)
        for i in np.arange(len(testClasses)):
            if result[i] != testClasses[i]:
                errorCount += 1.0
        relist.append(errorCount / float(len(testClasses)))
        print("第%d次错误率为:%.2f" % (j + 1, relist[j]))
    error = sum(relist)
    error /= 5
    print("平均的错误率为:%.2f" % error)

做出以上处理后,错误率如下:

朴素贝叶斯实战——垃圾邮件过滤-码农小屋

写在最后

这就是实施朴素贝叶斯算法的全部过程,包括预测分类以及计算分类器错误率,并且错误率也在接受范围之内。到此为止也就基本解决了简单的邮件分类这个实际问题,这也是朴素贝叶斯的重要应用。

垃圾邮件数据
下载
密码:866888
3
Mr Gu
等 3 人赞过
相关文章
机器学习——K-均值聚类算法
Logistic回归实战——病症状预测
机器学习——Logistic回归
线性回归实战——使用岭回归预测二手乐高的价格
机器学习——线性回归算法
评论 (0)
再想想
Mr Gu管理员
Better late than never.
45文章 1评论 51获赞
文章推荐
ZIP Pro 3 – 文件压缩分享加密管理套件
2月前
Uninstall Tool-专业的软件卸载工具
3月前
Speccy:优秀的硬件检测工具
4月前
CleanMyPC-专为 Windows打造的清理工具
4月前
Internet Downloader Manager-一款专业的Win下载工具
4月前
Wise Care 365-Windows 系统清理和加速工具
4月前
新鲜事
新Mac太牛:在电脑上运行iPhone、iPad的软件、游戏
2月前
自从苹果M1芯片发布之后,使用这颗芯片的Mac电脑,就被大家认为是有史以来最强的Mac,因为这颗小米的芯片,在性能上已经打败了苹果使用的最高端的i9芯 ...[阅读全文]
苹果发布会总结:一个芯片,三款产品!苹果这把棋下得可真深
2月前
北京时间11月11日凌晨2点,苹果在圣何塞召开了本年度最后一场发布会。在这次发布会上,苹果推出了基于ARM架构的全新M1自研处理器。 ...[阅读全文]
荣耀命运落定:救了自己,也救华为
2月前
华为出售荣耀一事终于落槌。 ...[阅读全文]
发布会停不下来,苹果下月发布新Mac
3月前
今年的苹果有些与众不同,往年只开一次秋季发布会,今年在九月十月连开两场。 ...[阅读全文]
iPhone 12 开启 5G 续航锐减,苹果回应
3月前
对于今年的 iPhone 12 来说,除了回归直角边框设计之外,最大的亮点就是 5G 了。 ...[阅读全文]
华为Mate40正式发布
3月前
定位高端旗舰的华为Mate40系列共发布四款新机:华为Mate40(6.5英寸)、华为Mate40 Pro(6.76英寸)、华为Mate40 Pro+ ...[阅读全文]
更多
  • 专题
  • 文章
  • 友情链接
  • 留言板
Copyright © 2020-2021 码农小屋. 苏ICP备20033168号