1. 程式人生 > >機器學習演算法之隨機森林(1)pyspark.mllib中的RF

機器學習演算法之隨機森林(1)pyspark.mllib中的RF

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)對部分特徵缺失不敏感。