统计学习方法(四)——朴素贝叶斯法

系统 1451 0

/*先把标题给写了、这样就能经常提醒自己*/

题记:今天下午去上厕所的一会儿时间,就把第四章给扫完了,说是扫完了主要是因为没有深入去看,对于某些证明都直接跳过了,看了一下里面的例子,大概懂个意思就行了

1.  朴素贝叶斯法

  设输入空间 维向量的集合,输出空间为类标记集合 ,输入特征向量 ,输出类标记为 的联合概率分布,数据集

独立同分布产生。

  朴素贝叶斯法就是通过训练集来学习联合概率分布 .具体怎么学习呢? 主要就是从先验概率分布和条件概率分布入手,俩个概率相乘即可得联合概率。

  为什么称之为朴素呢,主要是其将条件概率的估计简化了,对条件概率分布作了条件独立性假设,这也是朴素贝叶斯法的基石,具体的假设如下

                   

此公式在假设条件之下可以等价于

                      

现在, 对于给定的输入向量 ,通过学习到的模型计算后验概率分布P(Y=Ck|X=x),后验分布中最大的类作为的输出结果,根据贝叶斯定理可知后验概率为

 

 

上面的公式可能有点歧义,分母的Ck应该写成Cj才对,因为P(X=x)=E P(Y=Cj)*P(X=x|Y=Cj)

对于所有 都是相同的,即此可以将输出结果简化为

                        

至此大概讲解了朴素贝叶斯的基本方法步骤了,关于参数估计还有具体实例下次再写了。夏天真热啊!

2.  参数估计

  2.1 极大似然估计

上一小节讲了对于给定的输入向量 ,其输出结果可表示为

                          

对此可应用极大似然估计法来估计相应的概率,如先验概率 的极大似然估计是

                        

设第个 特征 可能取值的集合为 ,条件概率 的极大似然估计是

                       

公式看起来可能有点不实在,还是直接上例子来说明吧!

 

例子:试由下表的训练数据学习一个朴素贝叶斯分类器并确定 的类标记,表中 为特征, 为类标记。

统计学习方法(四)——朴素贝叶斯法_第1张图片


解:先验概率,

条件概率

据此可算出 后验分布中值 最大的,也就是最终的类标记为-1

    2.2 贝叶斯 估计

  极大似然估计的一个可能是会出现所要估计的概率值为 0的情况,这时会影响到后验概率的计算结果,解决这一问题的方法是采用贝叶斯估计,具体的只需要在极大似然估计的基础上加多一个参数即可。懒得继续写公式了,不想写了,刚刚码完代码!!

 

