【机器实战学习】朴素贝叶斯 python代码实现

2023-11-16

朴素贝叶斯

输入数据创造词汇表 代码实现:
# coding:UTF-8
def loadDataSet():
    """
    创建了一下实验样本
    :return:词条且分的文档集合,类别标签的集合,自动检测侮辱性的语言
    """
    postingList = [['my', 'dog', 'has', 'flea', \
                    'problem', 'help', 'please'],
                   ['maybe', 'not', 'take', 'him', \
                    'to', 'dog', 'park', 'stupid'],
                   ['my', 'dalmation', 'is', 'so', 'cute', \
                    'I', 'love', 'him'],
                   ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                   ['mr', 'licks', 'ate', 'my', 'steak', 'how', \
                    'to', 'stop', 'him'],
                   ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0, 1, 0, 1, 0, 1]
    return postingList, classVec


def createVocabList(dataSet):
    """
    创建一个包含在所有文档中出现的不重复词的列表
    一个不重读此表set返回
    求并集
    :param dataSet:
    :return:
    """
    vocabSet = set([])
    for document in dataSet:
        vocabSet = vocabSet | set(document)
        return list(vocabSet)


def setOfWords2Vec(vocabList, inputSet):
    """
    函数首先创建一个和词汇表登场的向量 全部设置为0,遍历文档中的所有单词,如果出现了词汇表中的单词,则将其元素设置为1
    :param vocabList: 词汇表以及某个文档
    :param inputSet:
    :return: 输出文档向量 向量的每一元素为1或者0,分别表示词汇表中单词在输入文档中是否出现
    """
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else:
            print('the word: %s is not in my Vocabulary!' % word)
    return returnVec


def main():
    listOPosts, listClasses = loadDataSet()
    myVocabList = createVocabList(listOPosts)
    print('词汇表:',myVocabList)
    print('对照组:', listOPosts[0])
    print(setOfWords2Vec(myVocabList, listOPosts[0]))
    print(setOfWords2Vec(myVocabList, listOPosts[3]))



if __name__ == '__main__':
    main()
执行截图:

image-20221009161443748

image-20221009162635444

训练算法:从词向量计算概率:

前面介绍了如何将一组单词转换为一组数字,接下来如何使用这些数据计算概率,

程序4-2 朴素贝叶斯分类器训练函数
def trainNB0(trainMatrix, trainCategory):
    """
    :param trainMatrix: 文档矩阵
    :param trainCategory: 每篇文档类别标签所构成的向量
    :return:
    """
    numTrainDocs = len(trainMatrix)  # 总文档的长度
    numWords = len(trainMatrix[0])  # 第一个文档关键词长度
    pAbusive = sum(trainCategory) / float(numTrainDocs)  # 侮辱性词汇占的概率
    p0Num = zeros(numWords)  # 第一个词组对应的0矩阵
    p1Num = zeros(numWords)  # 第一个词组对应的0矩阵
    p0Denom = 0.0
    p1Denom = 0.0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = p1Num / p1Denom
    p0Vect = p0Num / p0Denom
    return p0Vect, p1Vect, pAbusive
执行代码:
myVocabList = createVocabList(listOPosts)
trainMat = []
for postinDoc in listOPosts: # for循环使用词向量来填充trainMat列表
    trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
print(trainMat)
print("----------")
print(listClasses)
p0V, p1V, pAb = trainNB0(trainMat, listClasses)
print('pAb 显示的概率是: %f ' % pAb)
print(p0V)
print("-----------------------")
print(p1V)
运行算法概率的截图:

在这里插入图片描述

4.5.3 根据显示状况修改分类器:

贝叶斯分类器对文档进行划分 需要计算多个概率的乘积以获得文档属于某个类别的改了,避免其中一个概率值出现0,最后的乘积为0

p0Num = ones(numWords)
p1Num = ones(numWords)
p0Denom = 2.0
p1Denom = 2.0

由于产生下溢出,可以对其使用对数乘积

