教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

SparkMllib數值型特征基本處理方法介紹[大數據培訓]

更新時間:2019年09月18日17時20分 來源:傳智播客 瀏覽次數:

在SparkMllib中主要分為特征抽取、特征轉化、特征選擇,特別是在特征轉化方面是從一個DataFrame轉化為另外一個DataFrame,在數值型數據處理的時候我們對機器學習數據集中的樣本和特征部分進行單獨的處理,這里就涉及對樣本的正則化操作和數值型特征的歸一化和標準化的方法,今天就帶大家理解這一部分的思考和認識。

1.數據歸一化

什么是數據的歸一化?

答:數據的標準化是將數據按比例縮放,使之落入一個小的特定區(qū)間。在某些比較和評價的指標處理中經常會用到,去除數據的單位限制,將其轉化為無量綱的純數值,便于不同單位或量級的指標能夠進行比較和加權。其中最典型的就是數據的歸一化處理,即將數據統(tǒng)一映射到[0,1]區(qū)間上。

為什么對數據歸一化處理?

我們在對數據進行分析的時候,往往會遇到單個數據的各個維度量綱不同的情況,比如對房子進行價格預測的線性回歸問題中,我們假設房子面積(平方米)、年代(年)和幾居室(個)三個因素影響房價,其中一個房子的信息如下:

面積(S):150 平方米

年代(Y):5 年

這樣各個因素就會因為量綱的問題對模型有著大小不同的影響,但是這種大小不同的影響并非反應問題的本質。

為了解決這個問題,我們將所有的數據都用歸一化處理至同一區(qū)間內。



SparkMllib數值型特征


2.數據標準化

什么是標準化(StandardScaler)?

訓練集中某一列數值特征(假設是第i列)的值縮放成均值為0,方差為1的狀態(tài)。標準化之后,數據的范圍并不一定是0-1之間,數據不一定是標準正態(tài)分布,因為標準化之后數據的分布并不會改變,如果數據本身是正態(tài)分布,那進行標準化之后就是標準正態(tài)分布。

(1)歸一化和標準化的相同點都是對某個特征(column)進行縮放(scaling)而不是對某個樣本的特征向量(row樣本數據)進行縮放。對行進行縮放是毫無意義的。比如三列特征:身高、體重、血壓。每一條樣本(row)就是三個這樣的值,對這個row無論是進行標準化還是歸一化都是無意義的,因為你不能將身高、體重和血壓混到一起去。

(2)標準化/歸一化的好處

提升模型精度:基于距離的算法,例如Kmeans、KNN等,各個特征的量綱直接決定了模型的預測結果。舉一個簡單的例子,在KNN中,我們需要計算待分類點與所有實例點的距離。假設每個實例點(instance)由n個features構成。如果我們選用的距離度量為歐式距離,如果數據預先沒有經過歸一化,那么那些絕對值大的features在歐式距離計算的時候起了決定性作用。對于PCA,如果沒有對數據進行標準化,部分特征的所占的信息可能會虛高。

提升收斂速度:例如,對于linear model來說,數據歸一化后,最優(yōu)解的尋優(yōu)過程明顯會變得平緩,更容易正確的收斂到最優(yōu)解。對于SVM標準化之后梯度下降的速度加快。

3.標準化和歸一化的對比分析

(1)標準化/歸一化的對比分析

首先明確,在機器學習中,標準化是更常用的手段。

MinMaxScaler對異常值非常敏感。例如,比如三個樣本,某個特征的值為1,2,10000,假設10000這個值是異常值,用歸一化的方法后,正常的1,2就會被“擠”到一起去。在PCA,聚類,邏輯回歸,支持向量機,神經網絡這些算法中,StandardScaler往往是最好的選擇。

當數據需要被壓縮至一個固定的區(qū)間時,我們使用MinMaxScaler.

(2)在邏輯回歸中需要使用標準化么?

如果你不用正則,那么,標準化并不是必須的,如果你用正則,那么標準化是必須的。為什么呢?因為不用正則時,我們的損失函數只是僅僅在度量預測與真實的差距,加上正則后,我們的損失函數除了要度量上面的差距外,還要度量參數值是否足夠小。而參數值的大小程度或者說大小的級別是與特征的數值范圍相關的。

