1. 程式人生 > >基於Ubuntu16.04+Spark+Python的線性迴歸(linear regression)演算法

基於Ubuntu16.04+Spark+Python的線性迴歸(linear regression)演算法

參考:

spark+python+ubuntu環境配置:

https://blog.csdn.net/konglingshneg/article/details/82491157

Building A Linear Regression with PySpark and MLlib:

https://towardsdatascience.com/building-a-linear-regression-with-pyspark-and-mllib-d065c3ba246a

目錄

1.Ubuntu16.04+Spark+Python環境配置

安裝JDK1.8:

安裝spark :

2.利用Linear Regression預測Boston房價


1.Ubuntu16.04+Spark+Python環境配置

Spark是一個可以應用於大規模資料處理的快速通用引擎。是當今大資料領域最熱門的大資料計算平臺。Spark開發應用程式時可以採用Scala、Python、Java和R語言。在虛擬機器下的Ubuntu環境下安裝測試Spark,即使出錯也不會影響其他。

安裝JDK1.8:

Spark的執行環境依賴JVM環境,

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

下載jdk-8u191-linux-x64.tar.gz

(1)在/usr/lib下新建一個資料夾 sudo mkdir /usr/lib/jdk

[email protected]:~$ sudo mkdir /usr/lib/jdk

(2)系統預設下載到download資料夾(找到copy一下地址),cd 到下載檔案資料夾

[email protected]:~$ cd /home/zhb/Downloads/
[email protected]:~/Downloads$

(3)解壓縮到我們新建的資料夾 sudo tar -zxvf jdk-8u191-linux-x64.tar.gz -C /usr/lib/jdk

[email protected]:~/Downloads$ sudo tar -zxvf jdk-8u191-linux-x64.tar.gz -C /usr/lib/jdk

(4)配置PATH路徑,讓jdk命令在任何路徑下都能夠直接執行, gedit、vi都可以。 sudo gedit /etc/profile

[email protected]:~$ gedit /etc/proflie

在配置檔案末尾追加 

# java
export JAVA_HOME=/usr/lib/jdk/jdk1.8.0_191  
export JRE_HOME=${JAVA_HOME}/jre  
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib  
export PATH=${JAVA_HOME}/bin:$PATH

(5)重新載入/etc/profile配置檔案 source /etc/proflie

[email protected]:~$ source /etc/profile

(6)執行java -version檢視java是否安裝成功,出現如下結果說明安裝成功 

[email protected]:~$ java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
[email protected]:~$

安裝spark :

(1)官網下載地址 http://spark.apache.org/downloads.html 

          Download Spark: spark-2.4.0-bin-hadoop2.7.tgz

(2)為spark新建一個資料夾sudo mkdir /usr/lib/spark

[email protected]:~$ sudo mkdir /usr/lib/spark

(3)找到下載檔案目錄,並cd到該目錄下

[email protected]:~$ cd /home/zhb/Downloads/
[email protected]:~/Downloads$

(4)將下載檔案安裝到新建資料夾下sudo tar -zxvf spark-2.4.0-bin-hadoop2.7.tgz -C /usr/lib/spark

[email protected]:~/Downloads$ sudo tar -zxvf spark-2.4.0-bin-hadoop2.7.tgz -C /usr/lib/spark

(5)配置spark

cd /usr/lib/spark/spark-2.4.0-bin-hadoop2.7/conf/ 

sudo cp spark-env.sh.template spark-env.sh 

sudo gedit spark-env.sh

[email protected]:~$ cd /usr/lib/spark/spark-2.4.0-bin-hadoop2.7/conf/
[email protected]:/usr/lib/spark/spark-2.4.0-bin-hadoop2.7/conf$ sudo cp spark-env.sh.template spark-env.sh
[email protected]:/usr/lib/spark/spark-2.4.0-bin-hadoop2.7/conf$ sudo gedit spark-env.sh

在spark-env.sh檔案末尾追加:

JAVA_HOME=/usr/lib/jdk/jdk1.8.0_191  
SPARK_WORKER_MEMORY=3g

(6)然後我們需要配置PATH路徑,讓jdk命令在任何路徑下都能夠直接執行

sudo gedit /etc/profile
[email protected]:~$ sudo gedit /etc/profile

在配置檔案後加上

#spark 
export SPARK_HOME=/usr/lib/spark/spark-2.4.0-bin-hadoop2.7
export PATH=${SPARK_HOME}/bin:$PATH

(7)重新載入/etc/profile配置檔案

source /etc/profile
[email protected]:~$ source /etc/proflie

(8)執行 pyspark 檢視spark是否安裝成功,出現如下結果說明安裝成功

 

2.利用Linear Regression預測Boston房價

(1)在jupyter notebook使用spark時,通過findspark來呼叫spark。

切換到自己的python環境下,執行:

pip install findspark

 使用anaconda開啟jupyter notebook,在文件開頭輸入下列內容即可