def classifyNB(vec2classify, p0Vec, p1Vec, pClass1):
    """
    使用数组来计算两个向量相乘的结果,这里的相乘指的是对象元素相乘
    :param vec2classify: 需要分类的向量
    :param p0Vec: 三个概率
    :param p1Vec:
    :param pClass1:
    :return:
    """
    p1 = sum(vec2classify * p1Vec) + log(pClass1)
    p0 = sum(vec2classify * p0Vec) + log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0


def testingNB():
    """
    便利函数,封装所有操作
    :return:
    """
    listOPosts, listClasses = loadDataSet()
    myVocabList = createVocabList(listOPosts)
    trainMat = []
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
    p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
    testEntry = ['love', 'my', 'dalmation']
    thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
    print(testEntry, 'classified as :', classifyNB(thisDoc, p0V, p1V, pAb))
    testEntry = ['stupid', 'garbage']
    thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
    print(testEntry, 'classfied as:', classifyNB(thisDoc, p0V, p1V, pAb))
实现截图:

image-20221014182545177

4.5.4文档词袋模型

每个词是否出现作为一个特征,这个可以被描述为词集模型,如果一个词在文档中不止出现过一次,者可能意味着包含盖茨是否出现在文档中所表达的某种信息,词袋模型,每个单词可以出现多次,但是在词集中,每一个词只能出现一袭。需要setOfWord2Vec稍加修改,修改后的函数为bagOfWords2Vec

def bagOfWords2VecMN(vocabList, inputSet):
    """
    每遇到一个单词
    :param vocabList:
    :param inputSet:
    :return:
    """
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    return returnVec

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

使用朴素贝叶斯解决一些显示生活中的问题时,需要从文本内容获取字符串列表,然后生成词向量

收集数据;

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

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

训练算法 使用trainNB0函数

测试算法 classifyNB 构建一个新的测试函数来计算文档集的错误率

使用算法

4 .6.1切分文本
切分数据截图:

在这里插入图片描述

Demo
import re

if __name__ == '__main__':
    mySent = 'This book is the the best book on Python or M.L. I have ever laid eyes upon.'
    mySent.split()
    regEx = re.compile('\W+')  # 获取一长串的的字母 单词形式
    listOfTokens = regEx.split(mySent)
    print(listOfTokens)
    print([tok.lower() for tok in listOfTokens if len(tok) > 0])
    emailText = open(r'email/ham/6.txt', encoding='ISO-8859-1').read() # 显示编码方便MAC读入数据
    # print(emailText)
    listOfTokens = regEx.split(emailText)
    print(listOfTokens)



代码实现截图:

在这里插入图片描述

URL切分 需要实现过滤掉小于字符长度3的数据 实际的解析过程中,需要用更高级的过滤去来对诸如HTML和URI的对象的进行处理,目前一个URI最终会解析成词汇表中的单词,文本解析可能是一个相当复杂的过程

使用朴素贝叶斯进行交叉验证

def textParse(bigString):
    """
    URL切分 需要实现过滤掉小于字符长度3的数据 实际的解析过程中,
    需要用更高级的过滤去来对诸如HTML和URI的对象的进行处理,目前一个URI最终会解析成词汇表中的单词,文本解析可能是一个相当复杂的过程
    j接受一个大字符并将其解析为字符串列表,该函数去掉少于两个字符的字符串,并将所有的字符串转换为小写
    :param bigString:
    :return:
    """
    listOfToken = re.split(r'\W+', bigString)
    return [tok.lower() for tok in listOfToken if len(tok) > 2]