舉一例來說,我們預測身高,體重用kg衡量時,訓練出的模型是: 身高 = x*體重+y*父母身高,X是我們訓練出來的參數。當我們的體重用噸來衡量時,x的值就會擴大為原來的1000倍。在上面兩種情況下,都用L1正則的話,顯然當使用kg作為單位時,顯然對模型的訓練影響是不同的。

再舉一例來說,假如不同的特征的數值范圍不一樣,有的是0到0.1,有的是100到10000,那么,每個特征對應的參數大小級別也會不一樣,在L1正則時,我們是簡單將參數的絕對值相加,因為它們的大小級別不一樣,就會導致L1會對那些級別比較大的參數正則化程度高,那些小的參數都被忽略了。

就算不做正則化處理,建模前先對數據進行標準化處理也是有好處的。進行標準化后,我們得出的參數值的大小可以反應出不同特征對label的貢獻度,使參數具有可解釋性。

這里注意一點:有些需要保持數據的原始量綱的情況下,不能對數據進行標準化或者歸一化處理。例如,制作評分卡

而如何理解正則化方法呢?

我們在訓練模型時,要最小化損失函數,這樣很有可能出現過擬合的問題(參數過多,模型過于復雜),所以我么在損失函數后面加上正則化約束項,轉而求約束函數和正則化項之和的最小值。


SparkMllib

4. SparkMllib代碼實戰(zhàn)

0 數據準備

// 原始數據

+---+---------------------+

| id| features|

+---+---------------------+

| 0|[1.0,0.5,-1.0]|

| 1| [2.0,1.0,1.0]|

| 2|[4.0,10.0,2.0]|

+---+---------------------+

代碼如下:

import org.apache.spark.ml.linalg.Vectors

val dataFrame = spark.createDataFrame(Seq(

(0, Vectors.dense(1.0, 0.5, -1.0)),

(1, Vectors.dense(2.0, 1.0, 1.0)),

(2, Vectors.dense(4.0, 10.0, 2.0))

)).toDF("id", "features")

dataFrame.show

4.1 Normalizer

Normalizer的作用范圍是每一行,使每一個行向量的范數變換為一個單位范數

作用對象:行

方法公式:

L1范數是指向量中各個元素絕對值之和

colX/(|col1|+|col2|...+|coln|)

L2范數是指向量各元素的平方和然后求平方根

colX/(|col1^2|+|col2^2|...+|coln^2|)^(1/2)

Ln無窮階范數最終趨近于絕對值最大的元素(x趨近于無窮)

colX/(|col1^x|+|col2^x|...+|coln^x|)^(1/x)

max(|col1|,|col2|...|coln|)

import org.apache.spark.ml.feature.Normalizer

// 正則化每個向量到1階范數

val normalizer = new Normalizer()

.setInputCol("features")

.setOutputCol("normFeatures")

.setP(1.0)

val l1NormData = normalizer.transform(dataFrame)

println("Normalized using L^1 norm")

l1NormData.show()

// 將每一行的規(guī)整為1階范數為1的向量,1階范數即所有值絕對值之和。

+---+--------------+------------------+

| id| features| normFeatures|

+---+--------------+------------------+

| 0|[1.0,0.5,-1.0]| [0.4,0.2,-0.4]|

| 1| [2.0,1.0,1.0]| [0.5,0.25,0.25]|

| 2|[4.0,10.0,2.0]|[0.25,0.625,0.125]|

+---+--------------+------------------+

// 正則化每個向量到無窮階范數

val lInfNormData = normalizer.transform(dataFrame, normalizer.p -> Double.PositiveInfinity)

println("Normalized using L^inf norm")

lInfNormData.show()

// 向量的無窮階范數即向量中所有值中的最大值

+---+--------------+--------------+

| id| features| normFeatures|

+---+--------------+--------------+

| 0|[1.0,0.5,-1.0]|[1.0,0.5,-1.0]|

| 1| [2.0,1.0,1.0]| [1.0,0.5,0.5]|

| 2|[4.0,10.0,2.0]| [0.4,1.0,0.2]|

+---+--------------+--------------+

4.2 StandardScaler

StandardScaler處理的對象是每一列,也就是每一維特征,將特征標準化為單位標準差或是0均值,或是0均值單位標準差。

