机器学习算法与Python实践(14) - 朴素贝叶斯(Naive Bayesian Mode)

机器学习算法与Python实践(14) - 朴素贝叶斯(Naive Bayesian Mode)

这边文章是关于朴素贝叶斯相关的一些原理知识的介绍以及python代码的展示,这篇文章并非原创,但是这个博主讲述的方式十分的通俗易懂,所以就打算转载这个博主的这篇博客了

一、朴素贝叶斯的算法原理

1.1 概述

贝叶斯分类算法是一大类分类算法的总称

贝叶斯分类算法以样本可能属于某类的概率来作为分类依据

朴素贝叶斯分类算法是贝叶斯分类算法中最简单的一种

注:朴素的意思是条件概率独立性

P ( A ∣ x 1 x 2 x 3 x 4 ) = p ( A ∣ x 1 ) ∗ p ( A ∣ x 2 ) ∗ p ( A ∣ x 3 ) ∗ p ( A ∣ x 4 ) P(A|x_1x_2x_3x_4)=p(A|x_1)*p(A|x_2)*p(A|x_3)*p(A|x_4) P(Ax1x2x3x4)=p(Ax1)p(Ax2)p(Ax3)p(Ax4)则为条件概率独立

P ( x y ∣ z ) = p ( x y z ) p ( z ) = p ( x z ) p ( z ) ∗ p ( y z ) p ( z ) P(xy|z)=\frac{p(xyz)}{p(z)}=\frac{p(xz)}{p(z)}*\frac{p(yz)}{p(z)} P(xyz)=p(z)p(xyz)=p(z)p(xz)p(z)p(yz)

1.2 算法思想

朴素贝叶斯的思想是这样的:

如果一个事物在一些属性条件发生的情况下,事物属于A的概率>属于B的概率,则判定事物属于A。

通俗来说 比如:你在街上看到一个黑人,我让你猜这哥们哪里来的,你十有八九猜非洲。为什么呢?

在你的脑海中,有这么一个判断流程:

1、这个人的肤色是黑色 <特征>

2、黑色人种是非洲人的概率最高 <条件概率:黑色条件下是非洲人的概率>

3、没有其他辅助信息的情况下,最好的判断就是非洲人

这就是 朴素贝叶斯的思想基础

再稍微扩展一下:

假如在街上看到一个黑人讲英语,那我们是怎么去判断他来自于哪里?

提取特征:

肤色: 黑

语言: 英语

黑色人种来自非洲的概率: 80%

黑色人种来自于美国的概率:20%

讲英语的人来自于非洲的概率:10%

讲英语的人来自于美国的概率:90%

在我们的自然思维方式中,就会这样判断:

这个人来自非洲的概率:80% * 10% = 0.08

这个人来自美国的概率:20% * 90% =0.18

我们的判断结果就是:此人来自美国!

其蕴含的数学原理如下:

p ( A ∣ x y ) = p ( A x y ) p ( x y ) = p ( A x y ) p ( x ) p ( y ) = p ( A ) p ( x ) ∗ p ( A ) p ( y ) ∗ p ( x y ) p ( x y ) = p ( A ∣ x ) p ( A ∣ y ) p(A|xy)=\frac{p(Axy)}{p(xy)}=\frac{p(Axy)}{p(x)p(y)}=\frac{p(A)}{p(x)}*\frac{p(A)}{p(y)}*\frac{p(xy)}{p(xy)}=p(A|x)p(A|y) p(Axy)=p(xy)p(Axy)=p(x)p(y)p(Axy)=p(x)p(A)p(y)p(A)p(xy)p(xy)=p(Ax)p(Ay)

P ( 类 别 ∣ 特 征 ) = P ( 特 征 ∣ 类 别 ) ∗ P ( 类 别 ) P ( 特 征 ) P(类别 | 特征)=P(特征 | 类别)*\frac{P(类别) }{ P(特征)} P()=P()P()P()