def spamTest():
    """
    实现对贝叶斯垃圾邮件分类器进行自动化处理,导入文件家spam  ham中的文本文件,并将他们解析为词列表
    构建一个测试集与训练集
    两个集合中的邮件都是随机选出的
    10测试 trainSet是一个整数列表0-49 随机选择其中10个文件 将文档添加到测试机,从训练集剔除
    随机选择数据的一部分作为训练
    需要多次迭代计算出求出平均错误率
    需要使用setOfWords2Vec函数来构建词向量 traindNB0()函数中用于计算分类所需的概率,然后遍历测试集
    :return:
    """
    docList = []
    classList = []
    fullText = []
    for i in range(1, 26):
        wordList = textParse(open(r'email/spam/%d.txt' % i, encoding='ISO-8859-1').read())
        # print('wordList:', wordList)
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList = textParse(open(r'email/ham/%d.txt' % i, encoding='ISO-8859-1').read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
        # print('classList:', classList)
    vocabList = createVocabList(docList)
    # print('vocabList',vocabList)
    trainingSet = list(range(50))
    # print('trainingSet', trainingSet)
    testSet = []
    for i in range(10):
        randIndex = int(random.uniform(0, len(trainingSet)))
        testSet.append(trainingSet[randIndex])
        del (trainingSet[randIndex])
    # print('trainingSet', trainingSet)
    # print('docList', docList)
    trainMat = []
    trainClasses = []
    for docIndex in trainingSet:
        trainMat.append(setOfWords2Vec(vocabList, docList[docIndex]))
        trainClasses.append(classList[docIndex])
    # print('trainClasses', trainClasses)
    p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))
    errrorCount = 0
    for docIndex in testSet:
        wordVector = setOfWords2Vec(vocabList, docList[docIndex])
        if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:
            errrorCount += 1
    print('the error rate is :', float(errrorCount) / len(testSet))
执行截图:

image-20221014204710066

4.7 使用朴素贝叶斯分类器从个人广告中获取区域倾向

朴素贝叶斯应用:1,过滤网站的恶意留言 2,过滤垃圾邮件

使用朴素贝叶斯来发现地域相关的用词

收集数据:从RSS源收集内容,这里需要对RSS源构建一个接口

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

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

训练算法:使用trainNB0

测试算法:观察错误率,确保分类器可用,可以修改切分程序,降低错误率,提高分类结果

使用算法:构建一个完整的程序,封装所有内容,给定两个RSS源,该程序会显示最常用的公共词

4.7.1 导入RSS源

Universal Feed Parser 是python常用的RSS程序库


def calcMostFreq(vocabList, fullText):
    """
    获取排序中最高的30个单词并随后将他们移除
    :param vocabList:
    :param fullText:
    :return: 需要返回之后会
    """
    freqDict = {}
    for token in vocabList:
        freqDict[token] = fullText.count(token)
    sortedFreq = sorted(freqDict.items(), key=operator.itemgetter(1), reverse=True)
    return sortedFreq[:30]


def localWords(feed1, feed0):
    docList = []
    classList = []
    fullText = []
    minLen = min(len(feed1['entries']), len(feed0['entries']))
    print(len(feed1['entries']))
    print(len(feed0['entries']))
    print(feed0['entries'])
    print(feed1['entries'])
    for i in range(minLen):
        wordList = textParse(feed1['entries'][i]['summary'])
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList = textParse(feed0['entries'][i]['summary'])
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
    vocabList = createVocabList(docList)
    print("^^^^^^^^^^^^^")
    print(len(vocabList))
    top30Words = calcMostFreq(vocabList, fullText)
    for pairW in top30Words:
        if pairW[0] in vocabList:
            vocabList.remove((pairW[0]))
    trainingSet = list(range(2 * minLen))
    print('trainingSet',trainingSet)
    print('trainingSetlen', size(trainingSet))
    testSet = []
    for i in range(minLen):
        print('----------------')
        print((trainingSet))
        randIndex = int(random.uniform(0, len(trainingSet)))
        print('randIndex', randIndex)
        print('i', i)
        print('testSet', testSet)
        # print('randIndex:%d : %s'%(randIndex, trainingSet[randIndex]))
        testSet.append(trainingSet[randIndex])
        del (trainingSet[randIndex])
    trainMat = []
    trainClasses = []
    for docIndex in trainingSet:
        trainMat.append(bagOfWords2VecMN(vocabList,docList[docIndex]))
        trainClasses.append(classList[docIndex])
    p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))
    errorCount = 0
    for docIndex in testSet:
        wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
        if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:
            errorCount += 1
    print('the error rate is :', float(errorCount) / len(testSet))
    return vocabList, p0V, p1V