作用對象:列

方法公式:(colX-avgValue)/stddev

主要有兩個參數可以設置:

withStd: 默認為真。將數據標準化到單位標準差。

withMean: 默認為假。是否變換為0均值。

StandardScaler需要fit數據,獲取每一維的均值和標準差,來縮放每一維特征。

import org.apache.spark.ml.feature.StandardScaler

val scaler = new StandardScaler()

.setInputCol("features")

.setOutputCol("scaledFeatures")

.setWithStd(true)

.setWithMean(false)

// Compute summary statistics by fitting the StandardScaler.

val scalerModel = scaler.fit(dataFrame)

// Normalize each feature to have unit standard deviation.

val scaledData = scalerModel.transform(dataFrame)

scaledData.show

// 將每一列的標準差縮放到1。

+---+--------------+--------------------------------------------+

|id |features |scaledFeatures |

+---+--------------+--------------------------------------------+

|0 |[1.0,0.5,-1.0]|[0.6546536707,0.093521952958,-0.65465367070]|

|1 |[2.0,1.0,1.0] |[1.30930734141,0.18704390591,0.65465367070] |

|2 |[4.0,10.0,2.0]|[2.61861468283,1.8704390591,1.30930734141] |

+---+--------------+--------------------------------------------+

4.3 MinMaxScaler

MinMaxScaler作用同樣是每一列,即每一維特征。將每一維特征線性地映射到指定的區(qū)間,通常是[0, 1]。

作用對象:列

方法公式:(colX-minValue)/(maxValue-minValue)

有兩個參數可以設置:

min: 默認為0。指定區(qū)間的下限。

max: 默認為1。指定區(qū)間的上限。

import org.apache.spark.ml.feature.MinMaxScaler

val scaler = new MinMaxScaler()

.setInputCol("features")

.setOutputCol("scaledFeatures")

// Compute summary statistics and generate MinMaxScalerModel

val scalerModel = scaler.fit(dataFrame)

// rescale each feature to range [min, max].

val scaledData = scalerModel.transform(dataFrame)

println(s"Features scaled to range: [${scaler.getMin}, ${scaler.getMax}]")

scaledData.select("features", "scaledFeatures").show

// 每維特征線性地映射,最小值映射到0,最大值映射到1。

+--------------+--------------------------------------------+

|features |scaledFeatures |

+--------------+--------------------------------------------+

|[1.0,0.5,-1.0]|[0.0,0.0,0.0] |

|[2.0,1.0,1.0] |[0.33333333333,0.052631578947,0.66666666666]|

|[4.0,10.0,2.0]|[1.0,1.0,1.0] |

+--------------+--------------------------------------------+

4.4 MaxAbsScaler

MaxAbsScaler將每一維的特征變換到[-1, 1]閉區(qū)間上,通過除以每一維特征上的最大的絕對值,它不會平移整個分布,也不會破壞原來每一個特征向量的稀疏性。

作用對象:列

方法公式:colX/max(|colValue|)

import org.apache.spark.ml.feature.MaxAbsScaler

val scaler = new MaxAbsScaler()

.setInputCol("features")

.setOutputCol("scaledFeatures")

// Compute summary statistics and generate MaxAbsScalerModel

val scalerModel = scaler.fit(dataFrame)

// rescale each feature to range [-1, 1]

val scaledData = scalerModel.transform(dataFrame)

scaledData.select("features", "scaledFeatures").show()

// 每一維的絕對值的最大值為[4, 10, 2]

+--------------+----------------+

| features| scaledFeatures|

+--------------+----------------+

|[1.0,0.5,-1.0]|[0.25,0.05,-0.5]|

| [2.0,1.0,1.0]| [0.5,0.1,0.5]|

|[4.0,10.0,2.0]| [1.0,1.0,1.0]|

+--------------+----------------+

5.總結

通過對SparkMllib特征工程中涉及的數值型數據的處理分析,總結如何對機器學習中的樣本和特征數據的分析和實踐,通過總結分析得到對應結論,希望這部分知識能夠對初步學習SparkMllib但是對特征工程,尤其是數值型數據的特征工程理解存在問題的能夠起到作用。


推薦了解:
大數據培訓課程
python+人工智能課程

0 分享到:
和我們在線交談!