spark的persist操作可以使得数据常驻内存,而机器学习最主要的工作——迭代,需要频繁地存取数据,这样相比hadoop来说,天然地有利于机器学习。
———- 单机版。 至于集群的搭建——现在手头最多两台电脑,后面再折腾。
1、安装pysaprk
1.1 下载安装包
下载jdk压缩包,进入链接
http://www.oracle.com/technetwork/java/javase/downloads/index.html,下载最新版jdk,下载完成后解压到当前目录下。
下载spark压缩包,进入链接https://spark.apache.org/downloads.html。
1.2 移动至指定目录
执行 mv jdk1.8.0_131 /opt/jdk1.8.0_131
执行 mv spark-1.6.2-bin-hadoop2.6 /opt/spark-hadoop
1.3 修改环境变量
配置环境变量,编辑/etc/profile,执行以下命令
sudo gedit /etc/profile
在文件最下方增加(注意版本):
#Seeting JDK JDK环境变量
export JAVA_HOME=/opt/jdk1.8.0_131
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:$PATH #setting Spark Spark环境变量
export SPARK_HOME=/opt/spark-hadoop/
#PythonPath 将Spark中的pySpark模块增加的Python环境中
export PYTHONPATH=/opt/spark-hadoop/python
打开命令窗口,执行 source /etc/profile
在当前窗口生效 完成后cd到spark-hadoop目录,执行./bin/pyspark。
即安装成功。
1.4 python3.5下运行
因为另一台电脑已经配置好了python3.5的环境,所以为了搭建集群,所以想转成python3.5。
但是本机之前已经安装过了anaconda3,里面的python是3.6。如果使用python3.6,在导入pyspark包的时候会报错,因为spark dosenot work with python3.6,一次一次又一次被这种问题伤害,真是naive,以后不能再犯了。。。
幸运的是,之前折腾tensorflow的时候,因为tensorflow同样的是不兼容3.6,我已经在anaconda上设置了一个python3.5的环境,真是天无绝人之路啊。 所以还是提前把各个库的兼容问题看一下,省得做无用功。 ———-
2、随机森林
2.1 RF概念
首先,简单介绍一下随机森林: 由多个决策树构成的森林,算法分类结果由这些决策树投票得到。 其本质是基于决策树的bagging算法。
2.2 特征选择
决策树在生成的过程当中分别在行方向和列方向上添加随机过程,行方向上构建决策树时采用放回抽样(bootstraping)得到训练数据,列方向上采用无放回随机抽样得到特征子集,并据此得到其最优切分点,除此之外,所有的决策树的训练都是同样的。
2.3 分割点
最好的分割点是通过量化分割后类的纯度来确定的,目前有三种纯度计算方式,分别是 Gini 不纯度、熵(Entropy)及错误率。
2.4预测
对新加的数据进行预测,随机森林需要将所有的决策树的结果进行聚合,根据分类和回归的不同也不同:
2.4.1 分类
分类采用的就是投票机制,每个决策树都会有一个分类的结果,根据得票最多,就是哪类。
2.4.2 回归
每个回归树都预测得到一个值,对所有的树的结果取平均。
3、数据准备
LIBSVM Data: Classification, Regression, and Multi-label 数据来源于台湾大学的LIBSVM。 同时,在spark目录中\spark-1.6.0-bin-hadoop2.6\data\mllib文件夹中有准备好的数据集。
4、源码 首先导入相关的模块,初始化spark环境
from pyspark import SparkContext,SparkConf
conf = SparkConf().setAppName('RF').setMaster('local')
sc = SparkContext(conf=conf)
from pyspark.mllib.tree import RandomForest, RandomForestModel
from pyspark.mllib.util import MLUtils
导入数据,data最终成为了RDD类型
>>>data = MLUtils.loadLibSVMFile(sc,'data/mllib/sample_libsvm_data.txt')
>>>data PythonRDD[4] at RDD at PythonRDD.scala:43
#划分训练集和测试集
>>>(trainingData, testData) = data.randomSplit([0.7, 0.3])
训练模型
以提高算法效果的有两个参数:numTrees,maxDepth。
numTrees(决策树的个数):决策树的个数越多,结果的方差越小,越能对抗过拟合,同时,训练的时间也随着个数增加而增加。
maxDepth:是指森林中每一棵决策树最大深度。更深的一棵树意味模型更倾向于过拟合。
由于随机森林有效对抗过拟合,所以一般树的深度可以很大。
最后,特征选择个数也是非常关键的参数,特征越多,树的相关性和分类能力就越强。
model = RandomForest.trainClassifier(trainingData, numClasses=2, categoricalFeaturesInfo={},numTrees=3, featureSubsetStrategy="auto",impurity='gini', maxDepth=4, maxBins=32)
结果
predictions = model.predict(testData.map(lambda x: x.features))
labelsAndPredictions = testData.map(lambda lp: lp.label).zip(predictions)
testErr = labelsAndPredictions.filter(lambda (v, p): v != p).count() / float(testData.count())
print('Test Error = ' + str(testErr))
print('Learned classification forest model:') print(model.toDebugString())
# Save and load model
model.save(sc,"target/tmp/myRandomForestClassificationModel")
sameModel = RandomForestModel.load(sc, "target/tmp/myRandomForestClassificationModel")
5、随机森林优缺点
(1)bagging,高度并行化,适用于大数据。
(2)可以处理维度非常高的数据。
(3)双重随机采样,保证了训练模型的泛化能力强,投票机制对抗过拟合。
(4)对部分特征缺失不敏感。