贝叶斯分类是一类分类算法的总称,这类算法以贝叶斯定理为基础。此次介绍的是贝叶斯分类中最简单,最常见的朴素贝叶斯分类。
算法简介
朴素贝叶斯分类的思想基础是:对于给出的待分类项,求解此项在出现的条件下各类别的概率,哪个最大,就认为此项属于哪个类别。总结起来就是如下公式:
分类流程
x特征属性(,) | 训练样本() | 准备阶段 |
计算每个类别的先验概率 |
|
训练阶段 |
计算各类别下各特征属性的条件概率 |
| |
计算样本属于每个类别的概率 |
|
预测阶段 |
取最大项作为x的类别 |
运行步骤
数据说明
数据格式为:类别,特征1 特征2 特征3
0,1 0 0
0,2 0 0
0,3 0 0
0,4 0 0
1,0 1 0
1,0 2 0
1,0 3 0
1,0 4 0
2,0 0 1
2,0 0 2
2,0 0 3
2,0 0 4
该算法对数据格式有严格要求,必须是RDD[LabeledPoint],其中LabeledPoint格式为(label,features),若对此格式不明白请自行百度。
代码及说明
import org.apache.spark.mllib.classification.{ NaiveBayes, NaiveBayesModel}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.log4j.{Level, Logger}
object naiveBayes {
def main(args: Array[String]): Unit = {
//创建spark对象
val conf=new SparkConf().setAppName("naiveBayes")
val sc=new SparkContext(conf)
//设置日志输出级别
Logger.getRootLogger.setLevel(Level.WARN)
//读取样本数据
val data = sc.textFile("/home/hyk/test/naiveBayes/sample_naive_bayes_data.txt")
//将数据转化为LabelPoint(label,features)格式
val parsedData =data.map{line=>
val parts=line.split(",")
LabeledPoint(parts(0).toDouble,Vectors.dense(parts(1).split(" ").map(_.toDouble)))
}
//将样本数据划分为训练样本和测试样本
val splits=parsedData.randomSplit(Array(0.6,0.4), seed =11L)
val training =splits(0)
val test=splits(1)
//建立贝叶斯分类模型,并训练
val model=NaiveBayes.train(training,lambda=1.0,modelType="multinomial")
//对测试样本进行测试
val predictionAndLabel=test.map(p =>(model.predict(p.features),p.label))
val print_predict=predictionAndLabel.take(20)
//打印结果 (prediction label)
for (i<- 0 to print_predict.length - 1)
{
println(print_predict(i)._1 + "\t" + print_predict(i)._2)
}
//贝叶斯分类精度
val accuracy =1.0 * predictionAndLabel.filter(x => x._1 == x._2).count() / test.count()
println("accuracy:" + accuracy)
//保存模型
val ModelPath="/home/hyk/naive_bayes_model"
model.save(sc,ModelPath)
}
}
结果展示
前者是预测结果,后者是数据真实标签。