4.7.2 显示地域相关的用词

可以用向量pSF与pNY进行排序,然后按照顺序将顺序将词打印出来。

def getTopWords(ny, sf):
    """
    使用两个RSS源做为输入,然后训练并测试朴素贝叶斯分类器,返回使用的概率值,然后创建两个列表用于元组的存储。与之前返回排名最高的X
    个单词不同,这里可以返回大于某个阈值的所有词。这些元组会按照他们的条件概率进行排序。
    :param ny:
    :param sf:
    :return:
    """
    vocabList, p0V, p1V = localWords(ny, sf)
    topNY = []
    topSF = []
    for i in range(len(p0V)):
        if(p0V[i]) > -6.0: topSF.append((vocabList[i],p0V[i]))
        if(p1V[i]) > -6.0: topNY.append((vocabList[i],p0V[i]))
    sortedSF = sorted(topSF, key=lambda pair : pair[1], reverse=True)
    print('SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**')
    for item in sortedSF:
        print(item[0])
    sortedNY = sorted(topNY, key=lambda  pair:pair[1], reverse=True)
    print("NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**")
    for item in sortedNY:
        print(item[0])

执行返回排名最该的X个单词

在这里插入图片描述

4.8本章小结

使用概率有时要比硬规则更为有效,贝叶斯概率以及贝叶斯准则提供了一个利用已知值来估计未知概率的有效方法

可以通过特征之间的条件独立性假设,降低对数据量的需求,独立性假设是指一个词的出现概率并不依赖文档中的其他词,条件独立性并不正确。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【机器实战学习】朴素贝叶斯 python代码实现 的相关文章

