1. 程式人生 > >Spark一些常用的資料處理方法-2.MLlib基礎統計方法

Spark一些常用的資料處理方法-2.MLlib基礎統計方法

SparkMLlib中會經常對RDD用到統計方法,其用法如下

2.1 基礎載入包


//向量
import org.apache.spark.mllib.linalg.Vector

//向量集
import org.apache.spark.mllib.linalg.Vectors

//稠密向量
import org.apache.spark.mllib.linalg.DenseVector

//例項
import org.apache.spark.mllib.stat.{MultivariateStatisticalSummary, Statistics}

//矩陣
import org.apache.spark.mllib.linalg.{Matrix, Matrices}


//索引矩陣
import org.apache.spark.mllib.linalg.distributed.RowMatrix

//RDD
import org.apache.spark.rdd.RDD

2.2 標準構造


//建立一個RDD[Vector]
val rdd1 = sc.parallelize(Array(Array(1.0, 2.0, 3.0, 4.0), Array(2.0, 3.0, 4.0, 5.0), Array(3.0, 4.0, 5.0, 6.0))).map(f => Vectors.dense(f))
val rows: RDD[Vector] = rdd1

//或者建立一個矩陣將這個矩陣轉化
def toRDD(m: Matrix): RDD[Vector] = {
val columns = m.toArray.grouped(m.numRows)
val rows = columns.toSeq.transpose
val vectors = rows.map(row => new DenseVector(row.toArray))
sc.parallelize(vectors)
}

//將這個RDD轉變為MultivariateStatisticalSummary例項
val summary:MultivariateStatisticalSummary = Statistics.colStats(rdd1)

//這個例項可以呼叫以下方法
summary.mean//均值
summary.variance//方差
summary.numNonzeros//非零統計量個數
summary.count//總數
summary.max//最大值
summary.min//最小值
//返回值均為向量
//若為RDD[Double],則可以呼叫以下統計方法
//統計結果檢視doublerdd.stats
//計數doublerdd.count
//平均數doublerdd.mean
//方差doublerdd.variance
//標準差doublerdd.stdev
//最大值doublerdd.max
//最小值doublerdd.min


2.3 標準矩陣


//密集矩陣
val dm:Matrix = Matrices.dense(3,2,Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))
//稀疏矩陣
val sm:Matrix = Matrices.sparse(3,2,Array(0,1,3), Array(0,2,1), Array(9,6,8))

2.4 相關性

相關性是對變數之間相關程度的檢驗,值介於-1~1之間,越接近-1或1越可以進行線性擬合。

//皮爾森相關係數(預設)檢驗
//先導包
import org.apache.spark.mllib.stat.Statistics
//矩陣sm見1.3, toRDD方法見1.2
def toRDD(m: Matrix): RDD[Vector] =.......
val dm:Matrix = ......
//構造一個RDD[Vector]
val rdd1 = toRDD(sm)
//檢驗
val correlMatrix:Matrix = Statistics.corr(rdd1)
//或者
val correlMatrix:Matrix = Statistics.corr(rdd1,"pearson")
//若用斯皮爾曼等級相關係數
val correlMatrix:Matrix = Statistics.corr(rdd1,"spearman")
//以上結果返回的都是一個矩陣,反映數值之間的相關性,如果差別較大可以看的很明顯
//若比較兩個向量,如
val rdd2 = sc.parallelize(Array(170.0, 150.0, 210.0,180.0,160.0))
val rdd3 = sc.parallelize(Array(180.0, 165.0, 190.0,168.0,172.0))
val correlationPearson = Statistics.corr(rdd2, rdd3)
//則可以得到唯一的一個Double結果,用於判斷相關性,往往用於某種行為和某一結果的比較,且資料量需要最起碼大於2個才具備意義。由於該係數運算準確度與資料量相關,資料量較少或較多均會造成準確度下降,故而需要選取適當的資料集合進行運算。correlationPearson 的絕對值分類有如下規則。
//0.8-1.0 極強相關
//0.6-0.8 強相關
//0.4-0.6 中等程度相關
//0.2-0.4 弱相關
//0.0-0.2 極弱相關或無相關