1.3 算法思路
  • 分解各类先验样本中的数据特征

  • 计算各类数据中,各特征的条件概率
    (比如:特征1出现的情况下,属于A类的概率p(A|特征1),属于B类的概率p(B|特征1),属于C类的概率p(C|特征1)…)

  • 分解待分类数据中的特征(特征1,特征2,特征3,特征4)

  • 计算各特征的各条件概率的乘积,如下所示:

    判断为A类的概率: p ( A ∣ 特 征 1 ) ∗ p ( A ∣ 特 征 2 ) ∗ p ( A ∣ 特 征 3 ) ∗ p ( A ∣ 特 征 4 ) . . . . . p(A|特征1)*p(A|特征2)*p(A|特征3)*p(A|特征4) ..... p(A1)p(A2)p(A3)p(A4).....

    判断为B类的概率: p ( B ∣ 特 征 1 ) ∗ p ( B ∣ 特 征 2 ) ∗ p ( B ∣ 特 征 3 ) ∗ p ( B ∣ 特 征 4 ) . . . . . p(B|特征1)*p(B|特征2)*p(B|特征3)*p(B|特征4) ..... p(B1)p(B2)p(B3)p(B4).....

    判断为C类的概率: p ( C ∣ 特 征 1 ) ∗ p ( C ∣ 特 征 2 ) ∗ p ( C ∣ 特 征 3 ) ∗ p ( C ∣ 特 征 4 ) . . . . . p(C|特征1)*p(C|特征2)*p(C|特征3)*p(C|特征4) ..... p(C1)p(C2)p(C3)p(C4).....

    . . . . . . ...... ......

  • 结果中的最大值就是该样本所属的类别

1.4 真实案例分析以及python代码实现
1.41 案例详情

大众点评、淘宝等电商上都会有大量的用户评论,比如:

评价内容评论分类
1.衣服质量太差了!!!!颜色根本不纯!!!0
2.我有一有种上当受骗的感觉!!!!0
3.质量太差,衣服拿到手感觉像旧货!!!0
4.上身漂亮,合身,很帅,给卖家点赞1
5.穿上衣服帅呆了,给点一万个赞1
6.我在他家买了三件衣服!!!!质量都很差!0

其中 1 / 2 / 3 / 6 1/2/3/6 1/2/3/6是差评, 4 / 5 4/5 4/5是好评

现在需要使用朴素贝叶斯分类算法来自动分类其他的评论,比如:

评论内容评论分类
a、这么差的衣服以后再也不买了
b、帅,有逼格
……
1.4.2 设计算法流程
  • 分解出先验数据中的各特征

    (即分词,比如“衣服”“质量太差”“差”“不纯”“帅”“漂亮”,“赞”……)

  • 计算各类别(好评、差评)中,各特征的条件概率

    (比如 p(“衣服”|差评)、p(“衣服”|好评)、p(“差”|好评) 、p(“差”|差评)……)

  • 分解出待分类样本的各特征

    (比如分解a: “差” “衣服” ……)

  • 计算类别概率

    P(好评) = p(好评|“差”) p(好评|“衣服”)……

    P(差评) = p(差评|“差”) p(差评|“衣服”)……

  • 显然P(差评)的结果值更大,因此a被判别为“差评”

1.4.3 分类计算案例

大体计算方法:

P ( 好 评 ∣ 单 词 1 , 单 词 2 , 单 词 3 ) = P ( 单 词 1 , 单 词 2 , 单 词 3 ∣ 好 评 ) ∗ P ( 好 评 ) P ( 单 词 1 , 单 词 2 , 单 词 3 ) P(好评 | 单词1,单词2,单词3) = \frac{P(单词1,单词2,单词3 | 好评) * P(好评) }{ P(单词1,单词2,单词3)} P(1,2,3)=P(1,2,3)P(1,2,3)P()

因为分母都相同,所以只用比较分子即可: P ( 单 词 1 , 单 词 2 , 单 词 3 ∣ 好 评 ) ∗ P ( 好 评 ) P(单词1,单词2,单词3 | 好评) *P(好评) P(1,2,3)P()

