作者:hhh5460

大抵分成两类

一、离散的、标签化的数据

原文没有使用pandas,我使用pandas重新实现了朴素贝叶斯算法,看起来非常简洁、清爽。

  1. import pandas as pd
  2. '''
  3. 导入数据集
  4. {a1 = 0, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
  5. {a1 = 0, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
  6. {a1 = 0, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
  7. {a1 = 1, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
  8. {a1 = 1, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
  9. {a1 = 1, a2 = 0, C = 0} {a1 = 1, a2 = 0, C = 1}
  10. {a1 = 1, a2 = 1, C = 0} {a1 = 1, a2 = 0, C = 1}
  11. {a1 = 1, a2 = 1, C = 0} {a1 = 1, a2 = 1, C = 1}
  12. {a1 = 1, a2 = 1, C = 0} {a1 = 1, a2 = 1, C = 1}
  13. {a1 = 1, a2 = 1, C = 0} {a1 = 1, a2 = 1, C = 1}
  14. '''
  15. #导入数据集
  16. data = [[0, 0, 0],
  17. [0, 0, 0],
  18. [0, 0, 0],
  19. [1, 0, 0],
  20. [1, 0, 0],
  21. [1, 0, 0],
  22. [1, 1, 0],
  23. [1, 1, 0],
  24. [1, 1, 0],
  25. [1, 1, 0],
  26. [0, 0, 1],
  27. [0, 0, 1],
  28. [0, 0, 1],
  29. [0, 0, 1],
  30. [0, 0, 1],
  31. [1, 0, 1],
  32. [1, 0, 1],
  33. [1, 1, 1],
  34. [1, 1, 1],
  35. [1, 1, 1]]
  36. df = pd.DataFrame(data, columns=['a1', 'a2', 'c'])
  37. '''
  38. #计算类别的先验概率
  39. #P(C = 0) = 0.5
  40. #P(C = 1) = 0.5
  41. '''
  42. #计算类别的先验概率
  43. pc = df['c'].value_counts()/df['c'].size
  44. '''
  45. 计算每个特征属性条件概率:
  46. P(a1 = 0 | C = 0) = 0.3
  47. P(a1 = 1 | C = 0) = 0.7
  48. P(a2 = 0 | C = 0) = 0.4
  49. P(a2 = 1 | C = 0) = 0.6
  50. P(a1 = 0 | C = 1) = 0.5
  51. P(a1 = 1 | C = 1) = 0.5
  52. P(a2 = 0 | C = 1) = 0.7
  53. P(a2 = 1 | C = 1) = 0.3
  54. '''
  55. # 计算每个特征属性条件概率:
  56. pa1 = pd.crosstab(df['c'], df['a1'], margins=True).apply(lambda x:x/x[-1], axis=1)
  57. pa2 = pd.crosstab(df['c'], df['a2'], margins=True).apply(lambda x:x/x[-1], axis=1)
  58. '''
  59. 测试样本:
  60. x = { a1 = 1, a2 = 1}
  61. p(x | C = 0) = p(a1 = 1 | C = 0) * p( a2 = 1 | C = 0) = 0.3 * 0.6 = 0.18
  62. p(x | C = 1) = p(a1 = 1 | C = 1) * p (a2 = 1 | C = 1) = 0.5 * 0.3 = 0.15
  63. '''
  64. # 给出测试样本:
  65. x = pd.Series([1,1], index=['a1', 'a2'])
  66. px = pa1.ix[:,x[0]].mul(pa2.ix[:,x[1]])[:-1]
  67. '''
  68. 计算P(C | x):
  69. P(C = 0) * p(x | C = 1) = 0.5 * 0.18 = 0.09
  70. P(C = 1) * p(x | C = 1) = 0.5 * 0.15 = 0.075
  71. 所以认为测试样本属于类型C1
  72. '''
  73. # 计算P(C | x)
  74. res = pc.mul(px).argmax()
  75. print(res)

