一,算法简介
随机森林是决策树的集成算法。随机森林包含多个决策树来降低过拟合的风险。随机森林同样具有易解释性、可处理类别特征、易扩展到多分类问题、不需特征缩放等性质。随机森林分别训练一系列的决策树,所以训练过程是并行的。因算法中加入随机过程,所以每个决策树又有少量区别。通过合并每个树的预测结果来减少预测的方差,提高在测试集上的性能表现。
二.代码逐行讲解
1.操作数据
操作数据采用官网样例数据,sample_libsvm_data.txt,找不到的小伙伴可以去链接:【https://pan.baidu.com/s/1N-03piaEv9-KyrqNjnSyNA 密码:nqv7 】下载,数据格式:
------------------------------------------------------------------------------
label(分类标签 0/1) features(特征值的位置:特征值)
0 128:51 129:159 130:253 131:159 132:50 155:48 156:238 157:252 158:252 159:252 160:237
1 159:124 160:253 161:255 162:63 186:96 187:244 188:251 189:253 190:62 214:127 215:251
---------------------------------------------------------------------------------
以第一条数据为例,标签为0 => (128位置对应的特征值=>51,129位置对应的特征值=>159。。。)
2.实例代码以及注释
1.创建DataFrame读取数据
val spark:SparkSession = .........
val data =spark.read.format("libsvm").load(dataPath) //返回是一个DataFrame对象
方便理解show一下(图1)
ps:
label ===> 为读取的标签
features ===> 692代表特征向量的个数,第一个中括号是特征向量的位置,第二个中括号是特征向量值。 (特征个数,【特征值位置】,【特征值】)
2. 整理标签和特征向量
2.1 StringIndexer函数
val labelStringIndexer = new StringIndexer()
.setInputCol("label")
.setOutputCol("indexerLabel")
.fit(data)
作用 : 整理字符串类型字段转化为标签索引,数量即为不重复标签种类,从0开始计数,到最大数量为止,顺序为数量多的在前,举个例子:
0 特征向量_1
1 特征向量_2
2 特征向量_3
1 特征向量_4
2 特征向量_5
2 特征向量_6
2 特征向量_7
一共有三种标签(0,1,2) 分别对应的数量(1,2,4) 得出 = > (2,1,0)
几个参数
.setInputCol("label") : 指定dataFrame中的转换字段
setOutputCol("indexerLabel") : 设置输出的字段名
setHandleInvalid("skip") : 如果测试样本中存在训练样本中没有的标签,默认处理方式是报错,添加此参数,即表示忽略该标签,不会报错。
------------------------------------------
2.2 VectorIndexer() 函数
val featuresVectorIndexer =new VectorIndexer()
.setInputCol("features").setOutputCol("indexerFeature")
.setMaxCategories(4)
.fit(data)
作用 : 封装整理特征向量
几个参数
.setInputCol("features").setOutputCol("indexerFeature") //输入输出字段名称
.setMaxCategories(4) // 同一特征向量不重复超过4个值,即被视为连续值。
setHandleInvalid("skip") //效果同上
3. 切分训练数据和测试数据
val Array(trainingData, testData) = data.randomSplit(Array(0.6, 0.4))
将数据切分为两部分 trainingData(训练数据集) ,testData(测试数据集合)
4. 创建随机森林估计器
val rf =new RandomForestClassifier()
.setLabelCol("indexerLabel")
.setFeaturesCol("indexerFeature")
.setNumTrees(10)//10个决策树
5. 创建标签复原转化器
val labelConverter =new IndexToString()
.setInputCol("prediction")
.setOutputCol("predictionLabel")
.setLabels(labelStringIndexer.labels)
作用 : 前面我们为了方便计算把标签进行了转换,预测之后我们要把标签翻转回原来的格式。
6.创建pipeline管道
val pipeline =new Pipeline()
.setStages(
Array(
labelStringIndexer, //标签转换
featuresVectorIndexer, //特征向量转换
rf, //估计器---随机森林
labelConverter//标签反转
))
7.建立模型并通过模型对测试数据进行分类
val model = pipeline.fit(trainingData) // 通过管道训练模型
val forecastResult = model.transform(testData) // 对测试数据进行预测
8.对结果准确性进行校验
val evaluator =new MulticlassClassificationEvaluator()
.setLabelCol("indexerLabel")//真实值
.setPredictionCol("prediction")//预测值
.setMetricName("accuracy") //准确度检查
// 评估指标的类型(accuracy:准确度,预测正确个数/预测失败的个数)
// 默认值为 F1 : F1-Measure(精准率和召回率)
val accuracy:Double = evaluator.evaluate(forecastResult) // 返回正确率
3.完整代码
import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.classification.RandomForestClassifier
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator
import org.apache.spark.ml.feature.{IndexToString, StringIndexer, VectorIndexer}
val dataPath ="sample_libsvm_data.txt"
val data =ss.read.format("libsvm").load(dataPath)
val labelStringIndexer =new StringIndexer()
.setInputCol("label")
.setOutputCol("indexerLabel")
.fit(data)
val featuresVectorIndexer =new VectorIndexer()
.setInputCol("features").setOutputCol("indexerFeature")
.setMaxCategories(4)// 同一特征向量不重复超过4个值,即被视为连续值。
.fit(data)
// 数据切割
val Array(trainingData, testData) = data.randomSplit(Array(0.6, 0.4))
//创建随机森林
val rf =new RandomForestClassifier()
.setLabelCol("indexerLabel")
.setFeaturesCol("indexerFeature")
.setNumTrees(10)//10个决策树
val labelConverter =new IndexToString()
.setInputCol("prediction")
.setOutputCol("predictionLabel")
.setLabels(labelStringIndexer.labels)
val pipeline =new Pipeline()
.setStages(Array(labelStringIndexer, featuresVectorIndexer, rf, labelConverter))
val model = pipeline.fit(trainingData)
val forecastResult = model.transform(testData)
// forecastResult.show()
val evaluator =new MulticlassClassificationEvaluator()
.setLabelCol("indexerLabel")//真实值
.setPredictionCol("prediction")//预测值
// 评估指标的类型(accuracy:准确度,预测正确个数/预测失败的个数) 默认值为 F1 : F1-Measure(
.setMetricName("accuracy")
val accuracy:Double = evaluator.evaluate(forecastResult)
println(s"预测错误率:${(1 - accuracy) *100} % ")
ss.stop()