有兴趣的可以看一下具体的代码实现

      
        package
      
      
         org.juefan.bayes;


      
      
        import
      
      
         java.util.ArrayList;

      
      
        import
      
      
         java.util.HashMap;

      
      
        import
      
      
         java.util.Map;


      
      
        import
      
      
         org.juefan.basic.FileIO;

      
      
        /**
      
      
        
 * 这是一个简易的贝叶斯分类器
 * 只适用于离散数据,连续型数据的暂时请先绕道了^.^
 * 
      
      
        @author
      
      
         JueFan
 
      
      
        */
      
      
        public
      
      
        class
      
      
         NaiveBayes{

    
      
      
        //
      
      
        平滑指数, 默认为拉普拉斯平滑,极大似然估计则为0
      
      
        private
      
      
        static
      
      
        double
      
       Lambda  = 1
      
        ; 
    
      
      
        //
      
      
        存储先验概率数据
      
      
        private
      
       Map<Object, Double> PriorProbability = 
      
        new
      
       HashMap<>
      
        ();
    
      
      
        //
      
      
        存储条件概率数据
      
      
        private
      
       Map<Object, ArrayList<Map<Object, Double>>> ConditionProbability = 
      
        new
      
       HashMap<>
      
        ();

    
      
      
        /**
      
      
        
     * 计算类别的先验概率
     * 
      
      
        @param
      
      
         datas 
     
      
      
        */
      
      
        public
      
      
        void
      
       setPriorPro(ArrayList<Data>
      
         datas){
        
      
      
        int
      
       counts =
      
         datas.size();
        
      
      
        for
      
      
        (Data data: datas){
            
      
      
        if
      
      
        (PriorProbability.containsKey(data.y)){
                PriorProbability.put(data.y, PriorProbability.get(data.y) 
      
      + 1
      
        );
            }
      
      
        else
      
      
         {
                PriorProbability.put(data.y, (
      
      
        double
      
      ) 1
      
        );
            }
        }
        
      
      
        for
      
      
        (Object o: PriorProbability.keySet())
            PriorProbability.put(o, (PriorProbability.get(o) 
      
      + Lambda)/(counts + Lambda *
      
         PriorProbability.size()));
    }

    
      
      
        /**
      
      
        
     * 计算条件概率
     * 
      
      
        @param
      
      
         datas
     
      
      
        */
      
      
        public
      
      
        void
      
       setCondiPro(ArrayList<Data>
      
         datas){
        Map
      
      <Object, ArrayList<Data>> tmMap = 
      
        new
      
       HashMap<>
      
        ();
        
      
      
        //
      
      
        按类别先将数据分类存放
      
      
        for
      
      
        (Data data: datas){
            
      
      
        if
      
      
        (tmMap.containsKey(data.y)){
                tmMap.get(data.y).add(data);
            }
      
      
        else
      
      
         {
                ArrayList
      
      <Data> tmDatas = 
      
        new
      
       ArrayList<>
      
        ();
                tmDatas.add(data);
                tmMap.put(data.y, tmDatas);
            }
        }
        
      
      
        //
      
      
        条件概率主体
      
      
        for
      
      
        (Object o: tmMap.keySet()){
            ArrayList
      
      <Map<Object, Double>> tmCon = 
      
        new
      
       ArrayList<>
      
        ();
            
      
      
        int
      
       LabelCount =
      
         tmMap.get(o).size();
            
      
      
        //
      
      
        计算每个特征的相对频数
      
      
        for
      
      
        (Data data: tmMap.get(o)){
                
      
      
        for
      
      (
      
        int
      
       i = 0; i < data.x.size(); i++
      
        ){
                    
      
      
        if
      
      (tmCon.size() < i + 1
      
        ){
                        Map
      
      <Object, Double> tmMap2 = 
      
        new
      
       HashMap<>
      
        ();
                        tmMap2.put(data.x.get(i), (
      
      
        double
      
      ) 1
      
        );
                        tmCon.add(tmMap2);
                    }
      
      
        else
      
      
         {
                        
      
      
        if
      
      
        (tmCon.get(i).containsKey(data.x.get(i))){
                            tmCon.get(i).put(data.x.get(i), tmCon.get(i).get(data.x.get(i)) 
      
      + 1
      
        );
                        }
      
      
        else
      
      
         {
                            tmCon.get(i).put(data.x.get(i),  (
      
      
        double
      
      ) 1
      
        );
                        }
                    }
                }
            }
            
      
      
        //
      
      
        计算条件概率
      
      
        for
      
      (
      
        int
      
       i = 0; i < tmCon.size(); i++
      
        ){
                
      
      
        for
      
      
        (Object o1: tmCon.get(i).keySet()){
                    tmCon.get(i).put(o1, (tmCon.get(i).get(o1) 
      
      + Lambda)/(LabelCount + Lambda *
      
         tmCon.get(i).size()));
                }
            }
            ConditionProbability.put(o, tmCon);
        }
    }

    
      
      
        /**
      
      
        
     * 判断实例的类别
     * 
      
      
        @param
      
      
         data
     * 
      
      
        @return
      
      
         判断结果
     
      
      
        */
      
      
        public
      
      
         Object getLabel(Data data){
        Object label 
      
      = 
      
        new
      
      
         Object();
        
      
      
        double
      
       pro =
      
         0D;
        
      
      
        for
      
      
        (Object o: PriorProbability.keySet()){
            
      
      
        double
      
       tmPro = 1
      
        ;
            tmPro 
      
      *=
      
         PriorProbability.get(o);
            
      
      
        for
      
      (
      
        int
      
       i = 0; i < data.x.size(); i++
      
        ){
                tmPro 
      
      *=
      
         ConditionProbability.get(o).get(i).get(data.x.get(i));
            }
            
      
      
        if
      
      (tmPro >
      
         pro){
                pro 
      
      =
      
         tmPro;
                label 
      
      =
      
         o;
            }
            System.out.println(o.toString() 
      
      + " :的后验概率为: " +
      
         tmPro);
        }
        
      
      
        return
      
      
         label;
    }

    
      
      
        public
      
      
        static
      
      
        void
      
      
         main(String[] args) {
        ArrayList
      
      <Data> datas = 
      
        new
      
       ArrayList<>
      
        ();
        FileIO fileIO 
      
      = 
      
        new
      
      
         FileIO();
        fileIO.setFileName(
      
      ".//file//bayes.txt"
      
        );
        fileIO.FileRead();
        
      
      
        for
      
      
        (String data: fileIO.fileList){
            datas.add(
      
      
        new
      
      
         Data(data));
        }

        NaiveBayes bayes 
      
      = 
      
        new
      
      
         NaiveBayes();
        bayes.setPriorPro(datas);
        bayes.setCondiPro(datas);

        Data data 
      
      = 
      
        new
      
       Data("1\t2\tS"
      
        );
        System.out.println(data.toString() 
      
      + "\t的判断类别为: " +
      
         bayes.getLabel(data));
    }
}
      
    

 

 对代码有兴趣的可以上本人的GitHub查看: https://github.com/JueFan/StatisticsLearningMethod/

统计学习方法(四)——朴素贝叶斯法


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论