朴素贝叶斯原理及python实现_机器学习-朴素贝叶斯原理及Python实现

机器学习-朴素贝叶斯原理及Python实现

贝叶斯公式

P(A|B) = (P(B|A)P(A))/P(B)

举例:苹果10个,有2个黄色;梨10个,有6个黄色,求拿出一个黄色水果,是苹果的概率。

代入公式:

P(苹果|黄色) = (P(黄色|苹果)P(苹果))/P(黄色)

P(黄色) = (2+6)/20 = 2/5

P(苹果) = 10/20 = 1/2 = 0.5

P(黄色|苹果)=1/5

P(黄色|苹果)P(苹果) = P(黄色,苹果) = 1/5*1/2 = 1/10 = 0.1

P(苹果|黄色) = 0.1/0.5=0.2

朴素贝叶斯是一种十分简单的分类算法,称其朴素是因为其思想基础的简单性:就文本而言,它认为词袋中的两两词之间的关系是相互独立的,即一个对象的特征向量中每个维度都是相互独立的。

黄色是苹果和梨共有的属性,但苹果和梨是相互独立的。

朴素贝叶斯的正式定义如下:

(1)设x = {a1,a2,....,am}为一个待分类项,而每个a为x的一个特征属性。

(2)有类别集合 C = {y1,y2,...yn}

(3)计算P(y1|x),P(y2|x),...P(yn|x).

(4)如果P(yk|x) = max(P(y1|x),P(y2|x),...P(yn|x)),则x∈yk.

关键就是计算第(3)步中的各个条件概率,可按照以下步骤计算

(1)找到一个已知分类的待分类项集合,也就是训练集。

(2)统计得到在各类别下各个特征属性的条件概率估计。即:

P(a1|y1),P(a2|y1),...P(am|y1);

P(a1|y2),P(a2|y2),...P(am|y2);

P(a1|y1),P(a2|yn),...P(am|yn);

(3)如果各个特征属性是条件独立的(或者假设它们之间是相互独立的),则根据贝叶斯定理有如下推导

P(yi|x) = (P(x|yi)P(yi))/P(x)

因为分母对于所有类别为常熟,只要将分子最大化即可。又因为各特征属性是条件独立的,所以又

P(x|yi)P(yi) = P(a1|yi)P(a2|yi)...P(am|yi)P(yi)

根据上述分析,朴素贝叶斯分类的流程可以表示如下:

第一阶段:训练数据生成训练样本集:TF-IDF

第二阶段:对每个类别计算P(yi)

第三阶段:对每个特征属性计算所有划分的条件概率

第四阶段:对每个类别计算P(x|yi)P(yi)

第五阶段:以P(x|yi)P(yi)的最大项作为x的所属类别。

代码:

import numpy as np

class NBayes(object):

# 1.默认构造方法

def __init__(self):

self.vocabulary = [] # 词典 所有数据单词去重

self.idf = 0 # 词典的IDF权值向量,一行,词典数列,值为该词出现的文本数

self.tf = 0 # 训练集的权值矩阵,每个文本集一行,统计文本集中词出现的次数

self.tdm = 0 # P(x|yi) (类别行,词典数列)/类别的词出现次数的总和

self.Pcates = {} # P(yi)是一个类别字典, 每个类别数据条数/总数

self.labels = [] # 对应每个文本的分类,是一个外部导入的列表

self.doclength = 0 # 训练集文本数

self.vocablen = 0 # 词典词长 #词典中词的个数

self.testset = 0 # 测试集

# 2.导入和训练数据集,生成算法必须的参数和数据结构

def train_set(self, trainset, classVec):

self.cate_prob(classVec) # 计算每个分类在数据集中的概率P(yi) 每个分类的数据条数/总的数据条数

self.doclength = len(trainset) # 训练集数量

tempset = set()

[tempset.add(word) for doc in trainset for word in doc] # 生成词典 所有数据单词去重

