贝叶斯定理解决了在已知P(y),P(x),P(x|y)的情况下求P(y|x)
贝叶斯定理:
P(y|x) = P(x|y)*P(Y)/P(x)
P(y|x) = P(x|y)*P(Y)/P(x)
P(y|x) = P(x|y)*P(Y)/P(x)
朴素贝叶斯分类:
1.从待训练样本逐个求出P(x)、P(y)、P(x|y)对应的概率
2.根据贝叶斯定理来对待预测样本进行预测P(y|x) = P(x|y)*P(Y)/P(x)=(P(x1|y)*P(Y) * P(x2|y)*P(Y) * ... * P(xn|y)*P(Y))/P(x)
问题:若2对应的某项P(xn|y)*P(Y)的值为0,那么连乘后会导致P(y|x)的值为0。因此会有可能加入平滑因子,使分子不为0,即在分子和分母都加入值。
3.可能会出现相同P(xn-1|y)和P(xn|y)中xn-1和xn相同,那么会出现是计算一次还是计算两次的问题。
因此有了多项式模型和伯努力模型。
多项式模型中相同的计算多次,分母也是多次计算相同值。
伯努力模型中只计算一次,分母中多次出现只算一次。
测试数据集:链接: https://pan.baidu.com/s/1jKmYoce 密码: 3fdv
代码:
import org.apache.spark.mllib.classification.NaiveBayes import org.apache.spark.mllib.linalg.{Vector, Vectors} import org.apache.spark.mllib.regression.LabeledPoint import org.apache.spark.sql.SparkSession /** * Created by root on 1/15/18. */ object NaiveBayesTest { def main(args: Array[String]): Unit = { val spark = SparkSession.builder().appName("NaiveBayesTest").master("local[*]").getOrCreate() val path = "file:/home/enche/data/sample_naive_bayes_data.txt" val sc = spark.sparkContext val data = sc.textFile(path) //转成Rdd[LabeledPoint] val labelPoints = data.map{ line=> val parts = line.split(",") LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(" ").map(_.toDouble))) } //70%数据用于训练,30%数据用于检测 val splits = labelPoints.randomSplit(Array(0.7, 0.3, 1L)) //朴素贝叶斯进行训练,lambda表示平滑因子取值,modelType表示的是多项式模型还是伯努力模型 val model = NaiveBayes.train(input = splits(0),lambda = 1.0, modelType = "multinomial") val vectors = splits(1).map{ case (l : LabeledPoint)=> l.features } val labels = splits(1).map{ case (l : LabeledPoint)=> l.label } val predicts = model.predict(vectors) labels.zip(predicts).foreach(println) } }