同样的方法,7行代码解决这里的问题:

  1. import pandas as pd
  2. data = [['打喷嚏','护士','感冒'],
  3. ['打喷嚏','农夫','过敏'],
  4. ['头痛','建筑工人','脑震荡'],
  5. ['头痛','建筑工人','感冒'],
  6. ['打喷嚏','教师','感冒'],
  7. ['头痛','教师','脑震荡']]
  8. df = pd.DataFrame(data, columns=['症状','职业','疾病'])
  9. #计算类别的先验概率
  10. pr = df['疾病'].value_counts()/df['疾病'].size
  11. # 计算每个特征属性条件概率:
  12. pzz = pd.crosstab(df['疾病'], df['症状'], margins=True).apply(lambda x:x/x[-1], axis=1)
  13. pzy = pd.crosstab(df['疾病'], df['职业'], margins=True).apply(lambda x:x/x[-1], axis=1)
  14. # 给出测试样本:
  15. x = pd.Series(['打喷嚏','建筑工人'], index=['症状','职业'])
  16. px = pzz.ix[:,x[0]].mul(pzy.ix[:,x[1]])[:-1]
  17. # 计算P(C | x)
  18. res = pr.mul(px).argmax()
  19. print(res)

二、连续的、非标签化的数据

1.连续变量,样本足够大。使用区间,标签化

这里的第二个例子:

**

  1. # 检测SNS社区中不真实账号
  2. # 运维人员人工检测过的1万个账号作为训练样本
  3. # 原始数据格式:
  4. # ['日志数量','好友数量','注册天数','是否使用真实头像','账号类别']
  5. '''可惜,没有真实数据!!!!'''
  6. data = [
  7. [3,0,120,1,1],
  8. [3,0,120,1,1],
  9. [3,0,120,1,1],
  10. [3,0,120,1,1],
  11. [3,0,120,1,1],
  12. [3,0,120,1,1],
  13. [3,0,120,1,1],
  14. #...
  15. [3,0,120,1,1]]
  16. df = pd.DataFrame(data, columns=['日志数量','好友数量','注册天数','是否使用真实头像','账号类别'])
  17. # 计算训练样本中每个类别的频率(当做 类别的先验概率)
  18. '''
  19. P(C=0) = 8900/10000 = 0.89
  20. P(C=1) = 1100/10000 = 0.11
  21. '''
  22. pr = df['账号类别'].value_counts()/df['账号类别'].size
  23. #================================================================
  24. #----------------------------------------------------------------
  25. # 构建两个特征
  26. # ['日志数量/注册天数','好友数量/注册天数']
  27. df['日志数量/注册天数'] = df['日志数量'].div(df['注册天数'])
  28. df['好友数量/注册天数'] = df['好友数量'].div(df['注册天数'])
  29. # 把'日志数量/注册天数'分解成[0, 0.05]、(0.05, 0.2)、[0.2, +∞)三个区间
  30. # 把'好友数量/注册天数'分解成[0, 0.1]、(0.1, 0.8)、[0.8, +∞)三个区间
  31. # 打标签函数(根据 x 值所在的区间)
  32. def depart(x, low, high):
  33. if x <= low:
  34. return 0
  35. elif x >= high:
  36. return 2
  37. else:
  38. return 1
  39. # 打标签
  40. df['特征1'] = df['日志数量/注册天数'].apply(depart, args=(0.05, 0.2))
  41. df['特征2'] = df['好友数量/注册天数'].apply(depart, args=(0.1, 0.8))
  42. df['特征3'] = df['是否使用真实头像']
  43. #----------------------------------------------------------------
  44. #================================================================
  45. # 计算每个特征属性条件概率:
  46. ptz1 = pd.crosstab(df['账号类别'], df['特征1'], margins=True).apply(lambda x:x/x[-1], axis=1)
  47. ptz2 = pd.crosstab(df['账号类别'], df['特征2'], margins=True).apply(lambda x:x/x[-1], axis=1)
  48. ptz3 = pd.crosstab(df['账号类别'], df['特征3'], margins=True).apply(lambda x:x/x[-1], axis=1)
  49. # 给出测试样本:
  50. x_ = pd.Series([0.1, 0.2, 0], index=['日志数量/注册天数', '好友数量/注册天数', '是否使用真实头像'])
  51. #================================================================
  52. #----------------------------------------------------------------
  53. # 打标签
  54. x = pd.Series([depart(x_[0], 0.05, 0.2), depart(x_[1], 0.1, 0.8), x_[2]], index=['特征1','特征2','特征3'])
  55. #----------------------------------------------------------------
  56. #================================================================
  57. px = ptz1.ix[:,x[0]].mul(ptz2.ix[:,x[1]]).mul(ptz3.ix[:,x[2]])[:-1]
  58. # 计算P(C | x)
  59. res = pr.mul(px).argmax()
  60. print(res)

