机器学习贝叶斯分类(理论及代码实现)
一、理论部分
这部分涉及的理论知识比较多。深入浅出,公式就不多讲了。
具体可以参考 概率论与数理统计教材、周志华的西瓜书、李航的统计学习方法。
1.1、极大似然估计。
直接来例子
例:假设袋子里有n个球,n无限大。只有黑球和白球,每次有放回的 从袋子随机拿100次球。80次白球,20次黑球。问:袋子里白球概率为 什么值的时候 概率最大?
解析:假设袋子里白球概率为p。我们现在知道的是我们拿100次的结果。相当于用这100次估算n个球里白球的概率。更为经典的是硬币的正反面问题,当我们投足够多的时候,就越接近真实概率值。这个思想对我们来讲非常关键。
解:设袋子里白球概率为p
由题意知,我们每次取都是有放回的,每次抓取球这个事件属于独立且同分布则
P(80白20黑) = P(白)**80+P(黑)**20 = p**80+(1-p)**20
求p值使得P(80白20黑) 最大。求导,导数取0就可以计算出来。指数不方便求导,就先转log再求导取0也是一样的(x,log(x)同增同减)。计算也比较简单。问题转化成对ln(p)求导取0得:
80/p+(-20/(1-p)) = 0
求得 p=0.8。
用已知的数据去预测未知的数据(先验概率分布与后验概率分布)。
1.2、贝叶斯分类。
让我继续想个例子。。。.。。。
举个简单的栗子:判断员工是否是公司高层?
随机抽取10人。现有特征(a1,a2,a3,b) 。a1:年龄是否大, a2:工龄是否长,a3:学历是否高。b:是否高层(0代表否,1代表是)
(0,0,0,0)
(0,0,0,0)
(0,0,0,0)
(0,0,1,0)
(0,1,1,0)
(1,0,0,0)
(0,1,0,0)
(0,0,1,1)
(0,1,1,1)
(1,1,1,1)
【数据自己想的,实际数据要根据实际获取】
现在随机抽一个人,他年龄大,工龄长,学历高。预测他是否属于高层?
解:计算概率
P(是高层|所有数据集) = 3/10 P(不是高层|所有数据集)= 7/10
P(年龄大|是高层)= 1/3 P(工龄长|是高层)= 2/3 P(学历高|是高层) = 1/1
P(年龄大|不是高层)= 1/7 P(工龄长|不是高层)= 2/7 P(学历高|不是高层) = 2/7
假设他是属于高层:
P1 = P(是高层|所有数据集) * P(年龄大|是高层)* P(工龄长|是高层)* P(学历高|是高层)
= 3/10 * 1/3 * 2/3 * 1/1 = 6/90 = 0.0667
假设他不属于高层:
P0 = P(是高层|所有数据集)*P(年龄大|是高层)* P(工龄长|是高层)*P(学历高|是高层)
= 7/10 * 1/7 * 2/7 * 2/7 = 28/3430 = 0.00816
由 P1 > P0:
我们预测他属于高层
我们用10组数据(训练集)的分布,估计出全公司的人员分布。利用分布各个特征互相独立。计算出概率,哪种概率大 我们预测新的样本属于哪一类。下面用代码来实现下。
二、代码实现
2.1、代码解释
先来看下写的完整代码。
import numpy as npclass BayesModel():def __init__(self):super(BayesModel,self).__init__()self.ng_result = [] # 存放ng的概率self.ok_result = [] # 存放ok的概率def probability(self,a,b):p_a = a/(a+b)p_b = 1-p_areturn p_a,p_bdef fit(self,x,y):columns = x.shape[1] # 为了获取特征的数量,我们上述例子是3个特征 (年龄,工龄,学历)data = np.c_[x,y] # 连接到同一个numpy,方便操作ng_data = data[(data[:,-1] == 0)] # 把结果ng的数据取出来ok_data = data[(data[:,-1] == 1)] # 把结果ok的数据取出来ng_len,ok_len = ng_data.shape[0],ok_data.shape[0]self.ng,self.ok = self.probability(ng_len,ok_len)for i in range(columns):ng_len_ng = ng_data[(ng_data[:,i] == 0)].shape[0]ng_len_ok = ng_len - ng_len_ngok_len_ng = ok_data[(ok_data[:,i] == 0)].shape[0]ok_len_ok = ok_len - ok_len_ngself.ng_result.append(self.probability(ng_len_ng,ng_len_ok))self.ok_result.append(self.probability(ok_len_ng,ok_len_ok))def predict(self,data_data):list_result = [] # 存放预测的结果for datas in data_data:ng,ok = self.ng,self.okfor index,data in enumerate(datas):if data == 0:ng = ng*self.ng_result[index][0]ok = ok*self.ok_result[index][0]else:ng = ng*self.ng_result[index][1]ok = ok*self.ok_result[index][1]if ng>ok:list_result.append(0)else:list_result.append(1)return list_result if __name__ == '__main__':x1 = np.array([0,0,0,0,0,1,0,0,0,1]).reshape(-1,1)x2 = np.array([0,0,0,0,1,0,1,0,1,1]).reshape(-1,1)x3 = np.array([0,0,0,1,1,0,0,1,1,1]).reshape(-1,1)x = np.c_[x1,x2,x3]y = np.array([0,0,0,0,0,0,0,1,1,1]).reshape(-1,1)print(x)print(y)bayes = BayesModel()bayes.fit(x,y)predict = bayes.predict([[1,1,1],[0,1,1],[1,1,0]])print(bayes.predict(x)) # 预测下我们的训练集
定义一个函数,因为我们是二分类结果是yes/no,特征也只有yes/no。所以我们定义个求概率的函数。这个比较简单。输入两个值如4,1 返回两个概率值0.8,0.2。
def probability(self,a,b):p_a = a/(a+b)p_b = 1-p_areturn p_a,p_b
构建模型,把概率数据保存到对应的列表里。
1、先算出结果为ng与ok的数据概率。并把这两部分数据提取出来,ng_data,ok_data
2、对ng_data,ok_data计算出各个特征的ng/ok的概率,并存入相应的列表里。
def fit(self,x,y):columns = x.shape[1] # 为了获取特征的数量,我们上述例子是3个特征 (年龄,工龄,学历)data = np.c_[x,y] # 连接到同一个numpy,方便操作ng_data = data[(data[:,-1] == 0)] # 把结果ng的数据取出来ok_data = data[(data[:,-1] == 1)] # 把结果ok的数据取出来ng_len,ok_len = ng_data.shape[0],ok_data.shape[0]self.ng,self.ok = self.probability(ng_len,ok_len)for i in range(columns):ng_len_ng = ng_data[(ng_data[:,i] == 0)].shape[0]ng_len_ok = ng_len - ng_len_ngok_len_ng = ok_data[(ok_data[:,i] == 0)].shape[0]ok_len_ok = ok_len - ok_len_ngself.ng_result.append(self.probability(ng_len_ng,ng_len_ok))self.ok_result.append(self.probability(ok_len_ng,ok_len_ok))
这段是预测,由函数fit已经构建完模型,数据存到列表。现在想预测新的样本集。
先看传入进来的data_data是几组数据,然后每组数据进行枚举,概率相乘,最后判断ng与ok那种概率大。最后返回出整个结果。思路和整个代码都比较简单。
def predict(self,data_data):list_result = [] # 存放预测的结果for datas in data_data:ng,ok = self.ng,self.okfor index,data in enumerate(datas):if data == 0:ng = ng*self.ng_result[index][0]ok = ok*self.ok_result[index][0]else:ng = ng*self.ng_result[index][1]ok = ok*self.ok_result[index][1]if ng>ok:list_result.append(0)else:list_result.append(1)return list_result
数据集用的是上述判断是否为高层的数据。
if __name__ == '__main__':x1 = np.array([0,0,0,0,0,1,0,0,0,1]).reshape(-1,1)x2 = np.array([0,0,0,0,1,0,1,0,1,1]).reshape(-1,1)x3 = np.array([0,0,0,1,1,0,0,1,1,1]).reshape(-1,1)x = np.c_[x1,x2,x3]y = np.array([0,0,0,0,0,0,0,1,1,1]).reshape(-1,1)print(x)print(y)bayes = BayesModel()bayes.fit(x,y)predict = bayes.predict([[1,1,1],[0,1,1],[1,1,0]])
2.2、完整代码
代码可以直接运行的
import numpy as npclass BayesModel():def __init__(self):super(BayesModel,self).__init__()self.ng_result = [] # 存放ng的概率self.ok_result = [] # 存放ok的概率def probability(self,a,b):p_a = a/(a+b)p_b = 1-p_areturn p_a,p_bdef fit(self,x,y):columns = x.shape[1] # 为了获取特征的数量,我们上述例子是3个特征 (年龄,工龄,学历)data = np.c_[x,y] # 连接到同一个numpy,方便操作ng_data = data[(data[:,-1] == 0)] # 把结果ng的数据取出来ok_data = data[(data[:,-1] == 1)] # 把结果ok的数据取出来ng_len,ok_len = ng_data.shape[0],ok_data.shape[0]self.ng,self.ok = self.probability(ng_len,ok_len)for i in range(columns):ng_len_ng = ng_data[(ng_data[:,i] == 0)].shape[0]ng_len_ok = ng_len - ng_len_ngok_len_ng = ok_data[(ok_data[:,i] == 0)].shape[0]ok_len_ok = ok_len - ok_len_ngself.ng_result.append(self.probability(ng_len_ng,ng_len_ok))self.ok_result.append(self.probability(ok_len_ng,ok_len_ok))def predict(self,data_data):list_result = [] # 存放预测的结果for datas in data_data:ng,ok = self.ng,self.okfor index,data in enumerate(datas):if data == 0:ng = ng*self.ng_result[index][0]ok = ok*self.ok_result[index][0]else:ng = ng*self.ng_result[index][1]ok = ok*self.ok_result[index][1]if ng>ok:list_result.append(0)else:list_result.append(1)return list_result if __name__ == '__main__':x1 = np.array([0,0,0,0,0,1,0,0,0,1]).reshape(-1,1)x2 = np.array([0,0,0,0,1,0,1,0,1,1]).reshape(-1,1)x3 = np.array([0,0,0,1,1,0,0,1,1,1]).reshape(-1,1)x = np.c_[x1,x2,x3]y = np.array([0,0,0,0,0,0,0,1,1,1]).reshape(-1,1)print(x)print(y)bayes = BayesModel()bayes.fit(x,y)predict = bayes.predict([[1,1,1],[0,1,1],[1,1,0]])print(bayes.predict(x)) # 预测下我们的训练集看下结果
2.3、改进思路
1、如何实现多分类。
这部分只有二分类,要想多分类就不能只是0与1这么简单。模型要兼容多分类,可以对结果集利用np.unique(),然后取出值进行分类。特征单个种类分类多,也可以使用这种方法。如果比如身高这些特征符合正态分布,需要用正态分布概率进行计算。
2、可以发现,如果通过此数据集,P(学历不高|是高层)= 0,因为我们是连乘计算概率,所以会出现一种情况是,只要他学历不高,那么他是高层概率为0。按照常理讲这是不合理的。解决方式:增加数据训练集;拉普拉斯平滑处理,调整probability 函数计算概率的方式 ,分子加一,分母加特征种数。这部分也比较简单,具体可以参考文章开头说的。
3、如何提升预测准度。
3.1、提高训练集数据的质量。基本所有机器学习对训练集的数据要求都很高,贝叶斯更是如此,如果你选取的数据质量不高,没有代表性,抽选随机性不高。对模型影响很大。
3.2、增加训练集的数量。这个非常好理解,我们投硬币,投的次数越多,正面概率越解决1/2。更接近真实值。
3.3、选取特征。关于如何选取特征,这里不进行深度讨论。我们只针对例题,我们选取年龄大,工龄长,学历高是否合理。我们知道贝叶斯假设是各个特征独立,那么我们选取特征的时候尽量不要有冗余,特征之间相关性不要太大。
机器学习贝叶斯分类(理论及代码实现)相关推荐
- 视频教程-机器学习之聚类、主成分分析理论与代码实践-机器学习
机器学习之聚类.主成分分析理论与代码实践 干过开发,做到资深Java软件开发工程师,后做过培训,总共培训近千人.目前在高校工作,博士学位.主要研究领域为机器学习与深度学习. 纪佳琪 ¥68.00 立即 ...
- 白话机器学习算法理论+实战之K近邻算法
1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...
- 【机器学习基本理论】详解最大似然估计(MLE)、最大后验概率估计(MAP),以及贝叶斯公式的理解
[机器学习基本理论]详解最大似然估计(MLE).最大后验概率估计(MAP),以及贝叶斯公式的理解 https://mp.weixin.qq.com/s/6H0gmMWvTExySMraroLVlQ 最 ...
- 机器学习从理论到工程的第二步-开发环境与工具篇
在<第一步-编程语言篇>中,小夕为大家较为详细的介绍了做机器学习(及其相关应用方向)的编程语言的选择问题,这一篇便是小夕为大家推荐的各个编程语言的开发环境/工具. 习惯性扫盲开篇.鉴于可能 ...
- apriori算法代码_资源 | 《机器学习实战》及代码(基于Python3)
〇.<机器学习实战> 今天推荐给大家的是<机器学习实战>这本书. 机器学习作为人工智能研究领域中一个极其重要的研究方向(一文章看懂人工智能.机器学习和深度学习),在当下极其热门 ...
- python常用代码入门-入门十大Python机器学习算法(附代码)
入门十大Python机器学习算法(附代码) 今天,给大家推荐最常用的10种机器学习算法,它们几乎可以用在所有的数据问题上: 1.线性回归 线性回归通常用于根据连续变量估计实际数值(房价.呼叫次数.总销 ...
- 白话机器学习算法理论+实战之PCA降维
1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...
- 拥抱人工智能--机器学习(附python代码)
机器学习简述 加入了代码,如果不想看代码请直接跳过,这不会产生任何影响 文章来自于云栖社区,修改及补充了一些内容,增添了代码 文章目录 机器学习简述 机器学习算法:是使计算机具有智能的关键 下面我们将 ...
- 白话机器学习算法理论+实战之支持向量机(SVM)
1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...
- 白话机器学习算法理论+实战之EM聚类
1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...
最新文章
- 十三、流程控制之if语句
- 神经网络的梯度消失和过拟合产生原因及其解决方案
- 理解 Delphi 的类(十) - 深入方法[4] - 共同类型的参数的简化写法
- javascript canvas九宫格小程序
- c语言课程设计加密程序,C语言课程设计文件加密解密.doc
- c语言语法格式规范(1)常量的非法与合法
- Spark之RDD理论篇
- 158.用 Read4 读取 N 个字符read characters from file multiple calls
- mysql 存储过程 调度_mysql 存储过程和事件调度
- python写鼠标宏_最全Pycharm教程(24)——Pycharm编辑器功能之宏定义
- CTA策略01_dualThrust
- 使用JavaScript开发IE浏览器本地插件实例
- 面试部分梳理 - 计算机网络
- GT21L16S2W特殊字符计算地址
- 简明Python教程笔记(一)
- 根据class属性获取元素
- 学Python真的没用吗?Python到底可以干什么?
- 任正非十大经典比喻:善形象阐释管理理念
- 【光伏】基于战争策略算法WSO优化光伏模型附matlab代码
- FMEA软件——聊聊FMEA那些事
热门文章
- Asp.Net Core 中_ViewStart.cshtml 及_ViewImports.cshtml 的作用
- 图解LeetCode——768. 最多能完成排序的块 II(难度:困难)
- android-sdk下载安装
- 2019年中国研究生数学建模竞赛D题 汽车行驶工况构建【信息交流】
- 常见的一些计算机安全类词汇
- MBR与GPT分区的区别及使用注意事项(转载)
- 系统及服务器巡检流程图,业务巡检系统的整体设计和数据流程
- 一起来学ES —— Bulk剖析
- Linux搜索文件和文件夹的方法
- 利用opencv给视频截图