朴素贝叶斯算法

0.朴素贝叶斯

  • 朴素:特征条件独立
  • 贝叶斯:基于贝叶斯定理

1.朴素贝叶斯算法优缺点

  • 优点:在数据较少的情况下依然有效,可以处理多类别问题
  • 缺点:对输入数据的准备方式敏感
  • 适用数据类型:标称型数据

2.算法思想:

  •     比如我们想判断一个邮件是不是垃圾邮件,那么我们知道的是这个邮件中的词的分布,那么我们还要知道:垃圾邮件中某些词的出现是多少,就可以利用贝叶斯定理得到。

  •   朴素贝叶斯分类器中的一个假设是:每个特征同等重要

  • 贝叶斯公式
    p(y=Ck|X)=p(X|y=Ck)p(y=Ck)p(X)
  • X 是M维向量的时候 因为特征条件独立(朴素),根据全概率公式展开
    p(y=Ck|X)=mi=1p(xi|y=Ck)p(y=Ck)mi=1p(xi|y=Ck)kp(y=Ck)

即求在x词句出现的情况下是侮辱性言乱还是正常言论的概率
1.本算法中p(y=1) 通过样本我们可以知道概率(代码中的pAbusive)
2.而叠乘利用数学性质 换做叠加
3.未完待续…….

3.算法伪代码

计算每个类别中的文档数目
for 每篇文档
    每个类别
        词条出现在文档中 增加计数值
        增加所有词条计数值
    对每个类别
        对每个词条
            该词条数目/总词条数目 得到该类别的条件概率
返回 每个类别的条件概率

4.算法代码

# -*- coding:utf-8 -*-

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]  # 1代表侮辱性文字  0代表正常言论
    return postingList, classVec  # 返回输入数据和标签向量

# 创建'词库'
def createWordList(dataSet):
    wordList = set([])
    for line in dataSet:
        wordList = wordList | set(line)  # 按位与和集合合并相同符号
    return list(wordList)  # 单词的集合list 无重复


def word2Vec(wordList, inputSet):  # 词袋统计 不单纯01而是记录出现次数(为多项式模型)
    Vec = [0] * len(wordList)
    for word in inputSet:
        if word in wordList:
            Vec[wordList.index(word)] += 1
        else:
            print "%s is not in this word list !!!" % word
    return Vec


def classifyNB(inputVec, p0Vec, p1Vec, pClass1):
    p1 = sum(inputVec * p1Vec) + log(pClass1)
    p0 = sum(inputVec * p0Vec) + log(1.0 - pClass1)  #  
    if p1 > p0:
        return 'abuse !!!'
    else:
        return 'normal ^_^'


def trainNB(trainMatrix, trainLabel):  # 输入的文档信息和分类标签
    numTrainMatrix = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainLabel) / float(numTrainMatrix)  # p(y=1)侮辱性语句的概率
    print "sum of trainLabel", sum(trainLabel)
    print "pAbusive", pAbusive  # 先验概率
    p0Num = ones(numWords)
    p1Num = ones(numWords)
    p0Denom = 2.0
    p1Denom = 2.0
    for i in range(numTrainMatrix):
        if trainLabel[i] == 1:
            # 利用log(a+b)=log(a)*log(b)的性质 加法代替乘法 便于计算(避免乘法0与精度问题)
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = log(p1Num / p1Denom)  # 侮辱语言类类的条件概率
    p0Vect = log(p0Num / p0Denom)  # 正常类的条件概率

    print "p1num", p1Num
    print "p1Denom", p1Denom
    print "p0num", p0Num
    print "p0Denom", p0Denom

    return p0Vect, p1Vect, pAbusive


def testNB():
    dataSet, labelSet = loadDataSet()
    # print "dataSet", dataSet
    wordList = createWordList(dataSet)
    # print "wordList", wordList
    trainMat = []
    for item in dataSet:
        trainMat.append(word2Vec(wordList, item))
    print "labelset", labelSet
    print "trainMat", trainMat
    print "shape of trainMat", shape(trainMat)
    p0v, p1v, pAb = trainNB(trainMat, labelSet)
    print "p0v", p0v
    print "p1v", p1v
    print "pab", pAb
    # test1
    testData = ['love', 'my', 'dalmation']
    thisDoc = array(word2Vec(wordList, testData))
    print testData, "test result is --", classifyNB(thisDoc, p0v, p1v, pAb)
    # test2
    testData = ['stupid', 'garbage']
    thisDoc = array(word2Vec(wordList, testData))
    print testData, "test result is --", classifyNB(thisDoc, p0v, p1v, pAb)