2.5 分層抽樣

Spark中的分層抽樣有兩種,一種是擲幣抽樣sampleByKey,另一種是提供置信度達到99.99%的精確抽樣sampleByKeyExact(也就是說樣本幾乎可以完全代表資料集本身,只是數量少一點而已)。這個方法針對的是鍵值對RDD,即RDD[(K,V)]

//先導包
import org.apache.spark.rdd.PairRDDFunctions
//建立一個鍵值對
val data = sc.textFile("path").map(func)
//建立一個儲存抽樣的Map,並設定取樣規則,如二八準則
val fractions: Map[Int, Double] = (List((1, 0.2), (2, 0.8))).toMap
//獲取抽樣,樣本之間是不重複的
val approxSample =data.sampleByKey(withReplacement = false, fractions)
//精確抽樣,樣本之間是不重複的,時間效率較高,但更具代表性
val exactSample =data.sampleByKeyExact(withReplacement = false, fractions)

2.6 隨機資料

隨機資料一般用於運算測試,MLlib支援的分佈型別包括均勻分佈、泊松分佈、標準正態分佈,結果可以是Double或者Vector。

//先導包
import org.apache.spark.mllib.random.RandomRDDs._
import org.apache.spark.{SparkConf, SparkContext}
//關閉預設sc
sc.stop
//重新構建sc
val conf = new SparkConf().setMaster("local[4]").setAppName(this.getClass().getSimpleName().filter(!_.equals('$')))
val sc = new SparkContext(conf)
//標準正態分佈N(0,1) 其中中間的10表示10個,後面的10表示分割槽數,可以不寫
val ndrdd= normalRDD(sc, 10, 10)
//正態分佈N(1,4)
val ndrdd2 = ndrdd.map(x => 1.0 + 2.0 * x)
//泊松分佈
val psrdd = poissonRDD(sc, 10, 10)
//均勻分佈
val ufrdd = uniformRDD(sc, 10, 10)
//指數分佈
val eprdd= exponentialRDD(sc,10, 10)
//伽馬分佈
val gmardd = gammaRDD(sc, 3,3,10)
//對數正態分佈
val logrdd = logNormalRDD(sc, 0, 2, 10)

2.7 核密度估計

SparkMLlib中的核密度估計用的是最簡單的“高斯核函式”,原理部分不談了,以後寫ML庫的時候再說。簡單理解這個概念呢,說用一組特徵數來表達所有資料,那麼這組特徵數所能代表的密度,即概率大概是多少。這個在熱點圖中比較經常用到。

//還是先載入包
import org.apache.spark.mllib.stat.KernelDensity
//載入資料,此處用1.4的rdd2
val rdd2 =......
//載入資料,設定標準差
val kd = new KernelDensity().setSample(rdd2).setBandwidth(rdd2.stdev)
//設定座標值,求密度
val densities = kd.estimate(Array(140.0, 170.0, 200.0, 230.0))

2.8 假設檢驗

假設檢驗一般用於判斷一組資料或者向量是否符合假定的分佈情況,或者比較兩組資料是否具有相同的分佈情況,或者資料之間是否具有關聯

//先導包,還是統計包
import org.apache.spark.mllib.stat.Statistics
//顯著性檢驗:測試一下兩個向量是否同一分佈
val land1 = Vectors.dense(1000.0, 1856.0)
val land2 = Vectors.dense(400, 560)
val c1 = Statistics.chiSqTest(land1, land2)
//其結果返回pValue = 5.536682223805656E-13,說明其顯著性非常小,分佈幾乎是相同的,若這個值大於0.05,則說明差異較大。
//獨立性檢驗,先構建兩個向量
val v1:Vector = Vectors.dense(1.0, 2.0, 3.0, 4.0, 5.0)
val v2:Vector = Vectors.dense(2.0, 4.0, 6.0, 8.0, 10.0)
//將前者作為樣本,後者作為期望,檢驗
val a =Statistics.chiSqTest(v1, v2)
//得到結果pValue = 1.0,說明幾乎無差別。一般p值若非常小,則證明兩組資料是相關的。