1.召回率和正确率计算
对于一个
从上图所示的结果中不同的元素表示的含义如下:
对于所有的
那么召回率的计算公式如下:
其中:
2 随机森林中召回率和正确率的计算
import org.apache.log4j.{Level, Logger}
import org.apache.spark.mllib.evaluation.MulticlassMetrics
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.tree.RandomForest
import org.apache.spark.mllib.tree.model.RandomForestModel
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.rdd.RDD
/**
* Created by august on 17-6-1.
*/
object Main {
var beg = System.currentTimeMillis()
//设置日志文件为错误显示
Logger.getLogger("org").setLevel(Level.ERROR)
//设置application名称,并创建入口对象
val conf = new SparkConf().setAppName("rf")
val sc = new SparkContext(conf)
//加载hadoop中的数据信息,这里将IP地址信息隐去
val data = MLUtils.loadLibSVMFile(sc,"hdfs://***.***.***.***:8020/august/random_forest/Day2.txt")
// 将数据信息划分为70%的测试集和30%的训练集
val splits = data.randomSplit(Array(0.7, 0.3))
val (trainingData, testData) = (splits(0), splits(1))
//将数据一共分成12个类
val numClasses = 13
val categoricalFeaturesInfo = Map[Int, Int]()
val numTrees = 100
val featureSubsetStrategy = "auto" // Let the algorithm choose.
val impurity = "entropy"
val maxDepth = 10
val maxBins = 32
val model = RandomForest.trainClassifier(trainingData, numClasses, categoricalFeaturesInfo,
numTrees, featureSubsetStrategy, impurity, maxDepth, maxBins)
val metrics = getMetrics(model,testData)
//计算精确度(样本比例)
val precision = metrics.accuracy;
//计算每个样本的准确度(召回率)
val recall = (1 to 11).map( //DecisionTreeModel模型的类别号从1开始
cat => (metrics.precision(cat), metrics.recall(cat))
)
val end = System.currentTimeMillis()
//耗时时间
var castTime = end - beg
def main(args: Array[String]) {
println("========================================================================================")
//精确度(样本比例)
println("精确度: " + precision)
println("========================================================================================")
//准确度(召回率)
println("准确度: ")
recall.foreach(println)
println("========================================================================================")
println(" 运行程序耗时: " + castTime/1000 + "s")
}
def getMetrics(model: RandomForestModel, data: RDD[LabeledPoint]): MulticlassMetrics = {
val predictionsAndLabels = data.map(example => (model.predict(example.features), example.label))
new MulticlassMetrics(predictionsAndLabels)
}
}
在上述代码中,实现了对于随机森林分类后的结果计算召回率和每一个类的准确率。
2.1 数据获取并生成训练集和测试集
在下述代码中我们主要进行了以下工作:
(1)设置spark日志输出信息为Level.ERROR,在错误状态下输出日志信息。
(2)设置Application的入口对象。
(3)从Hadoop中获取数据信息,值的注意的是这里的数据信息的数据格式为libsvm格式,从一般数据格式转换到libsvm格式的转换方式可以参考另一篇文章。
(4)将所有的数据信息划分为traingingData训练集和testData测试集,其中trainingData占数据集中的70%,testData占30%。
Logger.getLogger("org").setLevel(Level.ERROR)
val conf = new SparkConf().setAppName("rf")
val sc = new SparkContext(conf)
val data = MLUtils.loadLibSVMFile(sc, "hdfs://***.***.***.***:8020/august/random_forest/Day2.txt")
val splits = data.randomSplit(Array(0.7, 0.3))
val (trainingData, testData) = (splits(0), splits(1))
2.2 设置随机森林参数并训练模型
在RandomForest.trainClassifier中对随机森林模型进行训练,将训练后模型的结果返回到model里面。在训练随机森林模型前对参数的设置如下:
numClasses:表示一共分为多少个类。
categoricalFeaturesInfo:为空,表示所有的特征为连续型变量
numTrees:表示随机森林里面包含的决策树的个数
featureSubsetStrategy:表示特征子集的选取方式。
impurity:“entropy”表示纯度的计算方式采用信息熵的方式计算。
maxDepth:表示数的最大深度为10
maxBins:表示最大装箱数为32
val numClasses = 13
val categoricalFeaturesInfo = Map[Int, Int]()
val numTrees = 100
val featureSubsetStrategy = "auto" // Let the algorithm choose.
val impurity = "entropy"
val maxDepth = 10
val maxBins = 32
val model = RandomForest.trainClassifier(trainingData, numClasses, categoricalFeaturesInfo,
numTrees, featureSubsetStrategy, impurity, maxDepth, maxBins)
2.3 计算正确率和召回率
函数功能:在Spark API中给出的MulticlassMetrics文档显示,建立一个MulticlassMetrics使用RDD作为参数传入,在RDD中是保存了一个两个Double类型的数据,其中第一个表示预测的结果,第二个表示标签的结果。
传入参数:model: RandomForestModel, data: RDD[LabeledPoint]其中model表示训练出来的随机森林模型,data用来表示测试数据集合。
返回结果:返回一个MulticlassMetrics的实例对象,用来计算整个数据集合的准确度和不同类的准确度。
def getMetrics(model: RandomForestModel, data: RDD[LabeledPoint]): MulticlassMetrics = {
val predictionsAndLabels = data.map(example => (model.predict(example.features), example.label))
new MulticlassMetrics(predictionsAndLabels)
}
在下述的代码中,我们通过对每一个类求出precision的值recall的值存放在recall中。
val metrics = getMetrics(model,testData)
//计算精确度(样本比例)
val precision = metrics.accuracy;
//计算每个样本的准确度(召回率)
val recall = (1 to 11).map( //DecisionTreeModel模型的类别号从0开始
cat => (metrics.precision(cat), metrics.recall(cat))
)
3. 实验结果
我们通过下述代码输出实验结果。
def main(args: Array[String]) {
println("========================================================================")
//精确度(样本比例)
println("精确度: " + precision)
println("========================================================================")
//准确度(召回率)
println("准确度: ")
recall.foreach(println)
println("========================================================================")
println(" 运行程序耗时: " + castTime/1000 + "s")
}
运行程序得到的实验结果如下图所示。