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

全國(guó)咨詢/投訴熱線:400-618-4000

SparkMllib數(shù)值型特征基本處理方法介紹[大數(shù)據(jù)培訓(xùn)]

更新時(shí)間:2019年09月18日17時(shí)20分 來(lái)源:傳智播客 瀏覽次數(shù):

在SparkMllib中主要分為特征抽取、特征轉(zhuǎn)化、特征選擇,特別是在特征轉(zhuǎn)化方面是從一個(gè)DataFrame轉(zhuǎn)化為另外一個(gè)DataFrame,在數(shù)值型數(shù)據(jù)處理的時(shí)候我們對(duì)機(jī)器學(xué)習(xí)數(shù)據(jù)集中的樣本和特征部分進(jìn)行單獨(dú)的處理,這里就涉及對(duì)樣本的正則化操作和數(shù)值型特征的歸一化和標(biāo)準(zhǔn)化的方法,今天就帶大家理解這一部分的思考和認(rèn)識(shí)。

1.數(shù)據(jù)歸一化

什么是數(shù)據(jù)的歸一化?

答:數(shù)據(jù)的標(biāo)準(zhǔn)化是將數(shù)據(jù)按比例縮放,使之落入一個(gè)小的特定區(qū)間。在某些比較和評(píng)價(jià)的指標(biāo)處理中經(jīng)常會(huì)用到,去除數(shù)據(jù)的單位限制,將其轉(zhuǎn)化為無(wú)量綱的純數(shù)值,便于不同單位或量級(jí)的指標(biāo)能夠進(jìn)行比較和加權(quán)。其中最典型的就是數(shù)據(jù)的歸一化處理,即將數(shù)據(jù)統(tǒng)一映射到[0,1]區(qū)間上。

為什么對(duì)數(shù)據(jù)歸一化處理?

我們?cè)趯?duì)數(shù)據(jù)進(jìn)行分析的時(shí)候,往往會(huì)遇到單個(gè)數(shù)據(jù)的各個(gè)維度量綱不同的情況,比如對(duì)房子進(jìn)行價(jià)格預(yù)測(cè)的線性回歸問(wèn)題中,我們假設(shè)房子面積(平方米)、年代(年)和幾居室(個(gè))三個(gè)因素影響房?jī)r(jià),其中一個(gè)房子的信息如下:

面積(S):150 平方米

年代(Y):5 年

這樣各個(gè)因素就會(huì)因?yàn)榱烤V的問(wèn)題對(duì)模型有著大小不同的影響,但是這種大小不同的影響并非反應(yīng)問(wèn)題的本質(zhì)。

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



SparkMllib數(shù)值型特征


2.數(shù)據(jù)標(biāo)準(zhǔn)化

什么是標(biāo)準(zhǔn)化(StandardScaler)?

訓(xùn)練集中某一列數(shù)值特征(假設(shè)是第i列)的值縮放成均值為0,方差為1的狀態(tài)。標(biāo)準(zhǔn)化之后,數(shù)據(jù)的范圍并不一定是0-1之間,數(shù)據(jù)不一定是標(biāo)準(zhǔn)正態(tài)分布,因?yàn)闃?biāo)準(zhǔn)化之后數(shù)據(jù)的分布并不會(huì)改變,如果數(shù)據(jù)本身是正態(tài)分布,那進(jìn)行標(biāo)準(zhǔn)化之后就是標(biāo)準(zhǔn)正態(tài)分布。

(1)歸一化和標(biāo)準(zhǔn)化的相同點(diǎn)都是對(duì)某個(gè)特征(column)進(jìn)行縮放(scaling)而不是對(duì)某個(gè)樣本的特征向量(row樣本數(shù)據(jù))進(jìn)行縮放。對(duì)行進(jìn)行縮放是毫無(wú)意義的。比如三列特征:身高、體重、血壓。每一條樣本(row)就是三個(gè)這樣的值,對(duì)這個(gè)row無(wú)論是進(jìn)行標(biāo)準(zhǔn)化還是歸一化都是無(wú)意義的,因?yàn)槟悴荒軐⑸砀?、體重和血壓混到一起去。

(2)標(biāo)準(zhǔn)化/歸一化的好處

提升模型精度:基于距離的算法,例如Kmeans、KNN等,各個(gè)特征的量綱直接決定了模型的預(yù)測(cè)結(jié)果。舉一個(gè)簡(jiǎn)單的例子,在KNN中,我們需要計(jì)算待分類點(diǎn)與所有實(shí)例點(diǎn)的距離。假設(shè)每個(gè)實(shí)例點(diǎn)(instance)由n個(gè)features構(gòu)成。如果我們選用的距離度量為歐式距離,如果數(shù)據(jù)預(yù)先沒(méi)有經(jīng)過(guò)歸一化,那么那些絕對(duì)值大的features在歐式距離計(jì)算的時(shí)候起了決定性作用。對(duì)于PCA,如果沒(méi)有對(duì)數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化,部分特征的所占的信息可能會(huì)虛高。

提升收斂速度:例如,對(duì)于linear model來(lái)說(shuō),數(shù)據(jù)歸一化后,最優(yōu)解的尋優(yōu)過(guò)程明顯會(huì)變得平緩,更容易正確的收斂到最優(yōu)解。對(duì)于SVM標(biāo)準(zhǔn)化之后梯度下降的速度加快。

3.標(biāo)準(zhǔn)化和歸一化的對(duì)比分析

(1)標(biāo)準(zhǔn)化/歸一化的對(duì)比分析

首先明確,在機(jī)器學(xué)習(xí)中,標(biāo)準(zhǔn)化是更常用的手段。

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

當(dāng)數(shù)據(jù)需要被壓縮至一個(gè)固定的區(qū)間時(shí),我們使用MinMaxScaler.

