一、理论部分

这部分涉及的理论知识比较多。深入浅出,公式就不多讲了。

具体可以参考 概率论与数理统计教材、周志华的西瓜书、李航的统计学习方法。

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、选取特征。关于如何选取特征,这里不进行深度讨论。我们只针对例题,我们选取年龄大,工龄长,学历高是否合理。我们知道贝叶斯假设是各个特征独立,那么我们选取特征的时候尽量不要有冗余,特征之间相关性不要太大。

机器学习贝叶斯分类(理论及代码实现)相关推荐

  1. 视频教程-机器学习之聚类、主成分分析理论与代码实践-机器学习

    机器学习之聚类.主成分分析理论与代码实践 干过开发,做到资深Java软件开发工程师,后做过培训,总共培训近千人.目前在高校工作,博士学位.主要研究领域为机器学习与深度学习. 纪佳琪 ¥68.00 立即 ...

  2. 白话机器学习算法理论+实战之K近邻算法

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...

  3. 【机器学习基本理论】详解最大似然估计(MLE)、最大后验概率估计(MAP),以及贝叶斯公式的理解

    [机器学习基本理论]详解最大似然估计(MLE).最大后验概率估计(MAP),以及贝叶斯公式的理解 https://mp.weixin.qq.com/s/6H0gmMWvTExySMraroLVlQ 最 ...

  4. 机器学习从理论到工程的第二步-开发环境与工具篇

    在<第一步-编程语言篇>中,小夕为大家较为详细的介绍了做机器学习(及其相关应用方向)的编程语言的选择问题,这一篇便是小夕为大家推荐的各个编程语言的开发环境/工具. 习惯性扫盲开篇.鉴于可能 ...

  5. apriori算法代码_资源 | 《机器学习实战》及代码(基于Python3)

    〇.<机器学习实战> 今天推荐给大家的是<机器学习实战>这本书. 机器学习作为人工智能研究领域中一个极其重要的研究方向(一文章看懂人工智能.机器学习和深度学习),在当下极其热门 ...

  6. python常用代码入门-入门十大Python机器学习算法(附代码)

    入门十大Python机器学习算法(附代码) 今天,给大家推荐最常用的10种机器学习算法,它们几乎可以用在所有的数据问题上: 1.线性回归 线性回归通常用于根据连续变量估计实际数值(房价.呼叫次数.总销 ...

  7. 白话机器学习算法理论+实战之PCA降维

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...

  8. 拥抱人工智能--机器学习(附python代码)

    机器学习简述 加入了代码,如果不想看代码请直接跳过,这不会产生任何影响 文章来自于云栖社区,修改及补充了一些内容,增添了代码 文章目录 机器学习简述 机器学习算法:是使计算机具有智能的关键 下面我们将 ...

  9. 白话机器学习算法理论+实战之支持向量机(SVM)

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...

  10. 白话机器学习算法理论+实战之EM聚类

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...

最新文章

  1. 十三、流程控制之if语句
  2. 神经网络的梯度消失和过拟合产生原因及其解决方案
  3. 理解 Delphi 的类(十) - 深入方法[4] - 共同类型的参数的简化写法
  4. javascript canvas九宫格小程序
  5. c语言课程设计加密程序,C语言课程设计文件加密解密.doc
  6. c语言语法格式规范(1)常量的非法与合法
  7. Spark之RDD理论篇
  8. 158.用 Read4 读取 N 个字符read characters from file multiple calls
  9. mysql 存储过程 调度_mysql 存储过程和事件调度
  10. python写鼠标宏_最全Pycharm教程(24)——Pycharm编辑器功能之宏定义
  11. CTA策略01_dualThrust
  12. 使用JavaScript开发IE浏览器本地插件实例
  13. 面试部分梳理 - 计算机网络
  14. GT21L16S2W特殊字符计算地址
  15. 简明Python教程笔记(一)
  16. 根据class属性获取元素
  17. 学Python真的没用吗?Python到底可以干什么?
  18. 任正非十大经典比喻:善形象阐释管理理念
  19. 【光伏】基于战争策略算法WSO优化光伏模型附matlab代码
  20. FMEA软件——聊聊FMEA那些事

热门文章

  1. Asp.Net Core 中_ViewStart.cshtml 及_ViewImports.cshtml 的作用
  2. 图解LeetCode——768. 最多能完成排序的块 II(难度:困难)
  3. android-sdk下载安装
  4. 2019年中国研究生数学建模竞赛D题 汽车行驶工况构建【信息交流】
  5. 常见的一些计算机安全类词汇
  6. MBR与GPT分区的区别及使用注意事项(转载)
  7. 系统及服务器巡检流程图,业务巡检系统的整体设计和数据流程
  8. 一起来学ES —— Bulk剖析
  9. Linux搜索文件和文件夹的方法
  10. 利用opencv给视频截图