2.连续变量,样本太小,无法划分区间。

假设符合正态分布,先求出按类的均值,方差,再代入密度函数

这里的第三个例子:

**

  1. import pandas as pd
  2. # 关于处理连续变量的另一种方法
  3. # 下面是一组人类身体特征的统计资料
  4. data = [['男', 6, 180, 12],
  5. ['男', 5.92, 190, 11],
  6. ['男', 5.58, 170, 12],
  7. ['男', 5.92, 165, 10],
  8. ['女', 5, 100, 6],
  9. ['女', 5.5, 150, 8],
  10. ['女', 5.42, 130, 7],
  11. ['女', 5.75, 150, 9]]
  12. df = pd.DataFrame(data, columns=['性别','身高(英尺)','体重(磅)','脚掌(英寸)'])
  13. # 已知某人身高6英尺、体重130磅,脚掌8英寸,请问该人是男是女?
  14. x = pd.Series([6,130,8], index=['身高(英尺)','体重(磅)','脚掌(英寸)'])
  15. # 这里的困难在于,
  16. # 1.连续变量
  17. # 2.样本太少(无法分成区间)
  18. # 解决:
  19. # 假设男性和女性的身高、体重、脚掌都是正态分布,
  20. # 通过样本计算出均值和方差,也就是得到正态分布的密度函数。
  21. # 有了密度函数,就可以把值代入,算出某一点的密度函数的值。
  22. mean_male = df[df['性别']=='男'].mean()
  23. var_male = df[df['性别']=='男'].var()
  24. mean_formale = df[df['性别']=='女'].mean()
  25. var_formale = df[df['性别']=='女'].var()
  26. df2 = pd.concat((x, mean_male, var_male, mean_formale, var_formale), axis=1, keys=['x', 'mean_male', 'var_male', 'mean_formale', 'var_formale'])
  27. # 正态分布密度函数:
  28. # f(x|male) = exp(-(x-mean)**2/(2*var))/sqrt(2*pi*var)
  29. from math import pi
  30. def f(x, mean, var):
  31. return exp(-(x-mean)**2/(2*var))/sqrt(2*pi*var) # 密度函数
  32. # 求对应的密度函数值
  33. df2['px_male'] = df2['x', 'mean_male', 'var_male'].apply(lambda x:f(x[0],x[1],x[2])) ###################报错!容后再改!!
  34. df2['px_formale'] = df2['x', 'mean_formale', 'var_formale'].apply(lambda x:f(x[0],x[1],x[2]))
  35. # 类别的先验概率
  36. pr = df['性别'].value_counts()/df['性别'].size
  37. # 预测结果
  38. res = pd.Series([df2['p_male'].cumprod()[-1]*pr['男'], df2['p_formale'].cumprod()[-1]]*pr['女'], index=['男','女']).argmax()
  39. print(res)

