精华内容
下载资源
问答
  • python实现贝叶斯算法
    千次阅读
    2017-11-27 16:37:19
    http://python.jobbole.com/85987/
    更多相关内容
  • 【项目实战】Python实现贝叶斯算法疫情微博评论情感分析 资料说明:包括数据集+源代码+Word文档说明。 资料内容包括: 1)需求分析; 2)数据采集; 3)数预处理; 4)数据分析过程; 5)利用贝叶斯定理进行情感分析...
  • 贝叶斯分类算法是统计学的一种分类算法,利用概率统计对数据进行分类,含数据集,Python实现贝叶斯分类算法
  • 这是分类算法贝叶斯算法的较为简单的一种,整个贝叶斯分类算法的核心就是在求解贝叶斯方程P(y|x)=[P(x|y)P(y)]/P(x) 而朴素贝叶斯算法就是在牺牲一定准确率的情况下强制特征x满足独立...
  • 本文实例讲述了朴素贝叶斯算法python实现方法。分享给大家供大家参考。具体实现方法如下: 朴素贝叶斯算法优缺点 优点:在数据较少的情况下依然有效,可以处理多类别问题 缺点:对输入数据的准备方式敏感 适用数据...
  • 接下来通过建立贝叶斯分类模型来进行微博评论数据的情感分析。 2.数据采集 本数据是从微博上抓取的数据: 数据集:data.xlsx 在实际应用中,根据自己的数据进行替换即可。 特征数据:微博正文 标签数据:分类...

    说明:这是一个机器学习实战项目(附带数据+代码),如需数据+完整代码可以直接到文章最后获取。

    1.需求分析

           在新浪微博上有很多关于新冠疫情的微博消息以及评论信息,那么这些文本数据究竟是一个怎样的观点,人们对这次疫情持什么样的态度:积极、消极还是中性。接下来通过建立贝叶斯分类模型来进行微博评论数据的情感分析。

    2.数据采集

    本数据是从微博上抓取的数据:

    数据集:data.xlsx

    在实际应用中,根据自己的数据进行替换即可。

    特征数据:微博正文

    标签数据:分类(积极 消极 客观)

    3.数据预处理

    1)原始数据描述

     

    2)数据去重与空值处理:

     

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    readPath='source.txt'
    writePath='source01.txt'
    lines_seen=set()
    outfiile=open(writePath,'a+',encoding='utf-8')
    f=open(readPath,'r',encoding='utf-8')
    for line in f:
        if line not in lines_seen:
            outfiile.write(line)
            lines_seen.add(line)

    去重前:

     

    去重后:

    4.数据分析过程

    4.1 分词处理

            微博作为一个社交平台,不仅拥有能够迅速的传播特点,并且成为了商家用来推广产品的重点发布平台。在微博中,大量广告、营销类账号的出现,给微博的情感分析造成很大的困难。所以,针对微博的文本预处理变得极其重要。

    4.1.1 分词

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    import jieba
    
    
    # 待分词的文本路径
    sourceTxt = 'source.txt'
    # 分好词后的文本路径
    targetTxt = 'target.txt'
    
    # 对文本进行操作
    with open(sourceTxt, 'r', encoding='utf-8') as sourceFile, open(targetTxt, 'a+', encoding='utf-8') as targetFile:
            for line in sourceFile:
                seg = jieba.cut(line.strip(), cut_all=False)
                # 分好词之后之间用/隔断
                output = '/'.join(seg)
                targetFile.write(output)
                targetFile.write('\n')
            print('写入成功!')
            sourceFile.close()
            targetFile.close()

    中文的分词是将一个汉字序列变成一个个单独的有意义的词汇。文本挖掘首先要以中文分词为前提。目前常用的中文分词软件主要有以下几种:

    (1)BosonNLP:玻森的中文语义开放平台,主要提供了一个方便、性能强大的中文自然语言分析的平台。

    (2)NLPIR:是中国科学院计算机研究所的一个产品,积累了多年研究工作,暂时是目前世界上最好的中文分词工具。

    (3)结巴分词:一款开源在GitHub上面的中文分词工具,提供了python、java等多语言的接口,而且能够识别繁体字,立志成为最好的中文分词工具。

    (4)IKAnalyzer:一款开源的java分词工具,最初是以lucene为应用主体的,之后结合了词典分词和语法分析算法的分词组件。

    本文中将采用中科院的NLPIR和开源的JIEBA进行分词,其中NLPIR的分类例子如下:

    不让我上去疫情高风险地区我还不会自己吗![doge][doge][doge](投稿:@还没怀上的葛一他麻麻)http://t.cn/RqKTebK

    如果不降噪进行分词:

    ['(', '不', '@还没怀上的葛一他麻麻', '投稿', '抢', '!', '会', '自己', '还', 'RqKTebK', '疫情', '上', '高风险',’高风险’,’地区’, '[doge]', '让', ':', 'http://t.cn/', ')', '吗', '我']

    4.1.2 删除URL

    垃圾微博中的内容一般较短,而且一般文字后面都带有链接,由此才能将用户导向网页的入口,如下面几条:

    【领 10 元 优惠 券】【券 后价 19.9元】【包邮】 粉丝福利购:http://t.cn/R6j6YyX ​"

    "神奇 口罩  =26.8 领券拍:http://t.cn/R6lLnsV http://t.cn/R6n9kRO ​"

    "买口罩?找优惠?上莫莉口罩!http://t.cn/RxmHa1i ​"

    "医用口罩  =49 领券拍:http://t.cn/R6nIheq http://t.cn/R6nI2Fp ​"

    "防病毒   口罩     =58 领券拍:http://t.cn/R6CjMuM http://t.cn/R6QsX8f ​"

    由上述内容可以知道,一般情况下的普通URL链接都是较长的字符串,如果保持原链接会占用微博的资源。因此,微博希望能够将原本的“长链接”变成缩短的短链接。微博中使用散列(hash)索引,将原始链接对应成一个较短的、一一对应的字幕、数字串组合。

    URL中带有有用的信息很少,一般都是广告的导向和用户的定位。我们使用SQL从数据库中查找含有URL的微博数量统计。

     统计结果

    统计项

    结果

    含有URL的微博数量

    16(总量:5781)

    由此可见,URL在微博中的引用量是0.2%,量不是很大,在情感分析前,要对微博文本进行适当的清理,从而去除这些无用的URL,降低这些URL对情感分析的影响。

    4.1.3 删除用户名

            微博文本中的用户名一般用来提醒该用户,但是,大部分微博用户的用户名毫无规律性,如:@real__pcyyyyy、@CloverH静、@baekhyunee7永远像25岁一样年轻等,对分词器来说有较大的影响,比如JIEBA分词会把“@baekhyunee7永远像25岁一样年轻”拆分成['@', 'baekhyunee7', '永远', '像', '25', '岁', '一样', '年轻'],其中“年轻”会对用来构建的词性特征造成影响,所以,对于用户名的出去也是极其重要的。

    4.1.4 去除停用词

    停用词(STOP WORDS),在词典中的意思为:对文本中表达的意义并不起什么作用的词语。在SEO中,为了节省存储空间和提高检索速度,搜索引擎会在搜索时自动忽略某些字或词,这些字或词便是停用词。

    停用词在一定程度上相当于过滤词,但是过滤词的范围比较大,通常包含色情、政治、暴力等敏感信息,停用词则没有这个限制。通常情况下,停用词可分为两类:

    (1)使用广泛,过于频繁的一些单词。比如“我”、“你”之类的词几乎在很多文档中都会出现,对于搜索引擎来说,这类词无法保证准确的搜索结果,还会降低效率。

    (2)文档中使用频率很高,但是实际意义不大的词。主要包括语气助词、副词、介词、连词等,在文本表达中没有变现出任何意义。为了增加情感分析的准确性,我们需要对微博文本中去除停用词。

    分词结果展示(部分):

     

    4.2 词频统计与词云图

    主要是通过JIEBA工具分词后,通过循环进行词频统计,为了更方便的展示词频的效果,方便进行查看,制作成词云图。

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    import jieba
    import re
    
    
    def txt():  # 输出词频前N的词语
        txt = open("target.txt", "r", encoding='utf-8').read()  # 打开txt文件,要和python在同一文件夹
        # print(txt)
        txt00 = open("shuchu.txt", "a+", encoding='utf-8')
        words = jieba.lcut(txt)  # 精确模式,返回一个列表
        # print(words)
        counts = {}  # 创建字典
        lt=['三炮','##','......','24','10','30','2020','14','31','11','13','20','15','28','17','16','29','微博']
        stopkeyword = [line.strip() for line in open('stopwords.txt', encoding='utf-8').readlines()]  # 加载停用词
        for word in words:
            if len(word) == 1:
                continue
            elif word  in stopkeyword :
                rword = " "
            else:
                rword = word
            counts[rword] = counts.get(rword, 0) + 1  # 字典的运用,统计词频
        items = list(counts.items())  # 返回所有键值对
        print(items)
        items.sort(key=lambda x: x[1], reverse=True)  # 降序排序
        N = eval(input("请输入N:代表输出的数字个数:"))
        wordlist = list()
        r1 = re.compile(r'\w')  # 字母,数字,下划线,汉字
        r2 = re.compile(r'[^\d]')  # 排除数字
        r3 = re.compile(r'[\u4e00-\u9fa5]')  # 中文
        r4 = re.compile(r'[^_]')  # 排除_
        # stopkeyword = [line.strip() for line in open('stopwords.txt', encoding='utf-8').readlines()]  # 加载停用词
        for i in range(N):
            word, count = items[i]
            txt00.write("{0:<10}{1:<5}".format(word, count))  # 输出前N个词频的词语
            txt00.write('\n')
            if  r1.match(word) and r2.match(word) and r3.match(word) and r4.match(word) :
                continue
    
        txt00.close()
    
    
    # 调用词频统计函数
    txt()
    

    词频统计结果展示(部分):

     

    词云图:

     

    5 利用贝叶斯定理情感分析

    贝叶斯方法作为一个历史悠久,有着坚实的理论基础的机器学习方法,不仅能够在同时处理很多问题时直接而又高效,而且很多高级自然语言处理模型也能够从它演化而来。贝叶斯方法,是研究自然语言处理问题的一个极其优秀的切入口。其流程主要如下图4.1。

                                   朴素贝叶斯情感分析基本流程

    准备工作阶段:此阶段主要是对文本进行预处理,先对样本进行标注,之后根据词频筛选部分的特征词。该阶段输入的事所有待分类的样本,然后得出特征属性和训练样本。朴素贝叶斯的分类器的准确性主要由筛选出来的特征属性来决定。

    分类器训练阶段:根据样本中的频率,然后由每个特征计算出每个类别的先验概率。此阶段主要是根据公式的机械计算。此阶段是朴素贝叶斯分类最重要的一个环节。

    应用阶段:该阶段主要将测试样本进行输入,然后由分类器来计算出分类的记过。

    5.1 贝叶斯定理

    贝叶斯公式就一行:

     

    而它其实是由以下的联合概率公式推导出来:

    P(Y,X)=P(Y|X)P(X)=P(X|Y)P(Y)          

    算法描述:

    标准的朴素贝叶斯分类算法的执行过程。

    (1)对样本进行人工标记

    (2)对不同类别的样本进行中文分词

    (3)去除样本中的垃圾词条

    (4)将整理后的词条做成特征组,分析并计算词条频率信息

    (5)根据词条的信息,计算其先验概率。

    (6)读取训练的样本,进行分词,降噪,然后形成样本特征组

    (7)将测试样本的先验概率代入朴素贝叶斯公式并计算后验概率,得到最大概率的所属类别就是文本的类别

    朴素贝叶斯文本分类流程

    本文中:将不同的经过数据预处理(去掉无关类的微博)后,将剩下的微博分为三类:POS(积极)、NEG(消极)、Neural(客观)。

    (1)一般情况下,积极即带有取向上、努力等思想和表现,如:全民防控 众志成城tyy生日快乐[噢耶][噢耶][噢耶]

    (2)而消极则代表了负面的,不思进取的,失落等情感,如:对面疫情,有时候觉得人活着挺难的,不想说话[闭嘴]

    (3)而客观的就表示仅仅陈述,不含有情感色彩的,如:疫情期间,一百本可以充实自己的外国图书,书荒的Mark

    对于文本分类,常用的朴素贝叶斯主要存在三种不同的贝叶斯模型:高斯模型、多变量的伯努利模型和多项式模型

    (1)高斯模型——它假设特征是正态分布的。它的一般使用场景是,给出人物的宽度和高度,判断这个人的性别。而情感分析,从给定推文文本中提取出词语的个数,不适合正态分布。

    (2)伯努利模型——和高斯模型相似,更适于判断词语是否出现二值特征,而不是词频统计。

    (3)多项式模型——它假设特征就是出现次数。这和我们是相关的,因为我们会把推文中的词频当做特征。

    5.1.1 高斯朴素贝叶斯

    某些特征很可能是连续型变量,比如说物体的长度和人的身高,这些特征可以转换成离散型的值。比如我们将人的身高进行划分,如表1。同时,我们也可以将身高用三个特征表示f1,f2,f3,结果如表2所示。

    表1身高特征划分方法一    

    0~160cm

    1

    160~170cm

    2

    170+cm

    3

    表2身高特征划分方法二

    身高

    f1 f2 f3

    0~160cm

    1  0  0

    160~170cm

    0  1  0

    170+cm

    0  0  1

    不过这些方式都不够细腻,高斯模型可以解决此类问题。高斯模型假设这些一个特征的所有属于某个类别的观测值符合高斯分布。

    5.1.2 伯努利贝叶斯

    伯努利贝叶斯(Bernoulli Naïve Bayes,BNB)是最早基于朴素贝叶斯模型对文本进行分类的算法。模型中,一篇文本会被表示成欧式空间中的一个二进制变量,即,如果文本中在指示变量中出现的话,则将改值标为1,否则为0.给定测试文本d=<w1,w2···wm>,如果属性条件独立,则BNB根据下面的公式选出最大的后验概率来对文本进行分类:

    c(d)=argmaxccP(c|c)                       

    从之前别人的研究可以表明伯努利贝叶斯在数据量比较少的时候性能较好,但是,当数据量大的时候,性能远远比不上多项式模型。

    5.1.3 多项式朴素贝叶斯定理

    多项式朴素贝叶斯(Multinomial Naïve Bayes,MNB)是为了改进多变量伯努利朴素贝叶斯而提出的。该模型中,文本的表示是欧式空间中的一个带有单词频率信息的向量,当一个词语在一篇文章中出现时,该文本的对应的词语频率为1,否则为0。

    在条件独立的情况下,给定测试文档,多项式朴素贝叶斯根据下面的极大后验概率来对文本进行分类:

                      

    5.2 本项目中的多项式朴素贝叶斯

    5.2.1 算法过程

    5.2.2 拉普拉斯平滑

    在计算先验概率和后验概率的时候,从样本中算出的概率值很有为0,会导致相乘的结果为0,这显然是不合理的,因为不能因为一个事件没有检测到就判断改事件的概率为0。我们可以通过分子和分母都分别加入一个平滑因子aa,就可以避免这个问题。更新过后的先验概率公式变为:

                   

    Lj是第j维特征的最大取值

    可以证明,改进以后的仍然是概率。平滑因子kk=0即为实现的最大似然估计,这时会出现在本节开始时提到的0概率问题;而kk=1则避免了0概率问题,这种方法被称为拉普拉斯平滑。

                                              拉普拉斯平滑曲线

    5.3 实现过程

    5.3.1 分词

    结巴分词,是Github中开源的中文分词组件,该分词器能够支持三种分词模式:

    1. 精确模式:能够将句子用最精确的方法切开,普遍适用于文本分析;
    2. 全模式:能够把文本中所有成词的词语都扫描出来,虽然速度非常快,但是不能解决歧义。
    3. 搜索引擎模式:在精确模式的基础上,会对长词再次切分,提高召回率,一般适用于搜索引擎分词。

    本实验是基于标注的情感分析,故使用结巴分词的精确模式来进行分词。

    分词的结果:

    5.3.2 特征提取

    跟第所述的一样,使用Python统计筛选出频率最高的词。得出的结果使用词云如图所示:

                                                            词云

    5.3.3 向量化

    假如上述中的特征提取中构建出来的单词特征为[‘喜欢’,’失望’,’快乐’,’越来越好’,’晚安’],长度为m,矢量化的时候如果一条微博为:生日快乐,晚安。那么,构建出来的矩阵为:[0,0,1,0,1]。

    说明:

    1.如果为n条微博,则构建出来则是n*m的矩阵。

    2.如果一条微博的某个特征出现次数多于一次,则进行累加,如,快乐快乐,矢量化之后变成:[0,0,2,0,0,0]。

    5.3.4 朴素贝叶斯分类

    本文中将微博的情感分为三类,分别用数字代表某一类结果,其中1表示积极,2表示消极,3表示客观。经过之前的去标签、分词和向量化之后,样本均变成了numpy中的数组,下面将使用多项式朴素贝叶斯进行训练。其伪代码如下图所示。

    对人工标注中的类别进行计算

    对于每篇训练的文本:

        对于每个类别:

            如果某个词语出现在文档中,增加其数值

            然后再增加所有词语的计数值

    对于每个类别:

        除于总数目,得出条件概率

    使用测试文档与词向量相乘,得出最大类别就是该文本的所属类别

    朴素贝叶斯

    5.3.5 测试及计算

    之后使用从数据源中选取几个句子用来测试,结果如下(后面的标号表示分类结果,其中1表示积极,2表示消极,3表示客观):
    
    疫情当前,不惊扰别人的宁静,就是慈悲; 不伤害别人的自尊,就是善良。 ---- 3
    
    疫情在家里面,与大哥太有缘分!竟是同天生日!!希望大哥的模特演绎之路能够越走越远越走越顺越走越好!!! ---- 1
    
    全民抗疫,萌萌哒 ---- 1
    
    在疫情中,现在的年轻人,连点小事都做不好 ---- 2
    
    新冠病毒来袭,丁丁美人飞机临时取消,只能明天再见了[失望] ---- 2
    
    疫情中,默默看书 ---- 3
    
    今年又遇到了疫情,一天又一天,今夕是何年[失望]    ----2
    
    疫情来了,还好这只傻狗没有被学校的捕狗大队抓走[悲伤]    ----2
    
    全民抗击病毒,相比游戏可以凭运气  ---- 3
    
    面对疫情病毒,生活中却全是坑,绕不开[哈哈]   ---- 1
    
    哎,疫情又要在家,现实比不过一个网?[拜拜]    ----2
    
    众志成城,抗击疫情,最最亲爱的自己,最最亲爱的世界,晚安[兔子][月亮]   ---- 3
    
    面对病毒,有点想哭   ----2
    
    疫情在家,发现只要过了星期三就变得好快[晕][晕]     ----2
    
    疫情在家,虽然下雨,健身不能停,瑜伽课加游泳八百米,代餐奶昔不裹腹啊,快睡吧,睡着了就不饿了! http://t.cn/R2Wx9Wb  ---- 3

    建模代码实现:

    6 情感倾向饼状图

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    import matplotlib.pyplot as plt
    
    plt.rcParams['font.sans-serif'] = 'SimHei'
    plt.figure(figsize=(6, 6))
    label = ['积极', '消极', '客观']
    explode = [0.01, 0.01, 0.01]
    values = [2250, 274, 3257]
    plt.pie(values, explode=explode, labels=label, autopct='%1.1f%%')
    plt.title('情感倾向饼状图')
    plt.savefig('./情感倾向饼状图')
    plt.show()
    

    针对,贝叶斯分析的结果,制作饼状图,如下图所示:

    通过饼状图分析,情感倾向大部分人是客观状态的,表名人们看到这次全民抗疫还是比较客观的;再者就是积极状态的人,说明在这次抗击疫情时,人民还是比较积极的;消极的人很少。

     本次机器学习项目实战所需的资料,项目资源如下:https://download.csdn.net/download/weixin_42163563/21350026

    展开全文
  • 简单的朴素贝叶斯垃圾邮件分类算法python实现),另外上传的有垃圾邮件训练数据集,供大家下载。
  • python实现朴素贝叶斯算法

    千次阅读 2021-12-08 16:53:26
    · 朴素贝叶斯算法是应用最为广泛的分类算法之一。 · 给定训练数据集X,其类别为Y,则有: 其中,P(Y|X)为后验概率,即测试集文本X取类别Y的概率。对于文本Xi,对每个类别Yi计算概率,得到P(Y1|Xi)、P(Y2|Xi...

    本次实验的任务是文本分类,所用数据集为20news_bydate
    实验流程主要如下:
    一、算法介绍
    · 朴素贝叶斯算法是应用最为广泛的分类算法之一。
    · 给定训练数据集X,其类别为Y,则有:
    在这里插入图片描述
    其中,P(Y|X)为后验概率,即测试集文本X取类别Y的概率。对于文本Xi,对每个类别Yi计算概率,得到P(Y1|Xi)、P(Y2|Xi)、……、P(Yn|Xi),概率最大的类别则为预测类别。

    上式中:
    · P(Y)为每个类别的先验概率,计算方式为:
    每个类别单词总数 / 训练集所有单词总数。

    · P(X | Y)= P(x1,x2,……,xn | Y),xi为文本的特征。
    朴素贝叶斯“朴素”地将各个特征视作相互独立,因此:
    P(X | Y) = P(x1 | Y)× P(x2 | Y)× P(x3 | Y)…… × P(xn | Y)。
    这里,文本的特征xi即为文本预处理、分词后得到的全部词汇。
    计算方式(以 P(xi | Yj)为例):
    单词xi在训练集Yj类别下所有文档中出现的总次数 / 训练集Yj类别下所有文档包含的单词总数

    · P(X)始终不变,可以忽略不计。

    综上,实验主要步骤为:
    数据集获取 -》 数据预处理,得到分词后的语料和词袋 -》 遍历计算P(X)、P(X|Y) -》
    max( P(X) × P(X|Y) )对应的类别即为预测类别

    二、数据集获取
    20newsgroups数据集可以直接从sklearn模块导入:

    from sklearn.datasets import fetch_20newsgroups #导入模块
    news_data = fetch_20newsgroups(subset="all") #读取数据
    

    也可以手动下载:
    链接:https://pan.baidu.com/s/1YO-Je1lT_y-MbGRpSwHQSA
    提取码:qwer

    三、数据预处理

    import os
    # string nltk 用于文本预处理
    import string
    import nltk
    from nltk.corpus import stopwords
    import pickle
    
    class Textprocess():
        def __init__(self):
        	# 存放原始语料库路径
            self.corpus = ''
            # 分词后的路径
            self.segment = ''
            # 存储分词、去重后的结果
            self.word_list = ''
            self.label_list = ''
            # 存储训练集分词结果,处理测试集时相关代码注释
            self.ori_words_list = ''
    	
    	# 在原始路径下创建train_segment,test_segment两个文件夹
    	# 存储预处理、分词后的结果
        def preprocess(self):
            mydir = os.listdir(self.corpus)
            for dir in mydir:
                create_dir = self.corpus + '/' + dir + '_segment'
                os.makedirs(create_dir)
                dir_path = self.corpus + '/' + dir
                news_list = os.listdir(dir_path)
                # 每个类别的文档集
                for news in news_list:
                    path = create_dir + '/' + news
                    os.makedirs(path)
                    news_path = dir_path + '/' + news
                    files = os.listdir(news_path)
                    # 每个文本文件
                    for file in files:
                        file_path = news_path + '/' + file
                        with open(file_path,'r',encoding='utf-8', errors='ignore') as f1:
                            content = f1.read()
                            clean_content = self.data_clean(content)
                            new_file_path = path + '/' + file
                            with open(new_file_path, 'w', encoding = 'utf-8', errors='ignore') as f2:
                                f2.write(clean_content)
    
        def data_clean(self, data):
            # 大写转换为小写
            data1 = data.lower()
            # 去除标点符号
            remove = str.maketrans('','',string.punctuation)
            data2 = data1.translate(remove)
            # 分词
            data3 = nltk.word_tokenize(data2)
            # 去除停用词和非英文词汇
            data4 = [w for w in data3 if (w not in stopwords.words('english')) and (w.isalpha()) and (len(w) < 15)]
            data_str = ' '.join(data4)
            return data_str
    
        def create_non_repeated_words:(self):
            self.content_list = []
            self.labels_list = []
            # self.ori_list = []
            mydir = sorted(os.listdir(self.segment))
            label = 0
            for dir in mydir:
                dir_path = self.segment + '/' + dir
                files = sorted(os.listdir(dir_path))
                for file in files:
                    file_path = dir_path + '/' + file
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                        line = f.read()
                        line1 = line.strip('\n')
                        line2 = line1.split()
                        # 将分词后的结果存入列表,处理测试集时注释
                        # self.ori_list.append(line2)
                        # 列表去重,并去掉仅出现一次的单词
                        line3 = []
                        once_word = []
                        for i in line2:
                            if i not in once_word:
                                once_word.append(i)
                            else:
                                if i not in line3:
                                    line3.append(i)
                        self.content_list.append(line3)
                        self.labels_list.append(label)
                label += 1
    
            self.data_dump(self.word_list, self.content_list)
            self.data_dump(self.label_list, self.labels_list)
            # self.data_dump(self.ori_words_list, self.ori_list)
    
        def data_dump(self, path, data):
            f = open(path, 'wb')
            pickle.dump(data, f)
            f.close()
    
        def data_load(self, path):
            f = open(path, 'rb')
            data = pickle.load(f)
            return data
        
    text = Textprocess()
    text.corpus = r'.\20news-bydate'
    text.segment = r'.\20news-bydate\20news-bydate-train_segment'
    text.word_list = 'train_words'
    text.label_list = 'train_labels'
    text.ori_words_list = 'original_bag'
    text.preprocess()
    text.create_non_repeated_words()
    
    
    test = Textprocess()
    test.corpus = r'.\20news-bydate'
    test.segment = r'.\20news-bydate\20news-bydate-test_segment'
    test.word_list = 'test_words'
    test.label_list = 'test_labels'
    test.create_non_repeated_words()
    

    四、朴素贝叶斯算法的实现

    #encoding=utf-8
    import textprocess_detail as tp
    import numpy as np
    from sklearn import metrics
    ori_words = tp.Textprocess().data_load('original_bag')
    train_labels = tp.Textprocess().data_load('train_labels')
    test_words = tp.Textprocess().data_load('test_words')
    test_labels = tp.Textprocess().data_load('test_labels')
    
    # 计算每个类别包含的单词总数
    def words_sum():
        sum = [0 for i in range(20)]
        for i in range(len(ori_words)):
            count = len(ori_words[i])
            sum[train_labels[i]] += count
        return sum
    
    # 计算每个类别的先验概率
    def category_probability(list):
        sum = 0
        cp = []
        for i in list:
            sum += i
        for j in list:
            cp.append(j / sum)
        return cp
    
    # p(x1|y) * p(x2|y) * …… * p(y)
    def predict(sum, cp):
        precision = []
        for doc in range(len(test_words)):
            p_list = []
            for predict_label in range(20):
                p = 1
                word_sum = sum[predict_label]
                for word in test_words[doc]:
                    count = 0
                    # 遍历训练集文档
                    for i in range(len(ori_words)):
                        if train_labels[i] == predict_label:
                            count += ori_words[i].count(word)
                    p *= (count + 1) / (word_sum + 20)
                p *= cp[predict_label]
                p_list.append(p)
            precision.append(p_list)
        tp.Textprocess().data_dump('precision', precision)
        print(precision)
        return precision
    
    count_list = words_sum()
    cp = category_probability(count_list)
    precision = predict(count_list, cp)
    probability = tp.Textprocess().data_load('precision')
    a = np.array(probability)
    precision = np.argmax(a, axis = 1)
    
    true_label = tp.Textprocess().data_load('test_labels')
    m_precision = metrics.accuracy_score(true_label,precision)
    print("%.2f"%m_precision)
    

    最终正确率在0.7左右

    展开全文
  • 压缩包中包括python脚本和一个PPT。 在UtralEdit中打开这两个脚本NBayes_lib.py和NBayes_...PPT详解了朴素贝叶斯算法的原理以及这个文本分类器的程序思想和运行结果详解,希望对你能够有帮助,如果有任何问题,请留言!
  • 机器学习 Python实现 贝叶斯算法

    千次阅读 2015-03-06 11:34:01
    贝叶斯概率需要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(w0|1)p(w1|1)p(w2|1)。如果其中一个概率值为0,那么最后的乘积也为0 第二个问题就是下溢出,这是由于太多过小的数相乘造成的。由于大...

    [['my','dog','has','flea','problems','help','please'],    0

     ['maybe','not','take','him','to','dog','park','stupid'],  1

     ['my','dalmation','is','so','cute','I','love','him'],          0

     ['stop','posting','stupid','worthless','garbage'],          1

     ['mr','licks','ate','my','steak','how','to','stop','him'],  0

    ['quit','buying','worthless','dog','food','stupid']]           1


    以上是六句话,标记是0句子的表示正常句,标记是1句子的表示为粗口。我们通过分析每个句子中的每个词,在粗口句或是正常句出现的概率,可以找出那些词是粗口。

    注意:主要从以下两点对分类器进行修改

    <1>贝叶斯概率需要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(w0|1)p(w1|1)p(w2|1)。如果其中一个概率值为0,那么最后的乘积也为0

    <2>第二个问题就是下溢出,这是由于太多过小的数相乘造成的。由于大部分因子都非常小,所以程序会下溢出或者得不到正确的答案。解决办法是对乘积取自然对数这样可以避免下溢出或者浮点数舍入导致的错误。

    <3>每个单词的出现与否作为一个特征,被称为词集模型;在词袋模型中,每个单词可以出现多次。

    贝叶斯理论就是通过可以求得的后验概率计算前验概率
    这里用到的朴素贝叶斯理论有两个前提
    特征之间相互独立
    特征之间同等重要
    # -*- coding: cp936 -*-
    from numpy import *  
    #过滤网站的恶意留言  
    # 创建一个实验样本  
    def loadDataSet():  
        postingList = [['my','dog','has','flea','problems','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):  
        vocabSet = set([])      #创建一个空集  
        for document in dataSet:  
            vocabSet = vocabSet | set(document)   #创建两个集合的并集  
        return list(vocabSet)  
      
    #将文档词条转换成词向量  
    def setOfWords2Vec(vocabList, inputSet):  
        returnVec = [0]*len(vocabList)        #创建一个其中所含元素都为0的向量  
        for word in inputSet:  
            if word in vocabList:  
                #returnVec[vocabList.index(word)] = 1     #index函数在字符串里找到字符第一次出现的位置  词集模型  
                returnVec[vocabList.index(word)] += 1      #文档的词袋模型    每个单词可以出现多次  
            else: print "the word: %s is not in my Vocabulary!" % word  
        return returnVec
    
    #朴素贝叶斯分类器训练函数   从词向量计算概率  
    def trainNB0(trainMatrix, trainCategory):  
        numTrainDocs = len(trainMatrix)  #文本数量
        numWords = len(trainMatrix[0])   #文本中词汇数量也是词库的大小
        pAbusive = sum(trainCategory)/float(numTrainDocs)  #P(wi)
       # p0Num = zeros(numWords); p1Num = zeros(numWords)  
        #p0Denom = 0.0; p1Denom = 0.0  
        p0Num = ones(numWords); p1Num = ones(numWords)#避免一个概率值为0,最后的乘积也为0  
        p0Denom = 2.0; p1Denom = 2.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   #计算获得p(wi|c1),p(wi|c0)
        #print (p1Num)
        #print (p1Denom)
        p1Vect = log(p1Num / p1Denom)  
        p0Vect = log(p0Num / p0Denom)      #避免下溢出或者浮点数舍入导致的错误   下溢出是由太多很小的数相乘得到的  
        return p0Vect, p1Vect, pAbusive
    
    #朴素贝叶斯分类器  
    def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):  #vec2Classify表示需要分类的向量
        p1 = sum(vec2Classify*p1Vec) + log(pClass1)  
        p0 = sum(vec2Classify*p0Vec) + log(1.0-pClass1)  
        if p1 > p0:  
            return 1  
        else: return 0  
      
    def test():
        listPosts,listClasses = loadDataSet()
        myVocablist = createVocabList(listPosts)
        set1 = setOfWords2Vec(myVocablist,listPosts[0])
        #print(set1)
        set2 = setOfWords2Vec(myVocablist,listPosts[1])
        #print(set2)
        trainMat = []
        for postinDoc in listPosts:
            trainMat.append(setOfWords2Vec(myVocablist,postinDoc))
        #print(trainMat)
        #print(listClasses)
        p0V,p1V,pAb = trainNB0(trainMat,listClasses)
        print(pAb)
        print(p1V)
        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, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb)
    
    #垃圾邮件过滤的例子:
    def textParse(bigString):      #正则表达式进行文本分割  
        import re  
        listOfTokens = re.split(r'\W*',bigString)  
        return [tok.lower() for tok in listOfTokens if len(tok) > 2]  
      
    def spamTest():  
        docList = []; classList = []; fullText = []  
        for i in range(1,26):                          #导入并解析文本文件  
            wordList = textParse(open('E:/python project/Bayes/email/spam/%d.txt' % i).read())  
            docList.append(wordList)  
            fullText.extend(wordList)  
            classList.append(1)  
            wordList = textParse(open('E:/python project/Bayes/email/ham/%d.txt' % i).read())  
            docList.append(wordList)  
            fullText.extend(wordList)  
            classList.append(0)  
        vocabList = createVocabList(docList)  
        trainingSet = range(50);testSet = []  
        for i in range(10):                         #随机构建10个测试集  
            randIndex = int(random.uniform(0,len(trainingSet)))  
            testSet.append(trainingSet[randIndex])  
            del(trainingSet[randIndex])  
        trainMat = []; trainClasses = []  
        for docIndex in trainingSet:  
            trainMat.append(setOfWords2Vec(vocabList, docList[docIndex]))  
            trainClasses.append(classList[docIndex])  
        p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))  
        errorCount = 0  
        for docIndex in testSet:              #对测试集进行分类  
            wordVector = setOfWords2Vec(vocabList, docList[docIndex])  
            if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:  
                errorCount += 1  
        print 'the error rate is: ', float(errorCount)/len(testSet)  
    



    展开全文
  • Python 贝叶斯算法

    千次阅读 2018-11-06 22:36:08
    Python 贝叶斯分类 贝叶斯的基本思想 朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。通俗来说,就好比这么个道理,...
  • 主要为大家详细介绍了python实现基于朴素贝叶斯的垃圾分类算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 朴素贝叶斯算法python 实现

    千次阅读 2019-03-23 18:05:14
    利用贝叶斯算法实现分类 import pandas as pd from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from collections import Counter import time class Beyes...
  • python语言实现基于朴素贝叶斯算法的垃圾邮件过滤器-附件资源
  • 首先介绍以下贝叶斯公式:这个是什么意思呢?该如何用呢?相信大家有一定的概率知识基础的同学,对先验概率及条件概率都比较清楚,在这里简单的说一下这条公式的含义:1、首先代表的意思就是在B条件发生的情况下,Ai...
  • 贝叶斯算法及实例python实现

    千次阅读 2018-11-13 09:39:06
    贝叶斯要解决的问题: 为什么要使用贝叶斯: 理解贝叶斯例子: 计算过程: 贝叶斯公式: 贝叶斯公式推导  python经典取球实例:  python拼写纠正实例: 模型比较理论 求解:argmaxc P(c|w) -&gt; ...
  • > 2] # 除了单个字母,例如大写的I,其它单词变成小写 """ 函数说明:测试朴素贝叶斯分类器,使用朴素贝叶斯进行交叉验证 """ def spamTest(): docList = [] classList = [] fullText = [] for i in range(1, 26): # ...
  • 主要介绍了Python实现的朴素贝叶斯算法,结合实例形式详细分析了Python实现与使用朴素贝叶斯算法的具体操作步骤与相关实现技巧,需要的朋友可以参考下
  • 朴素贝叶斯算法原理与Python实现

    千次阅读 热门讨论 2021-06-05 17:24:35
    朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法[1]。...同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。理论上,NBC模型与其他分类方法相比具有最小的误差率。但是实际上并...
  • python实现,包含贝叶斯估计、情感分析、分词等几个文件
  • 主要介绍了朴素贝叶斯分类算法原理与Python实现与使用方法,结合具体实例形式分析了朴素贝叶斯分类算法的概念、原理、实现流程与相关操作技巧,需要的朋友可以参考下
  • 【数据挖掘】贝叶斯网络理论及Python实现(csdn)————程序
  • 内容包括朴素贝叶斯算法python实现代码,实现对iris分类,包含iris的txt格式的数据集。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,242
精华内容 7,696
关键字:

python实现贝叶斯算法