(2)在邏輯回歸中需要使用標(biāo)準(zhǔn)化么?

如果你不用正則,那么,標(biāo)準(zhǔn)化并不是必須的,如果你用正則,那么標(biāo)準(zhǔn)化是必須的。為什么呢?因?yàn)椴挥谜齽t時(shí),我們的損失函數(shù)只是僅僅在度量預(yù)測(cè)與真實(shí)的差距,加上正則后,我們的損失函數(shù)除了要度量上面的差距外,還要度量參數(shù)值是否足夠小。而參數(shù)值的大小程度或者說(shuō)大小的級(jí)別是與特征的數(shù)值范圍相關(guān)的。

舉一例來(lái)說(shuō),我們預(yù)測(cè)身高,體重用kg衡量時(shí),訓(xùn)練出的模型是: 身高 = x*體重+y*父母身高,X是我們訓(xùn)練出來(lái)的參數(shù)。當(dāng)我們的體重用噸來(lái)衡量時(shí),x的值就會(huì)擴(kuò)大為原來(lái)的1000倍。在上面兩種情況下,都用L1正則的話,顯然當(dāng)使用kg作為單位時(shí),顯然對(duì)模型的訓(xùn)練影響是不同的。

再舉一例來(lái)說(shuō),假如不同的特征的數(shù)值范圍不一樣,有的是0到0.1,有的是100到10000,那么,每個(gè)特征對(duì)應(yīng)的參數(shù)大小級(jí)別也會(huì)不一樣,在L1正則時(shí),我們是簡(jiǎn)單將參數(shù)的絕對(duì)值相加,因?yàn)樗鼈兊拇笮〖?jí)別不一樣,就會(huì)導(dǎo)致L1會(huì)對(duì)那些級(jí)別比較大的參數(shù)正則化程度高,那些小的參數(shù)都被忽略了。

就算不做正則化處理,建模前先對(duì)數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化處理也是有好處的。進(jìn)行標(biāo)準(zhǔn)化后,我們得出的參數(shù)值的大小可以反應(yīng)出不同特征對(duì)label的貢獻(xiàn)度,使參數(shù)具有可解釋性。

這里注意一點(diǎn):有些需要保持?jǐn)?shù)據(jù)的原始量綱的情況下,不能對(duì)數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化或者歸一化處理。例如,制作評(píng)分卡

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

我們?cè)谟?xùn)練模型時(shí),要最小化損失函數(shù),這樣很有可能出現(xiàn)過(guò)擬合的問(wèn)題(參數(shù)過(guò)多,模型過(guò)于復(fù)雜),所以我么在損失函數(shù)后面加上正則化約束項(xiàng),轉(zhuǎn)而求約束函數(shù)和正則化項(xiàng)之和的最小值。


SparkMllib

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

0 數(shù)據(jù)準(zhǔn)備

// 原始數(shù)據(jù)

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

| 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的作用范圍是每一行,使每一個(gè)行向量的范數(shù)變換為一個(gè)單位范數(shù)

作用對(duì)象:行

方法公式:

L1范數(shù)是指向量中各個(gè)元素絕對(duì)值之和

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

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

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

Ln無(wú)窮階范數(shù)最終趨近于絕對(duì)值最大的元素(x趨近于無(wú)窮)

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

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

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

// 正則化每個(gè)向量到1階范數(shù)

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階范數(shù)為1的向量,1階范數(shù)即所有值絕對(duì)值之和。

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

| 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]|

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

// 正則化每個(gè)向量到無(wú)窮階范數(shù)

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

println("Normalized using L^inf norm")

lInfNormData.show()

// 向量的無(wú)窮階范數(shù)即向量中所有值中的最大值

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

| 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處理的對(duì)象是每一列,也就是每一維特征,將特征標(biāo)準(zhǔn)化為單位標(biāo)準(zhǔn)差或是0均值,或是0均值單位標(biāo)準(zhǔn)差。

作用對(duì)象:列

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

主要有兩個(gè)參數(shù)可以設(shè)置:

withStd: 默認(rèn)為真。將數(shù)據(jù)標(biāo)準(zhǔn)化到單位標(biāo)準(zhǔn)差。

withMean: 默認(rèn)為假。是否變換為0均值。

StandardScaler需要fit數(shù)據(jù),獲取每一維的均值和標(biāo)準(zhǔn)差,來(lái)縮放每一維特征。

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

// 將每一列的標(biāo)準(zhǔn)差縮放到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]。

作用對(duì)象:列

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

有兩個(gè)參數(shù)可以設(shè)置:

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

max: 默認(rèn)為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ū)間上,通過(guò)除以每一維特征上的最大的絕對(duì)值,它不會(huì)平移整個(gè)分布,也不會(huì)破壞原來(lái)每一個(gè)特征向量的稀疏性。

作用對(duì)象:列

方法公式: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()

// 每一維的絕對(duì)值的最大值為[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.總結(jié)

通過(guò)對(duì)SparkMllib特征工程中涉及的數(shù)值型數(shù)據(jù)的處理分析,總結(jié)如何對(duì)機(jī)器學(xué)習(xí)中的樣本和特征數(shù)據(jù)的分析和實(shí)踐,通過(guò)總結(jié)分析得到對(duì)應(yīng)結(jié)論,希望這部分知識(shí)能夠?qū)Τ醪綄W(xué)習(xí)SparkMllib但是對(duì)特征工程,尤其是數(shù)值型數(shù)據(jù)的特征工程理解存在問(wèn)題的能夠起到作用。


推薦了解:
大數(shù)據(jù)培訓(xùn)課程
python+人工智能課程

0 分享到:
和我們?cè)诰€交談!