[机器学习]朴素贝叶斯原理和基于Spark 实例

朴素贝叶斯分类

贝叶斯原理的由来:贝叶斯为了解决一个叫“逆向概率”问题写了一篇文章,尝试解答在缺乏太多可靠证据的情况下,怎样做出更符合数学逻辑的推测。

逆向概率:逆向概率是相对正向概率而言。正向概率的问题很容易理解,比如我们已经知道袋子里面有 N 个球,不是黑球就是白球,其中 M 个是黑球,那么把手伸进去摸一个球,就能知道摸出黑球的概率是多少。这是在了解了事情的全貌再做判断。在现实生活中,我们很难知道事情的全貌。贝叶斯则从实际场景出发,提了一个问题:如果我们事先不知道袋子里面黑球和白球的比例,而是通过我们摸出来的球的颜色,怎么判断出袋子里面黑白球的比例?

就是基于这个问题贝叶斯提出了贝叶斯原理。贝叶斯原理与其他统计学推断方法截然不同,它是建立在主观判断的基础上:在不了解所有客观事实的情况下,同样可以先估计一个值,然后根据实际结果不断进行修正。

贝叶斯原理中的几个概念:

先验概率:就是通过经验来判断事情发生的概率。比如北方的大雪季是11-12 月,就是通过往年的气候总结出来的经验,这个时候下大雪的概率就比其他时间高出很多。

后验概率:后验概率就是发生结果之后,推测原因的概率。比如说某人查出来了患有心脏病,那么患病的原因可能是A、B或C。患有心脏病是因为原因 A的概率就是后验概率。它是属于条件概率的一种。

条件概率:事件A在另外一个事件B已经发生条件下的发生概率,表示为 P(A|B),读作“在B发生的条件下A发生的概率”。比如原因A的条件下,患有心脏病的概率,就是条件概率。

似然函数(likelihood function)

在数理统计学中,似然函数是一种关于统计模型中的参数的函数,表示模型参数中的似然性。你可以把概率模型的训练过程理解为求参数估计的过程。举个例子,考虑投掷一枚硬币的实验。假如已知投出的硬币正面朝上的概率是 0.5,便可以知道投掷若干次后出现各种结果的可能性。比如说,投两次都是正面朝上的概率是0.25。

贝叶斯原理,实际上贝叶斯原理就是求解后验概率。贝叶斯的公式如下:

朴素贝叶斯:

朴素贝叶斯分类是常用的贝叶斯分类方法。 它是一种简单但极为强大的预测建模算法 。之所以称为朴素贝叶斯,是因为它假设每个输入变量是独立的。

朴素贝叶斯模型由两种类型的概率组成:

  1. 每个类别的概率 P(Cj);
  2. 每个属性的 条件概率 P(Ai|Cj)。

在朴素贝叶斯中,要统计的是属性的条件概率,即P(Ai|Cj)。

因为属性A可能会有很多,即

因为

所以

朴素贝叶斯分类常用于文本分类,如垃圾文本过滤、情感预测、推荐系统等。

常用的朴素贝叶斯算法

高斯朴素贝叶斯 :特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度。连续变量属性,考虑概率密度函数,假定p(xi|c)∼N(μc,i,σ2c,i),其中μc,i,σ2c,i分别是c类样本在第i个属性上取值的均值和标准差,则有

 

多项式朴素贝叶斯 :特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的 TF-IDF 值等。

伯努利朴素贝叶斯 :特征变量是布尔变量,符合 0/1 分布,在文档分类中特征是单词是否出现。

伯努利朴素贝叶斯是以文件为粒度,如果该单词在某文件中出现了即为 1,否则为 0。而多项式朴素贝叶斯是以单词为粒度,会计算在某个文件中的具体次数。而高斯朴素贝叶斯适合处理特征变量是连续变量,且符合正态分布(高斯分布)的情况。比如身高、体重这种自然界的现象就比较适合用高斯朴素贝叶斯来处理。而文本分类是使用多项式朴素贝叶斯或者伯努利朴素贝叶斯。

补码朴素贝叶斯:补码朴素贝叶斯(ComplementNB,cNB)是标准多项式朴素贝叶斯(MNB)算法的一种自适应算法,特别适用于不平衡的数据集。

处理技巧:

  1. 如果连续特征不是正态分布的,我们应该使用各种不同的方法将其转换正态分布。
  2. 如果测试数据集具有“零频率”的问题,应用平滑技术“拉普拉斯估计”修正数据集。

零概率问题:就是在计算实例的概率时,如果某个量x,在观察样本库(训练集)中没有出现过,会导致整个实例的概率结果是0。在文本分类的问题中,当一个词语没有在训练样本中出现,该词语调概率为0,使用连乘计算文本出现概率时也为0。这是不合理的,不能因为一个事件没有观察到就武断的认为该事件的概率是0。

  1. 删除重复出现的高度相关的特征,可能会丢失频率信息,影响效果。
  2. 朴素贝叶斯分类在参数调整上选择有限。建议把重点放在数据的预处理和特征选择。

