各位朋友们,小编在这里要分享,python零基础能学吗 知乎 python编程0基础怎么学,让我们开始吧!
朴素贝叶斯算法的python实现
一 实验准备实验介绍二 实验步骤2.1 朴素贝叶斯介绍2.2 朴素贝叶斯相关的统计学知识2.2.1 条件概率公式2.2.2 全概率公式2.2.3 贝叶斯公式推断2.3 朴素贝叶斯的python实现1、导入所需包2、加载数据集合及其对应的分类,从训练数据集中提取出属性矩阵和分类数据3、生成包含所有单词的list( 此处生成的单词向量是不重复的)4、 把单词转化为词向量,计算数据集中每一行每个单词出现的次数,如果此单词在数组中,数组的项值置15、计算,生成每个词对于类别上的概率(其中概率是以ln进行计算的)
一 实验准备
实验介绍
在所有的机器学习分类算法中,朴素贝叶斯(Naive Bayesian Model,NBM)和其他绝大多数的分类算法都不同好用简单的PHP后台框架的重要性。对于大多数的分类算法,比如决策树,KNN,逻辑回归,支持向量机等,他们都是判别方法,也就是直接学习出特征输出Y和特征X之间的关系,要么是决策函数 𝑌=𝑓(𝑋) ,要么是条件分布 𝑃(𝑌|𝑋) 。但是朴素贝叶斯却是生成方法,也就是直接找出特征输出Y和特征X的联合分布 𝑃(𝑋,𝑌) ,然后用 𝑃(𝑌|𝑋)=𝑃(𝑋,𝑌)/𝑃(𝑋) 得出。
朴素贝叶斯分类的流程可以由下图表示(暂时不考虑验证):实验目的
学习了解朴素贝叶斯的基本介绍学习掌握朴素贝叶斯算法相关的统计学知识(条件概率、全概率、以及贝叶斯公式推断)python实现朴素贝叶斯的代码详解(过滤广告、垃圾邮件)sklearn中的朴素贝叶斯(高斯朴素贝叶斯、多项式朴素贝叶斯、伯努利朴素贝叶斯)三种方法的详解
实验准备 服务器端:python3.6以上、Jupyter Notebook 客户端:Google Chrome浏览器
二 实验步骤
2.1 朴素贝叶斯介绍
贝叶斯分类算法是统计学的一种概率分类方法,朴素贝叶斯分类是贝叶斯分类中最简单的一种,朴素贝叶斯法(Naive Bayes)是基于贝叶斯定理与特征条件独立假设的分类方法,其分类原理就是利用贝叶斯公式根据某特征的先验概率计算出其后验概率,然后选择具有最大后验概率的类作为该特征所属的类。之所以称之为“朴素”,是因为贝叶斯分类只做最原始、最简单的假设:所有的特征之间都是相互独立的。
假设某样本 X X X有 a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1,a2,…,an个属性,那么有 P ( X ) = P ( a 1 , a 2 , … , a n ) = P ( a 1 ) ∗ P ( a 2 ) ∗ P ( a n ) P(X)=P(a_1,a_2,\ldots,a_n)=P(a_1)*P(a_2)*P(a_n) P(X)=P(a1,a2,…,an)=P(a1)∗P(a2)∗P(an)。满足这样的公式就说明特征统计独立。
2.2 朴素贝叶斯相关的统计学知识
在了解朴素贝叶斯的算法之前,我们需要对相关必须的统计学知识做一个回顾。
贝叶斯学派很古老,但是从诞生到一百年前一直不是主流。主流是频率学派。频率学派的权威皮尔逊和费歇尔都对贝叶斯学派不屑一顾,但是贝叶斯学派硬是凭借在现代特定领域的出色应用表现为自己赢得了半壁江山。
贝叶斯学派的思想可以概括为先验概率+数据=后验概率。也就是说我们在实际问题中需要得到的后验概率,可以通过先验概率和数据一起综合得到。数据大家好理解,被频率学派攻击的是先验概率,一般来说先验概率就是我们对于数据所在领域的历史经验,但是这个经验常常难以量化或者模型化,于是贝叶斯学派大胆的假设先验分布的模型,比如正态分布,beta分布等。这个假设一般没有特定的依据,因此一直被频率学派认为很荒谬。虽然难以从严密的数学逻辑里推出贝叶斯学派的逻辑,但是在很多实际应用中,贝叶斯理论很好用,比如垃圾邮件分类,文本分类。
2.2.1 条件概率公式
条件概率公式(Condittional probability),是指在事件B发生的情况下,事件A发生的概率,用 P ( A ∣ B ) P(A|B) P(A∣B)来表示。 根据文氏图可知:在事件B发生的情况下,事件A发生的概率就是 P ( A ∣ B ) P(A|B) P(A∣B)除以 P ( B ) P(B) P(B)。
P ( A ∣ B ) = P ( A ∩ B ) P ( B ) = > P ( A ∩ B ) = P ( A ∣ B ) P ( B ) P(A|B) = \frac{ P(A\cap B)}{ P(B) }\\ => P(A\cap B) = P(A|B)P(B) P(A∣B)=P(B)P(A∩B)=>P(A∩B)=P(A∣B)P(B) 同理可得:
P ( A ∩ B ) = P ( B ∣ A ) P ( A ) P(A\cap B) = P(B|A)P(A) P(A∩B)=P(B∣A)P(A)
所以,
P ( A ∣ B ) P ( B ) = P ( B ∣ A ) P ( A ) = > P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B)P(B)=P(B|A)P(A)\\ => P(A|B)=\frac{P(B|A)P(A)}{P(B)} P(A∣B)P(B)=P(B∣A)P(A)=>P(A∣B)=P(B)P(B∣A)P(A)
2.2.2 全概率公式
如果事件 A 1 , A 2 , A 3 , , A N A_1,A_2,A_3,,A_N A1,A2,A3,,AN构成一个完备事件且都有正概率,那么对于任意一个事件B则有:
P ( B ) = P ( B A 1 ) + P ( B A 2 ) + … + P ( B A n ) = P ( B ∣ A 1 ) P ( A 1 ) + P ( B ∣ A 2 ) P ( A 2 ) + … + P ( B ∣ A n ) P ( A n ) \begin{aligned} P(B)&=P(BA_1)+P(BA_2)+\ldots+P(BA_n) \\ &=P(B|A_1)P(A_1)+P(B|A_2)P(A_2)+\ldots+P(B|A_n)P(A_n) \end{aligned} P(B)=P(BA1)+P(BA2)+…+P(BAn)=P(B∣A1)P(A1)+P(B∣A2)P(A2)+…+P(B∣An)P(An)
P ( B ) = ∑ i = 1 n P ( A i ) P ( B ∣ A i ) P(B)=\sum_{i=1}^{n}{P(A_i)P(B|A_i)} P(B)=i=1∑nP(Ai)P(B∣Ai)
2.2.3 贝叶斯公式推断
根据条件概率和全概率公式,可以得到贝叶斯公式如下: P ( A ∣ B ) = P ( A ) P ( B ∣ A ) P ( B ) P(A|B)=P(A)\frac{P(B|A)}{P(B)} P(A∣B)=P(A)P(B)P(B∣A) 转换为分类任务的表达式: P ( 类 别 ∣ 特 征 ) = P ( 类 别 ) P ( 特 征 ∣ 类 别 ) P ( 特 征 ) P(类别|特征)=P(类别)\frac{P(特征|类别)}{P(特征)} P(类别∣特征)=P(类别)P(特征)P(特征∣类别)
P ( A i ∣ B ) = P ( A i ) P ( B ∣ A i ) ∑ i = 1 n P ( A i ) P ( B ∣ A i ) P(A_i | B) =P(A_i) \frac{ P(B|A_i)} {\sum_{i=1}^{n}{P(A_i)P(B|A_i)}} P(Ai∣B)=P(Ai)∑i=1nP(Ai)P(B∣Ai)P(B∣Ai)
P(A)称为“先验概率”(Prior probability),即在B事件发生之前,我们对A事件概率的一个判断。P(A|B)称为“后验概率”(Posterior probability),即在B事件发生之后,我们对A事件概率的重新评估。P(B|A)/P(B)称为“可能性函数”(Likely hood),这是一个调整因子,使得预估概率更接近真是概率。 如果“可能性函数”>1,意味着“先验概率”被增强,事件A的发生的可能性变大;如果“可能性函数”=1,意味着B事件无助于判断事件A的可能性;如果“可能性函数”<1,意味着“先验概率”被削弱,事件A的发生的可能性变小;
所以条件概率可以理解为:后验概率=先验概率*调整因子
2.3 朴素贝叶斯的python实现
过滤广告、垃圾邮件
1、导入所需包
from numpy import *
from functools import reduce
2、加载数据集合及其对应的分类,从训练数据集中提取出属性矩阵和分类数据
# 广告、垃圾标识
adClass = 1
def loadDataSet():
wordsList = [['周六', '公司', '一起', '聚餐', '时间'],
['优惠', '返利', '打折', '优惠', '金融', '理财'],
['喜欢', '机器学习', '一起', '研究', '欢迎', '贝叶斯', '算法', '公式'],
['公司', '发票', '税点', '优惠', '增值税', '打折'],
['北京', '今天', '雾霾', '不宜', '外出', '时间', '在家', '讨论', '学习'],
['招聘', '兼职', '日薪', '保险', '返利']]
# 1 是, 0 否
classVec = [0, 1, 0, 1, 0, 1]
return wordsList, classVec
3、生成包含所有单词的list( 此处生成的单词向量是不重复的)
从第一个和第二个集合开始进行并集操作,最后返回一个不重复的并集
def doc2VecList(docList):
a = list(reduce(lambda x, y: set(x) | set(y), docList))
return a
allWordsVec = doc2VecList(docList)
print(allWordsVec)
python中的 & | 是位运算符 and or 是逻辑运算符 当and的运算结果为true时候返回的并不是true而是运算结果最后一位变量的值当and返回的结果是false时候,如果A AND B 返回的是第一个false的值,如果a为false 则返回a,如果a不是false,那么返回b如果a or b 为true时候,返回的是第一个真的变量的值,如果a,b都为真时候那么返回a 如果a为假b为真那么返回ba & b a和b为两个set,返回结果取a和b的交集 a|b a和b为两个set,返回结果为两个集合的不重复并集
4、 把单词转化为词向量,计算数据集中每一行每个单词出现的次数,如果此单词在数组中,数组的项值置1
```
def words2Vec(vecList, inputWords):
# 转化成以一维数组
resultVec = [0] * len(vecList)
for word in inputWords:
if word in vecList:
resultVec[vecList.index(word)] += 1 # 在单词出现的位置上的计数加1
else:
print('没有发现此单词')
return array(resultVec)
```
构建词向量矩阵,计算docList数据集中每一行每个单词出现的次数,其中返回的trainMat是一个数组的数组
```
trainMat = list(map(lambda x: words2Vec(allWordsVec, x), docList))
trainMat
```
<img src="" width="400">
5、计算,生成每个词对于类别上的概率(其中概率是以ln进行计算的)
p0V:每个单词在非分类出现的概率,p1V:每个单词在是分类出现的概率pClass1为类别中是1的概率
def trainNB(trainMatrix, trainClass):
numTrainClass = len(trainClass) # 类别行数
numWords = len(trainMatrix[0]) # 列数
# 全部都初始化为1, 防止出现概率为0的情况出现,影响计算,因为在数量很大的情况下,在分子和分母同时+1的情况不会影响主要的数据
p0Num = ones(numWords)
p1Num = ones(numWords)
p0Words = 2.0 # 相应的单词初始化为2为了分子分母同时都加上某个数λ
p1Words = 2.0
统计每个分类的词的总数,训练数据集的行数作为遍历的条件,从1开始 如果当前类别为1,那么p1Num会加上当前单词矩阵行数据,依次遍历 如果当前类别为0,那么p0Num会加上当前单词矩阵行数据,依次遍历 同时统计当前类别下单词的个数和p1Words和p0Words
for i in range(numTrainClass):
if trainClass[i] == 1:
# 数组在对应的位置上相加
p1Num += trainMatrix[i]
p1Words += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Words += sum(trainMatrix[i])
* 计算每种类型里面, 每个单词出现的概率
* 朴素贝叶斯分类中,y=x是单调递增函数,y=ln(x)也是单调的递增的
* 如果x1>x2 那么ln(x1)>ln(x2)
* 在计算过程中,由于概率的值较小,所以我们就取对数进行比较,根据对数的特性
* ln(MN) = ln(M)+ln(N)
* ln(M/N) = ln(M)-ln(N)
* ln(M**n)= nln(M)
* 注:其中ln可替换为log的任意对数底
```
p0Vec = log(p0Num / p0Words)
p1Vec = log(p1Num / p1Words)
# 计算在类别中1出现的概率,0出现的概率可通过1-p得到
pClass1 = sum(trainClass) / float(numTrainClass)
return p0Vec, p1Vec, pClass1
```
训练计算每个词在分类上的概率
p0V, p1V, pClass1 = trainNB(trainMat, classVec)
pClass1
原文地址1:https://blog.csdn.net/b_z_K____0012/article/details/109613237
参考资料:python中用turtle画一个圆形 https://blog.csdn.net/SXIAOYAN_/article/details/140061099