朴素贝叶斯算法

原创 2017年07月31日 22:08:06

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]

版权声明:有错误麻烦赐教,感激不尽~~~(转载留言哦~)

简单易学的机器学习算法——朴素贝叶斯

一、贝叶斯定理

朴素贝叶斯算法源码

  • 2012年08月14日 17:20
  • 48KB
  • 下载

算法之朴素贝叶斯分类(Naive Bayesian classification

一、摘要          贝叶斯分类是一类分类算法的总称,这类算法以贝叶斯定理为基础,所以统称为贝叶斯分类。 二、分类问题综述         已知集合:和,确定映射规则,使得任意有且仅有一个使得成...

朴素贝叶斯算法 c++

  • 2014年03月11日 23:26
  • 8KB
  • 下载

EM算法理解——从朴素贝叶斯角度出发

参考资料: http://www.cnblogs.com/jerrylead/archive/2011/04/06/2006936.html其实虽然说看了一天的EM算法,但是当初是没有理解这个问题的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:朴素贝叶斯算法
举报原因:
原因补充:

(最多只允许输入30个字)