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")
}
運行程序得到的實驗結果如下圖所示。