最码农 最码农
  • 首页
  • 动态广场
  • 精选栏目
  • 闲言碎语
  • 左邻右里
  • 笔记屋
  • 注册
  • 登录
首页 › Python › 朴素贝叶斯实例——垃圾邮件过滤

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

Cosy
2年前Python阅读 1,463

以在线社区留言为例,为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标志为内容不当。

过滤这类内容是一个很常见的需求。 对此问题建立两个类型:侮辱类和非侮辱类,使用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)

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

朴素贝叶斯实例——垃圾邮件过滤-最码农

写在最后

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

人工智能 分类器 算法
赞赏 赞(5) 收藏(0)
基于概率论的分类方法:朴素贝叶斯
上一篇
OSI——7层的简单理解
下一篇
再想想
暂无评论
随 机 推 荐
基于Layui的兽音译者加密页面
Hadoop 小文件优化方法
Hadoop2.x 和 Hadoop3.x 的新特性
MapReduce框架原理-InputFormat数据输入
Hadoop概论(一)—— 开篇词
Hadoop HDFS(二)
Hadoop HA 高可用
Hadoop 数据压缩
5
  • 5
  • 0
介绍

我们致力于打造一个原创的计算机相关技术的博客网站,旨在为访客提供一个优质的计算机技术教程交流平台。网站开辟了很多于计算机相关的栏目,并且收集了不少实用资源,同时也鼓励欢迎访客一起分享、交流、学习。

灵魂推荐
Veer图库 数码荔枝
栏目标题
首页 动态广场 精选栏目 闲言碎语 左邻右里 笔记屋
Copyright © 2021-2023 最码农. 苏ICP备20033168号
  • 首页
  • 动态广场
  • 精选栏目
  • 闲言碎语
  • 左邻右里
  • 笔记屋
# 教程 # # Hadoop # # HDFS # # 人工智能 # # 算法 #
Cosy
即使世界毁灭,也总有回光返照的那一刻
90
文章
3
评论
425
喜欢