import findspark
findspark.init()

 (2)接下來採用Boston房價資訊資料集(https://www.kaggle.com/c/boston-housing/data)利用線性迴歸預測Boston房價。

Boston房價資訊:

crim:城鎮人均犯罪率

zn:佔地面積超過25,000平方英尺的住宅用地比例

indus:每個城鎮非零售業務的比例

chas: Charles River虛擬變數

nox:氮氧化物濃度(每千萬份)

rm:每間住宅的平均房間數

age: 1940年以前建造的自住單位比例

dis:到五個波士頓就業中心的距離的加權平均值

rad:徑向高速公路的可達性指數

tax:每10,000美元的全額物業稅率

ptratio:城鎮的學生與教師比例

black:1000(Bk — 0.63)² 其中Bk是城鎮黑人的比例

lstat:人口較低的地位(百分比)

medv:自住房屋的中位數價值1000美元,這是目標變數

(3)輸入資料集包含有關各種房屋細節的資料。根據所提供的資訊,目標是提出一個模型來預測該地區特定房屋的中值。

載入資料

from pyspark import SparkConf, SparkContext
from pyspark.sql import SQLContext
sc= SparkContext()
sqlContext = SQLContext(sc)

house_df = sqlContext.read.format('com.databricks.spark.csv').options(header='true', inferschema='true').load('boston.csv')
house_df.take(1)

[Row(ID=1, crim=0.00632, zn=18.0, indus=2.31, chas=0, nox=0.538, rm=6.575, age=65.2, dis=4.09, rad=1, tax=296, ptratio=15.3, black=396.9, lstat=4.98, medv=24.0)]

(4)以樹形模式列印資料

house_df.cache()
house_df.printSchema()

 

(5)執行描述性分析

house_df.describe().toPandas().transpose()

(6)散點矩陣可以粗略確定是否在多個自變數之間具有線性相關性

import pandas as pd
%matplotlib inline

numeric_features = [t[0] for t in house_df.dtypes if t[1] == 'int' or t[1] == 'double']
sampled_data = house_df.select(numeric_features).sample(False, 0.8).toPandas()
axs = pd.scatter_matrix(sampled_data, figsize=(10, 10))
n = len(sampled_data.columns)
for i in range(n):
    v = axs[i, 0]
    v.yaxis.label.set_rotation(0)
    v.yaxis.label.set_ha('right')
    v.set_yticks(())
    h = axs[n-1, i]
    h.xaxis.label.set_rotation(90)
h.set_xticks(())

(7)確定自變數和目標變數之間的相關性

import six
for i in house_df.columns:
    if not( isinstance(house_df.select(i).take(1)[0][0], six.string_types)):
        print( "Correlation to medv for ", i, house_df.stat.corr('medv',i))
 

相關係數的範圍從-1到1。當它接近1時,意味著存在強正相關;例如,當房間數量增加時,中值往往會上升。當係數接近-1時,意味著存在強烈的負相關; 當人口較低地位的百分比上升時,中值往往會下降。最後,接近零的係數意味著沒有線性相關。

(8)準備機器學習資料。(特徵feautures和標籤medv):

vhouse_df = vhouse_df.select(['features', 'medv'])
vhouse_df.show(3)

 (9)切分資料集,70%資料作為訓練集,30%資料作為測試集。

splits = vhouse_df.randomSplit([0.7, 0.3])
train_df = splits[0]
test_df = splits[1]

(10)線性迴歸

from pyspark.ml.regression import LinearRegression

lr = LinearRegression(featuresCol = 'features', labelCol='medv', maxIter=10, regParam=0.3, elasticNetParam=0.8)
lr_model = lr.fit(train_df)
print("Coefficients: " + str(lr_model.coefficients))#
print("Intercept: " + str(lr_model.intercept))

(11)訓練集上的評價指標:

trainingSummary = lr_model.summary
print("RMSE: %f" % trainingSummary.rootMeanSquaredError)
print("r2: %f" % trainingSummary.r2)

(12)RMSE通過模型和實際值測量預測值之間的差異。然而,在我們與實際的“medv”值(例如平均值,最小值和最大值)進行比較之前,僅RMSE是沒有意義的。

train_df.describe().show()

(13)R平方為0.71表明在我們的模型中,使用該模型可以解釋“medv”中大約71%的變異性。這與Scikit-Learn的結果一致。測試集上的表現與訓練集上有一些差異。

lr_predictions = lr_model.transform(test_df)
lr_predictions.select("prediction","medv","features").show(5)

from pyspark.ml.evaluation import RegressionEvaluator
lr_evaluator = RegressionEvaluator(predictionCol="prediction", \
                 labelCol="medv",metricName="r2")
print("R Squared (R2) on test data = %g" % lr_evaluator.evaluate(lr_predictions))

test_result = lr_model.evaluate(test_df)
print("Root Mean Squared Error (RMSE) on test data = %g" % test_result.rootMeanSquaredError)
Root Mean Squared Error (RMSE) on test data = 5.42683

(15)使用線性迴歸模型做一些預測:

predictions = lr_model.transform(test_df)
predictions.select("prediction","medv","features").show()