拉普拉斯平滑:

就是对每个类别下所有划分的计数加1,这样如果训练样本集数量充分大时,并不会对结果产生影响,并且解决了零概率的尴尬局面。

 

其中ajl,代表第j个特征的第l个选择,代表第j个特征的个数,K代表种类的个数。

为1,这也很好理解,加入拉普拉斯平滑之后,避免了出现概率为0的情况,又保证了每个值都在0到1的范围内,又保证了最终和为1的概率性质。如:

长相特征的个数为帅,不帅,俩种情况,那么Sj为2,则最终概率p(长相帅|嫁)为4/8 (嫁的个数为6+特征个数为2)

朴素贝叶斯实例

已知如下数据集:

序号

Age

Work

House

Loan

Class

1

中年

一般

2

中年

3

中年

4

中年

非常好

5

老年

非常好

已知某人Age 中年、Work 是,House 是,Loan 一般,请问该人属于哪个分类?

分析:用朴素贝叶斯公式可把问题转化为:

P(Class | Age,Work ,House,Loan)= P(Age,Work,House,Loan| Class )* P(Class)/P(Age,Work,House,Loan)=

P(Age|Class)* P(Work |Class) * P(House |Class) * P(Loan |Class)* P(Class)/ [P(Age)*P( Work)* P( House) *P( Loan)]

1、数据处理

   先把各个特征转换为数字化表示:

描述

编号

中年

0

老年

1

0

1

1

非常好

0

1

一般

2

上表表示为:

序号

Age

Work

House

Loan

Class

1

0

0

0

2

0

2

0

0

0

1

0

3

0

1

1

1

1

4

0

0

1

0

1

5

1

0

1

0

1

代码实例:

输入:naviebays.txt

0 0 0 2 0

0 0 0 1 0

0 1 1 1 1

0 0 1 0 1

1 0 1 0 1



package sparkmlNaiveBayes;

import java.util.*;

import org.apache.spark.SparkConf;

import org.apache.spark.api.java.JavaRDD;

import org.apache.spark.api.java.function.Function;

import org.apache.spark.ml.classification.NaiveBayes;

import org.apache.spark.ml.classification.NaiveBayesModel;

import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator;

import org.apache.spark.ml.feature.VectorAssembler;

import org.apache.spark.sql.Dataset;

import org.apache.spark.sql.Row;

import org.apache.spark.sql.RowFactory;

import org.apache.spark.sql.SparkSession;

import org.apache.spark.sql.types.DataTypes;

import org.apache.spark.sql.types.StructField;

import org.apache.spark.sql.types.StructType;



public class navieBayes {

    public static void main(String[] args) {

      

      SparkConf spconf=new  SparkConf().setMaster("local[4]").setAppName("testNaiveByes");

      SparkSession spsession=SparkSession.builder().config(spconf).getOrCreate();

       String schemaString = "a b c d label";

       List<StructField> fields = new ArrayList<>();

       for (String fieldName : schemaString.split(" ")) {

         StructField field = DataTypes.createStructField(fieldName, DataTypes.IntegerType, true);

         fields.add(field);

       }

       StructType schema = DataTypes.createStructType(fields);

       JavaRDD<String> javaRDDstr=spsession.sparkContext().textFile(".\\naviebays.txt",2).toJavaRDD();

      

       JavaRDD<Row> rowRDD=javaRDDstr.map((Function<String, Row>) r->

       {

       String[] attributes =  r.split(" ");

       int[] arr = new int[attributes.length];

        for (int i = 0; i < attributes.length; i++)

        {

            arr[i] = Integer.parseInt(attributes[i]);

        }

       return RowFactory.create(arr[0],arr[1],arr[2],arr[3],arr[4]);

} );

       Dataset<Row> df1 = spsession.createDataFrame(rowRDD, schema);

       df1.show();

       VectorAssembler v=new VectorAssembler();

       v.setInputCols( new String[]{"a","b","c","d"});

       v.setOutputCol("items");

       Dataset  df2= v.transform(df1);

       df2.show(false);

       NaiveBayes nb = new NaiveBayes();

      nb.setFeaturesCol("items");

      nb.setLabelCol("label");         

      NaiveBayesModel model = nb.fit(df2);

        Dataset<Row> predictions = model.transform(df2);

    predictions.show(false);

        MulticlassClassificationEvaluator evaluator = new MulticlassClassificationEvaluator()

                .setLabelCol("label")

                .setPredictionCol("prediction")

                .setMetricName("accuracy");

             double accuracy = evaluator.evaluate(predictions);

            System.out.println("Test set accuracy = " + accuracy);

    }

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值