self.vocabulary = list(tempset) #去重后的词典

self.vocablen = len(self.vocabulary) #词典中词的个数

self.calc_wordfreq(trainset) # 计算词频数据集 tf、idf

self.build_tdm() # 按分类累计向量空间的每维值P(x|yi)

# 3.cate_prob函数:计算在数据集中每个分类的概率P(yi)

def cate_prob(self,classVec):

self.labels = classVec

labeltemps = set(self.labels) # 获取全部分类

for labeltemp in labeltemps:

# 统计列表中重复的分类:self.labels.count(labeltemp)

self.Pcates[labeltemp] = float(self.labels.count(labeltemp)) / float(len(self.labels))

# 4.calc_wordfreq函数:生成普通的词频向量

def calc_wordfreq(self, trainset):

self.idf = np.zeros([1, self.vocablen]) # 1*字典数 1行vocablen列的数组

self.tf = np.zeros([self.doclength, self.vocablen]) # 训练集文件数 * 词典数

for indx in range(self.doclength): # 遍历所有的文本

for word in trainset[indx]: # 遍历文本中的每个词

# 找到文本的词在字典中的位置+1

self.tf[indx, self.vocabulary.index(word)] += 1 # 单词出现的次数,累加

for signleword in set(trainset[indx]):

self.idf[0,self.vocabulary.index(signleword)] += 1 # 单词出现的文章数,累加

# 5.build_tdm函数:按分类累计计算向量空间的每维值P(x|yi)

def build_tdm(self):

self.tdm = np.zeros([len(self.Pcates), self.vocablen]) # 类别行 * 词典列

sumlist = np.zeros([len(self.Pcates), 1]) # 统计每个分类的总值 类别行,一列

for indx in range(self.doclength): # 遍历文本集

# 将同一类别的词向量空间值加总

self.tdm[self.labels[indx]] += self.tf[indx] # 同一类别的词向量值加总。self.labels[indx]:类别标签 self.tf[indx]:文本中每个词出现的次数

# 统计每个分类的总值--是一个标量

sumlist[self.labels[indx]] = np.sum(self.tdm[self.labels[indx]]) # 同一类别词向量值加总为一个值

self.tdm = self.tdm / sumlist # 生成P(x|yi) 同一类别的词出现的次数/该类别下词出现的次数总和

# 6.map2vocab函数:将测试集映射到当前词典,计算测试数据在训练数据词典的词频

def map2vocab(self, testdata):

self.testset = np.zeros([1, self.vocablen])

for word in testdata:

self.testset[0, self.vocabulary.index(word)] += 1

# 7.predict函数:预测分类结果,输出预测的分类类别

def predict(self, testset):

if np.shape(testset)[1] != self.vocablen: # 如果测试集长度与词典不相等,则退出程序

print('输入错误')

exit(0)

predvalue = 0 # 初始化类别概率

predclass = "" # 初始化类别名称

print(self.tdm)

print(self.Pcates)

for tdm_vect, keyclass in zip(self.tdm, self.Pcates): # zip(),按索引组件元组[(a[i],b[i])] tdm_vect:类别词概率 keyclass:类别

# P(x|yi)P(yi),变量tdm,计算最大分类值

temp = np.sum(testset * tdm_vect * self.Pcates[keyclass]) # 测试集在该类别出现的概率

if temp > predvalue:

predvalue = temp

predclass = keyclass

return predclass

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', 'my'],

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

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

['quit', 'buying', 'worthless', 'dog', 'food', 'stopid']

]

# 每个文本对应的分类

classVec = [0, 1, 0, 1, 0, 1]

return postingList, classVec

# 导入外部数据集

# dataset:句子的词向量,listClasses:是句子所属的类别

dataset, listClasses = loadDataSet()

nb = NBayes() # 实例化

nb.train_set(dataset, listClasses) # 训练数据集

nb.map2vocab(dataset[0]) # 随机选择一个测试句

print(nb.predict(nb.testset))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值