随机推荐

  • 上传论文到arxiv教程

    由于文章需要引用或者虽然已经被期刊或者会议录用 但还未发表 可能需要先占坑 具体步骤如图 1 arxiv 注册 最好用 edu 邮箱 就不需要资格审查了 官网是 http arxiv org 注册好后直接登录 2 开始一个新的提交 以前记录
  • ADC学习系列(一):ADC基础概念

    本章主要是进行ADC的基础概念学习 从模拟和数字信号进行入手 分析各自的优缺点和应用场合 从而引出数模转换的重要性 紧接着提到了ADC部分最重要的奈奎斯特采样定理 了解采样频率和被测信号频率之间的关系 最后介绍了ADC的采样保持放大电路 作
  • Python全栈开发工程师 第一模块作业

    1 编程题 100分 第一模块作业 1 学习计算机运行原理 绘制一张python代码从输入电脑 到处理 到输出结果的整个流程图 2 构建自己的python编程环境 整个过程做笔记 把截图放到word里提交 3 写下自己学习编程的目标 建议按
  • 【IntelliJ IDEA】升级之后又要激活的解决方法

    用了几个月的idea 在它升级之后 又不听话了 启动时候需要重新激活 解决方法 1 找到C Windows System32 drivers etc 下的hosts文件 在文件中添加如下 0 0 0 0 account jetbrains
  • VC++ CComboBox自绘

    头文件定义 CSWComboBox h pragma once class CSWComboBox public CComboBox DECLARE DYNAMIC CSWComboBox public CSWComboBox CSWCom
  • 传奇GOM引擎合区工具源码

    传奇GOM引擎合区工具源码 自己写的一点小项目 所以在此给大家分享 包含MFC框架 Windows消息机制原理 WIN32API调用 还有找了半天的后台组合按键消息 合区功能基本都有 是学习MFC的一个好的小项目 VS2013 unicod
  • python中dataframe将一列中的数值拆分成多个列

    起初的数据是这样的 想将page no这一列拆分成多个列 然后将其中的值都作为列名 想要做成的结果如下图 也就是统计每个id下各个page no出现的次数 实现的思路是先对page no这一列进行one hot编码 将一列变为多列 然后再用
  • mybatis-plus3.5.2分页插件无效解决方案

    解决问题思路 测试分页插件的时候发现sql语句没有添加limit并返回的是所有数据 排查得知mybatis plus版本为3 5 2 搜索资料得知旧版本的PaginationInterceptor已经过时 官方推荐使用PaginationI
  • Python基本语法,python入门到精通

    python你不去认识它 可能没什么 一旦你认识了它 你就会爱上它 Python基本语法 1 定义变量 代码正文 x 1 y 2 z x y Python定义变量的方式呢很简单 就是上面这段代码 相信只要稍微懂点数学的人都能看懂这段代码的含
  • 微信终于支持 H5 跳转 App &小程序

    继小程序灰度测试分享朋友圈刷屏后 滴滴滴 这 闲着也闲着 顺藤摸瓜点了进去 好家伙 产品小姐姐写这个文案还是太含蓄了 我猜有可能是老干妈还没吃够 根据刀哥多年写代码要看文档的经验来看 证实了这次更新不仅支持了打开小程序 连app也顺带支持了
  • 第17节-PhotoShop基础课程-画笔修复工具

    文章目录 前言 1 画笔工具 1 基本操作 2 工具选项 1 不透明度 2 流量 3 平滑 2 画笔大小工具栏大小设置 4 笔刷 2 铅笔工具 3 颜色替换工具 批量替换颜色 4 混合器画笔工具 人像精修 前言 画笔工具的使用 1 画笔工具
  • BottomSheetDialogFragment圆角

    自己使用BottomSheetDialogFragment时 想实现上方圆角 布局设置了圆角的背景后 需要给dialog的北京设置为透明 才能有圆角的效果 网上其他的文章都是这么实现的 dialog getWindow findViewBy
  • 小程序发布上线全流程(包含小程序怎么通过审核)

    小程序在开发完成后 需要上传代码 设为体验版本 功能测试 提交审核 发布上线这几个基本步骤 接下来用自己的亲身经历一一详细介绍 小程序发布上线全流程 1 上传代码 在微信开发者工具的右上角上传处上传全部代码 如下图 如果小程序中涉及到一些r
  • 程序kill后仍占用GPU

    sc yolov5 zqchen gpurtx02 ultralytics gpustat gpurtx02 Thu Aug 24 09 18 31 2023 470 74 0 Quadro RTX 6000 41 C 0 0 24220
  • 2-需求分析

    一 需求收集 1 需求概念 以下常见三种情形 提问题 目的不明确 明确困境 提目的 目的明确 解决方案不明确 提方案 目的明确 方案明确 概念 本质是用户的预期和现状之间的差异产生的需求 在提出需求时 往往会基于目的描述问题 想法或建议 往
  • python代码~考研祝福

    完整代码如下所示 from turtle import speed 2 Turtle screen delay 0 def go to x y up goto x y down def ring a b c d for i in range
  • STM32F103小容量、中容量和大容量单片机介绍

    一 小容量 中容量和大容量表示的型号 STM32F103x4和STM32F103x6被归为小容量产品 闪存小于等于32K STM32F103x8和STM32F103xB被归为中等容量产品 闪存小于等于128K STM32F103xC STM
  • diskgenius创建efi分区_怎么创建efi系统分区?efi系统分区创建教程

    文章导读 近两年出来的的电脑不管是新台式机还是笔记本电脑 绝大多数是uefi主板 要采用对应的硬盘分区是gpt格式的 所以我们一定要记得采用efi引导对应的分区类型一定是gpt分区 EFI分区是GPT磁盘分区表里面的一个必要分区 是独立于系
  • win10上安装python3.9.0+robotframework

    win10上安装python3 9 robotframework python3 9 0下载安装 robotframework安装 wxpython安装 ride安装 python3 9 0下载安装 下载地址 python3 9 0下载地址
  • 【机器实战学习】朴素贝叶斯 python代码实现

    朴素贝叶斯 输入数据创造词汇表 代码实现 coding UTF 8 def loadDataSet 创建了一下实验样本 return 词条且分的文档集合 类别标签的集合 自动检测侮辱性的语言 postingList my dog has f