if __name__ == '__main__':
    testNB()

5.运行结果

'''
labelset [0, 1, 0, 1, 0, 1]
trainMat [[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0], [1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1], [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]]
shape of trainMat (6L, 32L)
sum of trainLabel 3
pAbusive 0.5
p1num [ 1.  1.  1.  2.  2.  1.  1.  1.  2.  2.  1.  1.  1.  2.  2.  2.  2.  2.
  1.  3.  1.  2.  2.  1.  3.  1.  4.  1.  2.  1.  1.  1.]
p1Denom 21.0
p0num [ 2.  2.  2.  1.  1.  2.  2.  2.  1.  2.  2.  2.  2.  1.  1.  3.  1.  1.
  2.  1.  2.  2.  1.  2.  2.  2.  1.  2.  1.  2.  2.  4.]
p0Denom 26.0
p0v [-2.56494936 -2.56494936 -2.56494936 -3.25809654 -3.25809654 -2.56494936
 -2.56494936 -2.56494936 -3.25809654 -2.56494936 -2.56494936 -2.56494936
 -2.56494936 -3.25809654 -3.25809654 -2.15948425 -3.25809654 -3.25809654
 -2.56494936 -3.25809654 -2.56494936 -2.56494936 -3.25809654 -2.56494936
 -2.56494936 -2.56494936 -3.25809654 -2.56494936 -3.25809654 -2.56494936
 -2.56494936 -1.87180218]
p1v [-3.04452244 -3.04452244 -3.04452244 -2.35137526 -2.35137526 -3.04452244
 -3.04452244 -3.04452244 -2.35137526 -2.35137526 -3.04452244 -3.04452244
 -3.04452244 -2.35137526 -2.35137526 -2.35137526 -2.35137526 -2.35137526
 -3.04452244 -1.94591015 -3.04452244 -2.35137526 -2.35137526 -3.04452244
 -1.94591015 -3.04452244 -1.65822808 -3.04452244 -2.35137526 -3.04452244
 -3.04452244 -3.04452244]
pab 0.5
['love', 'my', 'dalmation'] test result is -- normal ^_^
['stupid', 'garbage'] test result is -- abuse !!!

'''
# 原始的p1v p0v 概率向量
# 可以看出第一个词'cute'在第一类中出现而第二类则没有
# 第二类中倒数第六个数据大于其他数据 对比发现这个词是stupid 最能表征这一类(侮辱性文档)的单词
'''
p0v [ 0.04166667  0.04166667  0.04166667  0.          0.          0.04166667
  0.04166667  0.04166667  0.          0.04166667  0.04166667  0.04166667
  0.04166667  0.          0.          0.08333333  0.          0.
  0.04166667  0.          0.04166667  0.04166667  0.          0.04166667
  0.04166667  0.04166667  0.          0.04166667  0.          0.04166667
  0.04166667  0.125     ]
p1v [ 0.          0.          0.          0.05263158  0.05263158  0.          0.
  0.          0.05263158  0.05263158  0.          0.          0.
  0.05263158  0.05263158  0.05263158  0.05263158  0.05263158  0.
  0.10526316  0.          0.05263158  0.05263158  0.          0.10526316
  0.          0.15789474  0.          0.05263158  0.          0.          0.        ]
'''

6.sklearn库的使用

# coding:utf-8

import sklearn.naive_bayes


'''
数据例
基因片断A 基因片断B 高血压y1 胆结石y2 (1患该病 0正常)
    1        1         1        0    
    0        0         0        1    
    0        1         0        0    
    1        0         0        0    
    1        1         0        1    
    1        0         0        1    
    0        1         1        1    
    0        0         0        0    
    1        0         1        0    
    0        1         0        1  
'''

x = [[1, 1], [0, 0], [0, 1], [1, 0], [1, 1], [1, 0], [0, 1], [0, 0], [1, 0], [0, 1]]
y1 = [1, 0, 0, 0, 0, 0, 1, 0, 1, 0]

# 训练
clf = sklearn.naive_bayes.GaussianNB().fit(x, y1)

p = [[1, 0]]
# 预测
print clf.predict(p)  # [0]

y2 = [0, 1, 0, 0, 1, 1, 1, 0, 0, 1]
clf = sklearn.naive_bayes.GaussianNB().fit(x, y2)

p = [[1, 0]]
print clf.predict(p)  # [0]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值