机器学习之朴素贝叶斯分类器实现

参考网址:https://blog.csdn.net/zhelong3205/article/details/78659169
之前已经介绍了先验概率,后验概率,类条件概率,现在举例说明其应用。

问题如下

比如:有如下的需求,要判断某一句英语是不是侮辱性语句

分析思路

对于机器来说,可能不容易分辨出某一句话是不是侮辱性的句子,但是机器可以机械的进行分析,何为机械的进行分析,就是判断某一个句子中侮辱性的单词是不是达到一定数量(当然这个只是判决准则中很简单的一种)。这个方法叫词集法!

代码思路

规定标记:w0 (值为0)表示非侮辱性句子 w1(值为1) 表示侮辱性句子

1、收集侮辱性的句子和反例若干

构造数据集,分类是侮辱性 or 非侮辱性

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 is abusive, 0 not
    return postingList, classVec
2、统计出所有单词,构造一个单词表wordlist
# 创建一个包涵所有词汇的列表 , 为后面建立词条向量使用
def createlist (dataset) :
    vovabset = set ([])
    for vec in dataset :
        vovabset = vovabset | set (vec)
    return list (vovabset)
3、计算先验概率、类条件概率

注意,这里的类条件分布用对数表示


  • 这里的先验概率,指的是随机给一个句子,是侮辱性句子的概率或者非侮辱性句子的概率
    (当然,这里说的概率就是样本中的频率)
  • 对于类条件概率,就是指已经知道某个句子是侮辱性句子,或者非侮辱性句子,假设已经知道某个句子是侮辱性句子,则该句子的单词在单词表中的概率分布就是类条件概率!

代码如下

# 创建贝叶斯分类器
def trainNBO (dataset, classlebels) :
    num_of_sample = len (dataset)
    num_of_feature = len (dataset[0])
    pAusuive = sum (classlebels) / num_of_sample # 侮辱性语言的概率
    p0Num = np.ones (num_of_feature)
    p1Num = np.ones (num_of_feature)
    p0tot = num_of_feature
    p1tot = num_of_feature
    for i in range (num_of_sample) :
        if classlebels[i] == 1 :
            p1Num += dataset[i]
            p1tot += sum (dataset[i])
        else :
            p0Num += dataset[i]
            p0tot += sum (dataset[i])
    p0Vec = p0Num / p0tot
    p1Vec = p1Num / p1tot
    for i in range (num_of_feature) :
        p0Vec[i] = math.log (p0Vec[i])
        p1Vec[i] = math.log (p1Vec[i])
    return p0Vec, p1Vec, pAusuive

返回的结果pAusuive就是先验分布,p0Vec,p1Vec就是类条件分布。
对于本题,计算出先验概率和后验概率就相当于把贝叶斯分类器训练出来了

4、测试

给定一个句子,求其后验概率p(w0|x),p(w1|x)
如果p(w0|x)>p(w1|x),则该句子属于非侮辱性句子,反之属于侮辱性句子。
如何求解后验分布,可以根据已经求得的先验分布和类条件分布进行求解!
代码如下:

#  定义分类器
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + math.log(pClass1)      #element-wise mult
    p0 = sum(vec2Classify * p0Vec) + math.log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0

该函数参数p0Vec,p1Vec指的是类条件概率,pClass1指的是先验概率
返回的是该句子属于哪一个类,值为0,即w0,值为1,即w1。

代码实现如下

import numpy as np
import math
# 使用词集法进行贝叶斯分类
# 构造数据集,分类是侮辱性 or 非侮辱性
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 is abusive, 0 not
    return postingList, classVec


# 创建一个包涵所有词汇的列表 , 为后面建立词条向量使用
def createlist (dataset) :
    vovabset = set ([])
    for vec in dataset :
        vovabset = vovabset | set (vec)
    return list (vovabset)

# 将词条转化为向量的形式
def changeword2vec (inputdata, wordlist) :
    returnVec = [0] * len (wordlist)
    for word in inputdata :
        if word in wordlist :
            returnVec[wordlist.index(word)] = 1
    return returnVec

# 创建贝叶斯分类器
def trainNBO (dataset, classlebels) :
    num_of_sample = len (dataset)
    num_of_feature = len (dataset[0])
    pAusuive = sum (classlebels) / num_of_sample # 侮辱性语言的概率
    p0Num = np.ones (num_of_feature)
    p1Num = np.ones (num_of_feature)
    p0tot = num_of_feature
    p1tot = num_of_feature
    for i in range (num_of_sample) :
        if classlebels[i] == 1 :
            p1Num += dataset[i]
            p1tot += sum (dataset[i])
        else :
            p0Num += dataset[i]
            p0tot += sum (dataset[i])
    p0Vec = p0Num / p0tot
    p1Vec = p1Num / p1tot
    for i in range (num_of_feature) :
        p0Vec[i] = math.log (p0Vec[i])
        p1Vec[i] = math.log (p1Vec[i])
    return p0Vec, p1Vec, pAusuive


#  定义分类器
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + math.log(pClass1)      #element-wise mult
    p0 = sum(vec2Classify * p0Vec) + math.log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0

# 测试代码
dataset,classlebels = loadDataset ()
wordlist = createlist(dataset)
print (wordlist)
print (changeword2vec (dataset[0], wordlist))
trainmat = []
for temp in dataset :
    trainmat.append (changeword2vec (temp,wordlist))
p0V, p1V, pAb = trainNBO (trainmat, classlebels)
print(p0V)
print(p1V)
print(pAb)

# 对训练集进行测试
dataset,classlebels = loadDataset()
vec2Classify = changeword2vec(dataset[0], wordlist)
print(classifyNB(vec2Classify, p0V, p1V, pAb))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值