在Colorado北部,有一片森林,森林里中有多种类型的植被,有人已经将其大概总结出来了7种:
1 - Spruce/Fir
2 - Lodgepole Pine
3 - Ponderosa Pine
4 - Cottonwood/Willow
5 - Aspen
6 - Douglas-fir
7 - Krummholz
如果将它们的特征划,可以划分成12种,在这12中类型中,其中两种特征又可以划分成4和40中,这样可以任务这些植被有54中类型。现在有人已经根据样本的特性手动划分了植被类型一部分,现在需要自动识别未划分的植被类型。
(1)本文将基于随机森林算法在spark的集群上做模型系数的优化,来识别不同的植被类型。
1.1 数据的预处理:
在其给出的数据中存在54中数据类型如图:
很显然,这些特征属于类别型特征,其中比较特殊是wilderness_area和soil_type,它们是one-hot类型,有4和40个特征值。
val data=sparkSession.sparkContext.textFile(fileName).map(_.split(",").map(_.toDouble)).map(lin=>{
LabeledPoint(line.last-1,Vectors.dense(line.init))
})
val Array(trainData,cvData,testData)=data.randomSplit(Array(0.8,0.1,0.1));
这里我们用80%做训练集,10%做校验,10%做测试。
(2)建立模型和调节参数;
随机森林的模型val model=RandomForest.trainClassifier(trainData,numclass,map,numTrees,"auto",inpurity,maxDepth,maxBin)
说明:trainData:训练数据,LabeledPoint类型
numclass:分类数量
map(k->v) 类别k是v的特征
numTrees:建立数的棵树
auto:评估特征选择策略
inpuity:采用哪种信息纯度计算方式
maxDepth:数的最大深度
maxbin:数的最大同数
好了,下面来确定参数,参数确定当然是根据预测的准确度、召回率、错误率、、、
这里spark中有一个类MulticlassMetrics来帮我们计算,这样我们就不用自己写了。这个类有个方法accuracy就等到了准确率,调节参数过程如下:
val evaluations=for(numtrees<- 1 to 20;depth<- 20 to 30;bins<-2- to 300;inpuity<-Array("gini","entropy"))yield {
val model=RandomForest.trainClassifier(trainData,7,Map(10->4,11->40),numtrees,"auto",inpuity,depth,bins);
val trainAccuracy=desionTree3.getForestMetra(model,cvData).accuracy;
(inpuity,depth,bins,trainAccuracy)
}
evaluations.sortBy(_._4).reverse.take(10).foreach(println)
}
最后的结果:
显然当深度取30,桶数取40时,准确率最高达到93.9%