zoukankan      html  css  js  c++  java
  • Naive Bayes Classifier 朴素贝叶斯分类器

    贝叶斯分类器的分类

    根据实际处理的数据类型, 可以分为离散型贝叶斯分类器和连续型贝叶斯分类器, 这两种类型的分类器, 使用的计算方式是不一样的.

    贝叶斯公式

    首先看一下贝叶斯公式

    $ Pleft ( y|x ight ) = frac{Pleft ( x|y ight ) * Pleft ( y ight )}{sum_{i=1}^{n}Pleft ( x|y_{i} ight )*Pleft ( y_{i} ight )} $

    其推导很简单, 因为 P(yx) = P(xy), 可得 P(y|x) * P(x) = P(x|y) * P(y), 可得 P(y|x) = P(x|y) * P(y) / P(x), 将P(x)分解就得到了上面的公式.

    在实际应用中, 可以用于计算一些检测项目的可靠性. 例如某机构对雇员是否吸毒的检测. 假定吸毒人员比例很低, 为0.5%, 而检测存在误差, 吸毒者检出阳性率为99%, 非吸毒者检出阳性率1%, 那么仅作一轮检测, 检出阳性的结果中实际是吸毒者的比例有多高呢? 用式子描述就是

    P(吸毒|阳性)
    = P(阳性|吸毒) * P(吸毒) / P(阳性)
    = P(阳性|吸毒) * P(吸毒) / (P(阳性|吸毒)*P(吸毒) + P(阳性|未吸毒)*P(未吸毒))
    = 0.99 * 0.005 / (0.99 * 0.005 + 0.01 * 0.995) = 0.00495 / (0.00495 + 0.00995) = 0.00495 / 0.0149 = 0.3322

    对检测为阳性的雇员, 再做第二轮检测, 检出阳性的结果中实际是吸毒者的比例还可以按上式计算, 但是P(吸毒)从0.005变成了0.3322, 于是

    P(吸毒|阳性) = 0.99 * 0.3322 / (0.99 * 0.3322 + 0.01 * 0.6678) = 0.98

    这样经过二次检测后呈阳性的结果误判率就仅有2%了.

    另外, 对于检测结果为阴性的雇员, 其吸毒的概率计算如下, 误判的概率很低

    P(吸毒|阴性)
    = P(阴性|吸毒) * P(吸毒) / P(阴性)
    = P(阴性|吸毒) * P(吸毒) / (P(阴性|吸毒)*P(吸毒) + P(阴性|未吸毒)*P(未吸毒))
    = 0.01 * 0.005 / (0.01 * 0.005 + 0.99 * 0.995)
    = 0.00005 / (0.00005 + 0.98505) = 0.005%

    高斯分布公式

    高斯分布(Gaussian distribution) 又名正态分布(Normal distribution)/常态分布. 是一个在数学物理及工程等领域都非常重要的概率分布, 在统计学的许多方面有着重大的影响力, 正态曲线呈钟型, 若随机变量X服从一个数学期望为μ, 方差为σ^2的正态分布, 记为N(μ,σ^2). 其概率密度函数为正态分布的期望值μ决定了其位置, 其标准差σ决定了分布的幅度. 当μ = 0, σ = 1时正态分布就是标准正态分布. 

    高斯函数标准型:

    $ f(x)=frac{1}{sqrt{2pi }}e^{-frac{x^{2}}{2}}, -infty < x < +infty $

    这个函数描述了变量 x 的一种分布特性,变量x的分布有如下特点:

    • 均值 = 0
    • 方差为1
    • 概率密度和为1

    一元高斯函数一般形式

    $ f(x)=frac{1}{sqrt{2pi sigma }}e^{-frac{(x - mu )^{2}}{2sigma ^{2}}}, -infty < x < +infty $

    其中μ, σ(σ > 0)为常数, 一般使用均值作为μ, 标准差(Standard Deviation [ˌdi:viˈeɪʃn] )作为σ

    高斯分布重要量的性质

    • 密度函数关于平均值对称
    • 平均值是它的众数(statistical mode)以及中位数(median)
    • 68.268949%的面积在平均值左右一个标准差σ范围内
    • 95.449974%的面积在平均值左右两个标准差2σ范围内
    • 99.730020%的面积在平均值左右三个标准差3σ范围

    离散型的贝叶斯分类器

    离散型的贝叶斯分类器, 训练数据为Xin和 Yin,
    Xin是离散的特征值, 例如英文句子 I like sun shine, I am so happy, It is a good day, 和 I hate rainy, I don't like cloudy day,
    Yin是对应的分类, 例如前面的句子, 对应的Yin分别是positive, positive, positive, negative, negative

    训练时, 将句子拆成单词, 以单词作为特征值, 累计到以下key的count
    ytotal, ypositive, ynegative,
    xsun&ypositive, xshine&ypositive, xhappy&ypositive, ... , xI&ypositive, xam&ypositive, xI&ynegative, ... xday&ynegative

    计算以下数值:

    P(ypositive) = ypositive / ytotal
    P(ynegative) = ynegative / ytotal

    对于测试的句子, 将句子拆分为单词数组, 分别计算各个单词对于yi的条件概率: 
    P(yi|xword) = P(xword|yi) * P(yi) / Σ (P(xword|yj) * P(yj)) 
    对每个单词得到的值累加, 将累加的结果进行排序, 最高的yi就是分类的结果. 

    对于Σ P(xword|yj) * P(yj) 的值为0的情况, 可以给每一个count(xwordi&yj)预设一个初始值, 例如count(xwordi&yj) = 1, 避免除数为0

    连续型贝叶斯分类器(高斯贝叶斯分类器)

    连续型的贝叶斯分类器, 训练数据为Xin和 Yin

    Xin是带多维向量的特征值, 例如一个人的身高体重(H, W):  (175, 68.5), (181.5, 75.3), (132, 31.5), (170, 71.5), (60, 15.0)
    Yin是对应的分类, 例如前面的Xin值, 对应的Yin分别是A, A, K, A, K (A:adult, K:kid)

    训练时, 需要计算以下值:

    P(A) = YA / Ytotal
    P(K) = YK / Ytotal
    A的身高均值和标准差: μAH, σAH, A的体重均值和标准差: μAW, σAW
    K的身高均值和标准差: μKH, σKH, B的体重均值和标准差: μKW, σKW
    假定身高和体重这两个是相互独立的维度. 这样就确定了这两个分类, 在各维度上的高斯分布函数

    对于输入的测试数据 x:(h, w), 先对A计算各个维度上的高斯分布概率, 再将结果乘起来(假定各维度相互独立):
    P(x|A) = P(Hx|A) * P(Wx|A) = GAH(x) * GAW(x), 再计算得到 P(A|x) = P(x|A) * P(A) / (P(x|A) * P(A) + P(x|K) * P(K))
    同理计算得到P(K|x), 比较P(A|x)和 P(K|x)大小, 大者就是选中的结果分类.

    ...
    public static HashMap<Integer, HashMap<Integer, Double>> meanMatrix = new HashMap<>(); //Matrix to hold the mean values
    public static HashMap<Integer, HashMap<Integer, Double>> derivationMatrix = new HashMap<>(); //Matrix to hold standard devirations
    ...
    
    /**
     * Get gaussian parameters by lable & feature, then calculate with input x
     */
    public static double gaussian(double x, int label, int feature) {
        double conditionalMean = meanMatrix.get(label).get(feature);
        double conditionalDerivation = derivationMatrix.get(label).get(feature);
        return (Math.exp(-1 * (Math.pow(x - conditionalMean, 2) / (2 * conditionalDerivation)))) / (Math.sqrt(2 * Math.PI * conditionalDerivation));
    }
    

    .

  • 相关阅读:
    “菜鸟”程序员和“大神”程序员差距在哪里?别告诉我你连菜鸟都不算!
    Android开发:为什么你的学习效率如此低,为什么你很迷茫?
    Android架构师吐槽腾讯王者荣耀的程序员,排位匹配算法怎么搞的,每次都输
    程序员如何回答面试官“请介绍一下自己”这类问题
    Android程序员事件分发机制学习笔记
    面试时,问哪些问题能试出一个 Android 应用开发者真正的水平?
    List、Set、Map的区别
    在Eclipse中使用JUnit4进行单元测试(图文教程一)
    1
    2016、11、17
  • 原文地址:https://www.cnblogs.com/milton/p/9292184.html
Copyright © 2011-2022 走看看