Spark隨機森林演算法對資料分類(一)——計算準確率和召回率
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")
}
執行程式得到的實驗結果如下圖所示。