1.概述
要了解贝叶斯分类,必须了解贝叶斯定理,贝叶斯定理离不开条件概率
条件概率定义:
事件A在另外一个事件B已经发生条件下的发生概率。条件概率表示为P(A|B),读作“在B条件下A的概率”。
在事件B发生的情况下,事件A发生的概率就是P(A∩B)除以P(B)。
可以很清楚地看到在事件B发生的情况下,事件A发生的概率就是P(A∩B)除以P(B)。
P(A|B)=P(A∩B)/P(B)
因此,P(A∩B)=P(A|B)P(B)
所以,P(A|B)P(B)=P(B|A)P(A)
即
P(A|B)=P(B|A)P(A)/P(B)
2.贝叶斯分类的定义
1、设为一个待分类项,而每个a为x的一个特征属性。
2、有类别集合。
3、计算。
4、求出在X个属性条件下,所有类别的概率,选取概率最大的。则X属于概率最大的类别
,则
。
根据贝叶斯定理,要求P(A|B),只要求出P(B|A)即可 .这里Y指A,X指B.把B分解为各个特征属性,求出每个类别的每个特征属性即可,如下
1、找到一个已知分类的待分类项集合,这个集合叫做训练样本集。
2、统计得到在各类别下各个特征属性的条件概率估计。即。
3、如果各个特征属性是条件独立的,则根据贝叶斯定理有如下推导:
因为分母对于所有类别为常数,因为我们只要将分子最大化皆可。又因为各特征属性是条件独立的,所以有:
上式等号右边的每一项,都可以从统计资料中得到,由此就可以计算出每个类别对应的概率,从而找出最大概率的那个类。
注意:各个特征属性是条件独立的,这是朴素贝叶斯所要求的,如果各个特征属性不独立,就不属于朴素贝叶斯,属于贝叶斯网络,暂时不在这里展开。
3.例子
1. 看一个阮一峰老师的朴素贝叶斯应用一文中摘自维基百科的例子,关于处理连续变量的另一种方法。
下面是一组人类身体特征的统计资料。
- 性别 身高(英尺) 体重(磅) 脚掌(英寸)
- 男 6 180 12
- 男 5.92 190 11
- 男 5.58 170 12
- 男 5.92 165 10
- 女 5 100 6
- 女 5.5 150 8
- 女 5.42 130 7
- 女 5.75 150 9
已知某人身高6英尺、体重130磅,脚掌8英寸,请问该人是男是女?
根据朴素贝叶斯分类器,计算下面这个式子的值。
P(身高|性别) x P(体重|性别) x P(脚掌|性别) x P(性别)
这里的困难在于,由于身高、体重、脚掌都是连续变量,不能采用离散变量的方法计算概率。而且由于样本太少,所以也无法分成区间计算。怎么办?
这时,可以假设男性和女性的身高、体重、脚掌都是正态分布,通过样本计算出均值和方差,也就是得到正态分布的密度函数。有了密度函数,就可以把值代入,算出某一点的密度函数的值。
比如,男性的身高是均值5.855、方差0.035的正态分布。所以,男性的身高为6英尺的概率的相对值等于1.5789(大于1并没有关系,因为这里是密度函数的值,只用来反映各个值的相对可能性)。
有了这些数据以后,就可以计算性别的分类了。
P(身高=6|男) x P(体重=130|男) x P(脚掌=8|男) x P(男)
= 6.1984 x e-9P(身高=6|女) x P(体重=130|女) x P(脚掌=8|女) x P(女)
= 5.3778 x e-4
可以看到,女性的概率比男性要高出将近10000倍,所以判断该人为女性。
2. 数据:天气情况和每天是否踢足球的记录表
数据抽象为如下,含义为是否会去踢球,天气,温度,湿度,风速
如果15号的天气为(晴天,凉爽,湿度高,风速高,预测他是否会踢足球)
计算过程
假设小明15号去踢球,踢球概率为:
P(踢)=9/14
P(晴天|踢)=2/9
P(凉爽|踢)=3/9
P(湿度高|踢)=3/9
P(风速高|踢)=3/9
P(踢)由踢的天数除以总天数得到,P(晴天|踢)为踢球的同事是晴天除以踢的天数得到,其他以此类推。
P(踢|晴天,凉爽,湿度高,风速高)=
P(踢)* P(晴天|踢)* P(凉爽|踢)* P(湿度高|踢) *P(风速高|踢)=
9/14*2/9*3/9*3/9*3/9=0.00529
假设小明15号不去踢球,概率为:
P(不踢)=5/14
P(晴天|不踢)=3/5
P(凉爽|不踢)=1/5
P(湿度高|不踢)=4/5
P(风速高|不踢)=3/5
P(不踢|晴天,凉爽,湿度高,风速高)=
P(不踢)* P(晴天|不踢)* P(凉爽|不踢)* P(湿度高|不踢) *P(风速高|不踢)=
5/14*3/5*1/5*4/5*3/5=0.02057
可以看到小明不去踢足球的概率比去踢足球的概率高。
4.流程图
5.spark 中实现
F:/download/MLlib机器学习/数据/sample_libsvm_naive_bayes.txt 中内容为:
0 1:1 2:2 3:1
1 1:2 2:2 3:1
0 1:2 2:1 3:3
1 1:1 2:2 3:2
2 1:1 2:3 3:1
2 1:2 2:3 3:2
1 1:4 2:4 3:3
3 1:2 2:1 3:2
1 1:4 2:1 3:2
1 1:5 2:2 3:2
2 1:4 2:1 3:1
2 1:5 2:4 3:2
3 1:4 2:5 3:2
object NaiveBayesExample {
def main(args: Array[String]): Unit = {
System.setProperty("hadoop.home.dir", "E:\\hadoop-2.6.0-cdh5.8.5")
val conf = new SparkConf().setMaster("local").setAppName("NaiveBayes")
val spark = SparkSession.builder().config(conf).getOrCreate()
spark.sparkContext.setCheckpointDir("hdfs://xxxxx:9000/user/zhy/spark/wd_checkpoint")
Logger.getRootLogger.setLevel(Level.WARN)
// $example on$
// Load the data stored in LIBSVM format as a DataFrame.
val data = spark.read.format("libsvm").load("file:///F:/download/MLlib机器学习/数据/sample_libsvm_naive_bayes.txt")
val indexer = new VectorIndexer()
.setInputCol("features")
.setOutputCol("indexed")
.setMaxCategories(6)
// Split the data into training and test sets (30% held out for testing)
val Array(trainingData, testData) = data.randomSplit(Array(0.7, 0.3), seed = 1234L)
// Train a NaiveBayes model.
val naiveBayes = new NaiveBayes()
//.fit(trainingData)
val pipeline = new Pipeline()
.setStages(Array(indexer, naiveBayes))
val model = pipeline.fit(trainingData)
println("--------original data----------")
data.show()
println("-------test data-----")
testData.show()
// Select example rows to display.
val predictions = model.transform(testData)
predictions.show()
println("rawPrediction:")
predictions.select("rawPrediction").foreach(row => {
println(row)
})
println("features:")
predictions.select("features").foreach(row => {
println(row)
})
println("probability:")
predictions.select("probability").foreach(row => {
println(row)
})
// Select (prediction, true label) and compute test error
val evaluator = new MulticlassClassificationEvaluator()
.setLabelCol("label")
.setPredictionCol("prediction")
.setMetricName("accuracy")
val accuracy = evaluator.evaluate(predictions)
println(s"Test set accuracy = $accuracy")
// $example off$
spark.stop()
}
}