盒子
盒子

随机森林的两种语言实现

##随机森林

随机森林是一个高度灵活的机器学习方法,随机森林是一个可做能够回归分类。 它具备处理大数据的特性,而且它有助于估计或变量是非常重要的基础数据建模。

随机森林其实是集成学习的一个子类,依靠于决策树的合并。

本文给出决策树的两种实现python和spark平台的scala语言实现。

###1. python实现

这里使用的数据集是来自uci的Forest Cover类型数据,数据量算是大的了,大概有58万个样本。

直接先上代码:

import pandas as pd
from sklearn.cross_validation import train_test_split

covdata = pd.read_csv('D:/covtype.csv')

print(covdata.groupby('Cover_Type').count())
target = covdata.Cover_Type.values
features = covdata.get(['Elevation','Aspect','Slope ','Horizontal_Distance_To_Hydrology','Vertical_Distance_To_Hydrology','Horizontal_Distance_To_Roadway','Hillshade_9am','Hillshade_Noon','Hillshade_3pm','Horizontal_Distance_To_Fire_Points','w1','w2','w3','w4','s1','s2','s3','s4','s5','s6','s7','s8','s9','s10','s11','s12','s13','s14','s15','s16','s17','s18','s19','s20','s21','s22','s23','s24','s25','s26','s27','s28','s29','s30','s31','s32','s33','s34','s35','s36','s37','s38','s39','s40'])
features_train, features_test, target_train, target_test = train_test_split(
   features, target, test_size=0.20, random_state=0)

from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_jobs=3,n_estimators=30,max_features=7)
clf.fit(features_train, target_train)
target_predicted = clf.predict(features_test)

from sklearn.metrics import accuracy_score
score = accuracy_score(target_test, target_predicted)
print('the score is :' ,score)

输出结果:

            Elevation  Aspect  Slope   Horizontal_Distance_To_Hydrology  \
Cover_Type                                                                
1              211840  211840  211840                            211840   
2              283301  283301  283301                            283301   
3               35754   35754   35754                             35754   
4                2747    2747    2747                              2747   
5                9493    9493    9493                              9493   
6               17367   17367   17367                             17367   
7               20510   20510   20510                             20510   

            Vertical_Distance_To_Hydrology  Horizontal_Distance_To_Roadway  \
Cover_Type                                                                   
1                                   211840                          211840   
2                                   283301                          283301   
3                                    35754                           35754   
4                                     2747                            2747   
5                                     9493                            9493   
6                                    17367                           17367   
7                                    20510                           20510   

            Hillshade_9am  Hillshade_Noon  Hillshade_3pm  \
Cover_Type                                                 
1                  211840          211840         211840   
2                  283301          283301         283301   
3                   35754           35754          35754   
4                    2747            2747           2747   
5                    9493            9493           9493   
6                   17367           17367          17367   
7                   20510           20510          20510   

            Horizontal_Distance_To_Fire_Points   ...       s31     s32  \
Cover_Type                                       ...                     
1                                       211840   ...    211840  211840   
2                                       283301   ...    283301  283301   
3                                        35754   ...     35754   35754   
4                                         2747   ...      2747    2747   
5                                         9493   ...      9493    9493   
6                                        17367   ...     17367   17367   
7                                        20510   ...     20510   20510   

               s33     s34     s35     s36     s37     s38     s39     s40  
Cover_Type                                                                  
1           211840  211840  211840  211840  211840  211840  211840  211840  
2           283301  283301  283301  283301  283301  283301  283301  283301  
3            35754   35754   35754   35754   35754   35754   35754   35754  
4             2747    2747    2747    2747    2747    2747    2747    2747  
5             9493    9493    9493    9493    9493    9493    9493    9493  
6            17367   17367   17367   17367   17367   17367   17367   17367  
7            20510   20510   20510   20510   20510   20510   20510   20510  

[7 rows x 54 columns]

the score is : 0.953486570915

这里还可以使用grid search来进行参数寻优。而随机森林有两个重要参数:n-estimators和 max-features ,前者 n-estimators是森林中树的数目,一般来说,数字越大,模型表现越好,但同时花费的时间也越多。后者max-features是分裂特征的随机子集时要考虑分裂结点的大小,值越小方差减少得越多。偏差增长的也越大,从经验来说max-features = n-features适合做回归问题,max-features=sqrt(n-features)适合做分类问题,(n-feartures是数据特征的个数)。

python专门有个包scikit是为机器学习的,而且有个好处就是,很多机器学习算法使用时几乎是一套模板,比如要将决策树换成逻辑斯谛回归来进行分类,那么只需将里面的函数名改下就行了。这里随机森林也有这样的Scikit学习文档

顺便给个各个分类算法的比较,很强大http://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html

###2. spark的scala实现

Spark基于map reduce算法实现的分布式计算,拥有Hadoop MapReduce所具有的优点;但不同于MapReduce的是Job中间输出和结果可以保存在内存中,从而不再需要读写HDFS,因此Spark能更好地适用于数据挖掘与机器学习等需要迭代的map reduce的算法。它有专门的MLlib,来进行机器学习,其实spark只提供了计算模式,数据的存储方面还是得依靠hdfs等一些集群。还有就是Spark的RDD在迭代式处理方式一直是津津乐道的。

这个数据集代码位于github

这里使用了本地单线程模式来实现随机森林的算法,由于内存的限制,把数据集缩小了之后,测试集准确率为0.8764160659114315,同样的数据集在python上是0.880559085133。相差不大。使用本地单线程时注意要用如下代码设置运行环境:

val conf = new SparkConf().setMaster("local").setAppName("RDF")
val sc = new SparkContext("local","RDF")