每个单词之间都是相互独立的: P ( 单 词 1 ∣ 好 评 ) ∗ P ( 单 词 2 ∣ 好 评 ) ∗ P ( 单 词 3 ∣ 好 评 ) ∗ P ( 好 评 ) P(单词1 | 好评)*P(单词2 | 好评)*P(单词3 | 好评)*P(好评) P(1)P(2)P(3)P()

P ( 单 词 1 ∣ 好 评 ) = 单 词 1 在 样 本 好 评 中 出 现 的 总 次 数 样 本 好 评 句 子 中 总 的 单 词 数 P(单词1 | 好评) = \frac{单词1在样本好评中出现的总次数}{样本好评句子中总的单词数} P(1)=1

P ( 好 评 ) = 样 本 好 评 的 条 数 样 本 的 总 条 数 P(好评) = \frac{样本好评的条数}{样本的总条数} P()=

同理:

P ( 差 评 ∣ 单 词 1 , 单 词 2 , 单 词 3 ) = P ( 单 词 1 , 单 词 2 , 单 词 3 ∣ 差 评 ) ∗ P ( 差 评 ) P ( 单 词 1 , 单 词 2 , 单 词 3 ) P(差评 | 单词1,单词2,单词3) = \frac{P(单词1,单词2,单词3 | 差评) * P(差评)}{ P(单词1,单词2,单词3)} P(123)=P(123)P(123)P()

因为分母都相同,所以只用比较分子即可: P ( 单 词 1 , 单 词 2 , 单 词 3 ∣ 差 评 ) ∗ P ( 差 评 ) P(单词1,单词2,单词3 | 差评) *P(差评) P(123)P()

每个单词之间都是相互独立的: P ( 单 词 1 ∣ 差 评 ) ∗ P ( 单 词 2 ∣ 差 评 ) ∗ P ( 单 词 3 ∣ 差 评 ) ∗ P ( 差 评 ) P(单词1 | 差评)*P(单词2 | 差评)*P(单词3 | 差评)*P(差评) P(1)P(2)P(3)P()

#!/usr/bin/python
# coding=utf-8
from numpy import *


# 过滤网站的恶意留言  侮辱性:1     非侮辱性:0
# 创建一个实验样本
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([])  # 创建一个空集
    # print(type(vocabSet))
    for document in dataSet:
        vocabSet = vocabSet | set(document)  # 创建两个集合的并集
    print('vocabSet:', list(vocabSet))
    print(len(vocabSet))
    return list(vocabSet)


# 将文档词条转换成词向量
def setOfWords2Vec(vocabList, inputSet):
    # print(vocabList)
    # print(inputSet)
    # print('-' * 100)
    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)
    # print('returnVec:', returnVec)
    # print(len(returnVec))
    return returnVec


# 朴素贝叶斯分类器训练函数   从词向量计算概率
def trainNB0(trainMatrix, trainCategory):
    print('-' * 10)
    print(trainMatrix)
    print(trainCategory)
    numTrainDocs = len(trainMatrix)
    print(numTrainDocs)
    numWords = len(trainMatrix[0])
    print(numWords)
    pAbusive = sum(trainCategory) / float(numTrainDocs)
    print(pAbusive)
    # p0Num = zeros(numWords); p1Num = zeros(numWords)
    # p0Denom = 0.0; p1Denom = 0.0
    p0Num = ones(numWords)  # 避免一个概率值为0,最后的乘积也为0
    p1Num = ones(numWords)  # 用来统计两类数据中,各词的词频
    p0Denom = 2.0  # 用于统计0类中的总数
    p1Denom = 2.0  # 用于统计1类中的总数
    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
    p1Vect = log(p1Num / p1Denom)  # 在类1中,每个词的发生概率
    p0Vect = log(p0Num / p0Denom)  # 避免下溢出或者浮点数舍入导致的错误   下溢出是由太多很小的数相乘得到的
    print('-' * 10)

    return p0Vect, p1Vect, pAbusive


# 朴素贝叶斯分类器
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + log(pClass1)
    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0


def testingNB():
    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, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))


if __name__ == '__main__':
    testingNB()

结果如下:
在这里插入图片描述
参考博客:https://www.cnblogs.com/ahu-lichang/p/7157855.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值