• 机器学习——朴素贝叶斯(Naive Bayes)详解及其python仿真


    参考视频与文献:

    https://www.bilibili.com/video/BV1oX4y137p9?spm_id_from=333.999.0.0&vd_source=77c874a500ef21df351103560dada737

    统计学习方法(第二版)李航(编著) 

    一、朴素贝叶斯(naive Bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入输出的联合概率分布;然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y。朴素贝叶斯法实现简单,学习与预测的效率都很高,是一种常用的方法。

    那么在掌握朴素贝叶斯算法之前,我们必须了解条件概率和全概率。

    1.1、条件概率公式如下:

    1.2、全概率公式如下:

    指若事件{A1,A2,…,An}构成一个完备事件组且都有正概率,则对任意一个事件B都有:

     

    则有 

    二、贝叶斯定理

    一种有效计算条件概率的方法称为贝叶斯定理。贝叶斯定理告诉我们如何交换条件概率中的条件与结果,即如果已知 P(X|Y),要求 P(Y|X):

    这里的每个概率都有其特定的名称:

    P ( Y ) :先验概率。先验概率(prior probability)是指事情还没有发生,求这件事情发生的可能性的大小,是先验概率。它往往作为"由因求果"问题中的"因"出现。

    P ( Y ∣ X ) :后验概率。后验概率是指事情已经发生,求这件事情发生的原因是由某个因素引起的可能性的大小。后验概率的计算要以先验概率为基础

    P ( X ∣ Y ) :条件概率,又叫似然概率,一般是通过历史数据统计得到。一般不把它叫做先验概率,但从定义上也符合先验定义。

    三、贝叶斯推论:

    结合条件概率可推导出如下公式:

    即为贝叶斯公式。把P(Ai)称为先验概率(Prior probability),即在B事件发生之前,我们对A事件概率的一个判断。
    P(Ai|B)称为后验概率(Posterior probability),即在B事件发生之后,我们对A事件概率的重新评估。
    P(B|Ai)/P(B)称为可能性函数(Likelyhood),这是一个调整因子,使得预估概率更接近真实概率。
    所以条件概率可以理解为:后验概率 = 先验概率 × 调整因子

    如果"可能性函数">1,意味着先验概率被增强,事件A的发生的可能性变大;
    如果"可能性函数"=1,意味着B事件无助于判断事件A的可能性;
    如果"可能性函数"<1,意味着"先验概率"被削弱,事件A的可能性变小。

    四、朴素贝叶斯法是典型的生成学习方法。生成方法由训练数据学习联合概率分布P(X,Y),然后求得后验概率分布P(Y|X)。具体来说,利用训练数据学习P(X|Y)和P(Y)的估计,得到联合概率分布:

    P(X,Y)=P(Y)P(X|Y)

    概率估计方法可以是极大似然估计或贝叶斯估计。 

    五、朴素贝叶斯法的基本假设是条件独立性,

    这是一个较强的假设。由于这一假设,模型包含的条件概率的数量大为减少,朴素贝叶斯法的学习与预测大为简化。因而朴素贝叶斯法高效,且易于实现。其缺点是分类的性能不一定很高。

    六、朴素贝叶斯算法如下:

    视频截图: 

     

     

     

    程序如下:

    1. import numpy as np
    2. def createDataSet():
    3. dataSet = [[0, 0, 0, 0, 'no'], #数据集
    4. [0, 0, 0, 1, 'no'],
    5. [0, 1, 0, 1, 'yes'],
    6. [0, 1, 1, 0, 'yes'],
    7. [0, 0, 0, 0, 'no'],
    8. [1, 0, 0, 0, 'no'],
    9. [1, 0, 0, 1, 'no'],
    10. [1, 1, 1, 1, 'yes'],
    11. [1, 0, 1, 2, 'yes'],
    12. [1, 0, 1, 2, 'yes'],
    13. [2, 0, 1, 2, 'yes'],
    14. [2, 0, 1, 1, 'yes'],
    15. [2, 1, 0, 1, 'yes'],
    16. [2, 1, 0, 2, 'yes'],
    17. [2, 0, 0, 0, 'no']]
    18. labels = ['年龄', '有工作', '有自己的房子', '信贷情况'] #特征标签
    19. return dataSet, labels #返回数据集和分类属性
    20. # 获取概率模型, 输入feat np.array格式 大小[N,D]
    21. def trainPbmodel_X(feats):
    22. N,D = np.shape(feats)
    23. model = {}
    24. # 对每一维度的特征进行概率统计
    25. for d in range(D):
    26. data = feats[:,d].tolist()
    27. keys = set(data)
    28. N = len(data)
    29. model[d] ={}
    30. for key in keys:
    31. model[d][key] = float(data.count(key)/N)
    32. return model
    33. # datas: list格式 每个元素表示1个特征序列
    34. # labs: list格式 每个元素表示一个标签
    35. def trainPbmodel(datas,labs):
    36. # 定义模型
    37. model = {}
    38. # 获取分类的类别
    39. keys = set(labs)
    40. for key in keys:
    41. # 获得P(Y)
    42. Pbmodel_Y = labs.count(key)/len(labs)
    43. # 收集标签为Y的数据
    44. index = np.where(np.array(labs)==key)[0].tolist()
    45. feats = np.array(datas)[index]
    46. # 获得 P(X|Y)
    47. Pbmodel_X = trainPbmodel_X(feats)
    48. # 模型保存
    49. model[key]={}
    50. model[key]["PY"] = Pbmodel_Y
    51. model[key]["PX"] = Pbmodel_X
    52. return model
    53. # feat : list格式 一条输入特征
    54. # model: 训练的概率模型
    55. # keys :考察标签的种类
    56. def getPbfromModel(feat,model,keys):
    57. results ={}
    58. eps = 0.00001
    59. for key in keys:
    60. # 获取P(Y)
    61. PY = model.get(key,eps).get("PY")
    62. # 分别获取 P(X|Y)
    63. model_X = model.get(key,eps).get("PX")
    64. list_px=[]
    65. for d in range(len(feat)):
    66. pb = model_X.get(d,eps).get(feat[d],eps)
    67. list_px.append(pb)
    68. result = np.log(PY) + np.sum(np.log(list_px))
    69. results[key]= result
    70. return results
    71. if __name__ == '__main__':
    72. '''实验一 自制贷款数据集'''
    73. # # 获取数据集
    74. # dataSet, labels = createDataSet()
    75. # # 截取数据和标签
    76. # datas = [i[:-1] for i in dataSet]
    77. # labs = [i[-1] for i in dataSet]
    78. # # 获取标签种类
    79. # keys = set(labs)
    80. # # 进行模型训练
    81. # model = trainPbmodel(datas,labs)
    82. # print(model)
    83. # # 根据输入数据获得预测结果
    84. # feat = [0,1,0,1]
    85. # result = getPbfromModel(feat,model,keys)
    86. # print(result)
    87. # # 遍历结果找到概率最大值进行数据
    88. # for key,value in result.items():
    89. # if(value == max(result.values())):
    90. # print("预测结果是",key)
    91. # '''实验二 隐形眼睛数据集'''
    92. # 读取数据文件 截取数据和标签
    93. with open("train-lenses.txt",'r',encoding="utf-8") as f:
    94. lines = f.read().splitlines()
    95. dataSet = [line.split('\t') for line in lines]
    96. datas = [i[:-1] for i in dataSet]
    97. labs = [i[-1] for i in dataSet]
    98. # 获取标签种类
    99. keys = set(labs)
    100. # 进行模型训练
    101. model = trainPbmodel(datas,labs)
    102. print(model)
    103. # 测试
    104. # 读取测试文件
    105. with open("test-lenses.txt",'r',encoding="utf-8") as f:
    106. lines = f.read().splitlines()
    107. # 逐行读取数据并测试
    108. for line in lines:
    109. data = line.split('\t')
    110. lab_true = data[-1]
    111. feat = data[:-1]
    112. result = getPbfromModel(feat,model,keys)
    113. key_out = ""
    114. for key,value in result.items():
    115. if(value == max(result.values())):
    116. key_out=key
    117. print("输入特征:")
    118. print(data)
    119. print(result)
    120. print("预测结果 %s 医生推荐 %s"%(key_out,lab_true))

    运行结果如下:

  • 相关阅读:
    SPD5详解
    Macleod中的偏振
    web页面之间的3种关系
    WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表
    WPF 入门笔记 - 08 - 动画
    XxlJob实现Alarm警告
    EfficientDet论文讲解
    2023-09-04 LeetCode每日一题(序列化和反序列化二叉搜索树)
    WEB服务的配置与使用 Apache HTTPD
    POJ1062 , kuangbin专题 昂贵的聘礼
  • 原文地址:https://blog.csdn.net/qq_42233059/article/details/126892996