Spark实现贝叶斯算法本章要点一、分类算法二、贝叶斯公式三、朴素贝叶斯分类四、Spark实现贝叶斯算法分类算法何为分类算法?简单来说,就是将具有某些特性的物体归类对应到一个已知的类别集合中的某个类别上。从数学角度来说,可以做如下定义:已知集合:C={y1,y2,..,yn}和I={x1,x2,..,xm,..},确定映射规则y=f(x),使得任意xi∈I有且仅有一个yj∈C使得yj=f(xi)成立。其中,C为类别集合,I为待分类的物体,f则为分类器,分类算法的主要任务就是构造分类器f。分类算法的构造通常需要一个已知类别的集合来进行训练,通常来说训练出来的分类算法不可能达到100%的准确率。分类器的质量往往与训练数据、验证数据、训练数据样本大小等因素相关。分类算法举个例子,我们日常生活中看到一个陌生人,要做的第一件事情就是判断其性别,判断性别的过程就是一个分类的过程。根据以往的生活经验,通常经过头发长短、服饰和体型这三个要素就能判断出来一个人的性别。这里的“生活经验”就是一个训练好的关于性别判断的模型,其训练数据是日常生活中遇到的形形色色的人。突然有一天,一个娘炮走到了你面前,长发飘飘,穿着紧身的衣裤,可是体型却很man,于是你就疑惑了,根据以往的经验——也就是已经训练好的模型,无法判断这个人的性别。于是你学会了通过喉结来判断其性别,这样你的模型被训练的质量更高了。但不可否认的是,永远会出现一个让你无法判断性别的人。所以模型永远无法达到100%的准确,只会随着训练数据的不断增多而无限接近100%的准确。贝叶斯公式贝叶斯公式,或者叫做贝叶斯定理,是贝叶斯分类的基础。而贝叶斯分类是一类分类算法的统称,这一类算法的基础都是贝叶斯公式。目前研究较多的四种贝叶斯分类算法有:NaiveBayes、TAN、BAN和GBN。理工科的学生在大学应该都学过概率论,其中最重要的几个公式中就有贝叶斯公式——用来描述两个条件概率之间的关系,比如P(A|B)和P(B|A)。如何在已知事件A和B分别发生的概率,和事件B发生时事件A发生的概率,来求得事件A发生时事件B发生的概率,这就是贝叶斯公式的作用。其表述如下:贝叶斯公式朴素贝叶斯分类朴素贝叶斯分类,NaiveBayes,你也可以叫它NB算法。其核心思想非常简单:对于某一预测项,分别计算该预测项为各个分类的概率,然后选择概率最大的分类为其预测分类。就好像你预测一个娘炮是女人的可能性是40%,是男人的可能性是41%,那么就可以判断他是男人。NaiveBayes的数学定义如下:1.设x={a1,a2,..,am}为一个待分类项,而每个ai为x的一个特征属性2.已知类别集合C={y1,y2,..,yn}3.计算x为各个类别的概率:P(y1|x),P(y2|x),..,P(yn|x)4.如果P(yk|x)=max{P(y1|x),P(y2|x),..,P(yn|x)},则x的类别为yk朴素贝叶斯分类如何获取第四步中的最大值,也就是如何计算第三步中的各个条件概率最为重要。可以采用如下做法:1.获取训练数据集,即分类已知的数据集2.统计得到在各类别下各个特征属性的条件概率估计,即:P(a1|y1),P(a2|y1),...,P(am|y1);P(a1|y2),P(a2|y2),...,P(am|y2);...;P(a1|yn),P(a2|yn),...,P(am|yn),其中的数据可以是离散的也可以是连续的3.如果各个特征属性是条件独立的,则根据贝叶斯定理有如下推导:P(yi|x)=P(x|yi)P(yi)P(x)对于某x来说,分母是固定的,所以只要找出分子最大的即为条件概率最大的。又因为各特征属性是条件独立的,所以有:P(x|yi)P(yi)=P(a1|yi)P(a2|yi)...P(am|yi)P(yi)=P(yi)∏mj=1P(aj|yi)Spark实现贝叶斯算法测试数据0,1000,2000,100.10,200.20,10.100,20.201,010.11,020.2朴素贝叶斯分类其中第一列代表类别,训练数据中有三种类别:0、1、2。第2-4列代表数据的三个维度,可以想象成前文中性别分类算法中的头发长度、服饰和体型这三个要素。通常来说为了保证每个要素的权值相差不大,需要取相对的数值,例如头发长度/最长的头发长度。Spark实现贝叶斯算法publicstaticvoidmain(String[]args){SparkConfsparkConf=newSparkConf().setAppName(Bayes).setMaster(local[2]);JavaSparkContextsc=newJavaSparkContext(sparkConf);JavaRDDStringdata=sc.textFile(/home/yurnom/data/sample_naive_bayes_data.txt);RDDLabeledPointparsedData=data.map(line-{String[]parts=line.split(,);double[]values=Arrays.stream(parts[1].split()).mapToDouble(Double::parseDouble).toArray();//LabeledPoint代表一条训练数据,即打过标签的数据returnnewLabeledPoint(Double.parseDouble(parts[0]),Vectors.dense(values));}).rdd();Spark实现贝叶斯算法结果Accuracy=1.0Predictionof(0.5,3.0,0.5):1.0Predictionof(1.5,0.4,0.6):0.0Predictionof(0.3,0.4,2.6):2.0由于数据的人为捏造过度,可以看到此次训练的模型精度十分高为100%,即测试数据的类别和用模型预测出来的对于类别完全吻合,实际生产环境中是无法达到100%的。后面又预测了3个不在训练数据中的数据,结果和大脑判断的类别完全相同。