使用pandas,7行代码实现朴素贝叶斯的更多相关文章

  1. 朴素贝叶斯python代码实现(西瓜书)

    朴素贝叶斯python代码实现(西瓜书) 摘要: 朴素贝叶斯也是机器学习中一种非常常见的分类方法,对于二分类问题,并且数据集特征为离散型属性的时候, 使用起来非常的方便.原理简单,训练效率高,拟合效果 ...

  2. 利用朴素贝叶斯算法进行分类-Java代码实现

    http://www.crocro.cn/post/286.html 利用朴素贝叶斯算法进行分类-Java代码实现  鳄鱼  3个月前 (12-14)  分类:机器学习  阅读(44)  评论(0) ...

  3. 朴素贝叶斯算法简介及python代码实现分析

    概念: 贝叶斯定理:贝叶斯理论是以18世纪的一位神学家托马斯.贝叶斯(Thomas Bayes)命名.通常,事件A在事件B(发生)的条件下的概率,与事件B在事件A(发生)的条件下的概率是不一样的:然而 ...

  4. 朴素贝叶斯算法源码分析及代码实战【python sklearn/spark ML】

    一.简介 贝叶斯定理是关于随机事件A和事件B的条件概率的一个定理.通常在事件A发生的前提下事件B发生的概率,与在事件B发生的前提下事件A发生的概率是不一致的.然而,这两者之间有确定的关系,贝叶斯定理就 ...

  5. 【sklearn朴素贝叶斯算法】高斯分布/多项式/伯努利贝叶斯算法以及代码实例

    朴素贝叶斯 朴素贝叶斯方法是一组基于贝叶斯定理的监督学习算法,其"朴素"假设是:给定类别变量的每一对特征之间条件独立.贝叶斯定理描述了如下关系: 给定类别变量\(y\)以及属性值向 ...

  6. 机器学习---用python实现朴素贝叶斯算法(Machine Learning Naive Bayes Algorithm Application)

    在<机器学习---朴素贝叶斯分类器(Machine Learning Naive Bayes Classifier)>一文中,我们介绍了朴素贝叶斯分类器的原理.现在,让我们来实践一下. 在 ...

  7. 朴素贝叶斯算法下的情感分析——C#编程实现

    这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Language Pr ...

  8. C#编程实现朴素贝叶斯算法下的情感分析

    C#编程实现 这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Lang ...

  9. 【Machine Learning in Action --4】朴素贝叶斯从个人广告中获取区域倾向

    背景:广告商往往想知道关于一个人的一些特定人口统计信息,以便能更好地定向推销广告. 我们将分别从美国的两个城市中选取一些人,通过分析这些人发布的信息,来比较这两个城市的人们在广告用词上是否不同.如果结 ...

随机推荐

  1. Expo大作战(二)--expo的生命周期,expo社区交流方式,expo学习必备资源,开发使用expo时关注的一些问题

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  2. UWP开发细节记录:加载图像文件到D2D位图和D3D纹理

    在UWP中加载文件一般先创建 StorageFile 对象,然后调用StorageFile.OpenReadAsync 方法得到一个IRandomAccessStream 接口用来读取数据: Stor ...

  3. go语言练习:类型转换

    package main import "fmt" func main() { var a int var b uint var c float32 var d float64 a ...

  4. IAM页面是在统一区分配的还是在混合区分配的?

    IAM页面是在统一区分配的还是在混合区分配的? IAM页面的作用这里就不说了,网上的资料很多 文章中用到的工具:查看SQLSERVER内部数据页面的小插件Internals Viewer 先建立四张表 ...

  5. C#多线程的用法10-线程池

    TheadPool:在进行多线程编程时,如果不想频繁的创建线程,那可以考虑使用使用线程池来完成多线程编程的工作.你只需将要处理的任务交付给ThreadPool,如果ThreadPool中有空闲的线程, ...

  6. percona pt toolkit 总结

    ##=====================================================##pt-osc之工作流程:1.检查更改表是否有主键或唯一索引,是否有触发器2.检查修改表 ...

  7. AD用户移除所属组

    AD用户移除所属组: $Membership = Get-ADPrincipalGroupMembership $Users $Membership.distinguishedName Remove- ...

  8. git常用命令图

  9. 乘风破浪:LeetCode真题_026_Remove Duplicates from Sorted Array

    乘风破浪:LeetCode真题_026_Remove Duplicates from Sorted Array 一.前言     我们这次的实验是去除重复的有序数组元素,有大体两种算法. 二.Remo ...

  10. CreateEvent

    事件对象就像一个开关:它只有两种状态---开和关.当一个事件处于”开”状态,我们称其为”有信号”否则称为”无信号”.可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是”无信号”就让该 ...