分佈式計算 標準差,信度

分佈式計算 標準差,信度mysql


當一組數據沒法徹底加載到內存計算時,那咱們就須要進行分佈式計算,每臺機器計算部分數據而後合成最後結果。例如典型的詞頻統計案例,可是當最後的結果不能根據每臺機器的結果得出,那麼就要拆分算法了。算法

==拆分算法的標準:算法公式的粒度必定要能根據分佈式的各個task處理得出==sql

拆分標準差:app

針對一組數據 (例如:一、二、三、四、五、六、7),咱們把他拆分到兩臺機器來計算
兩組數據分佈式

A機器計算 (一、二、三、4)

B機器計算 (五、六、7)

首先單組數據須要計算三個指標函數

針對(一、二、三、4) 這個小組:code

成員個數: 4
成員之和: 1+2+3+4=10
成員的平方和:1²+2²+3²+4²=30

針對(五、六、7) 這個小組:blog

成員個數: 3
成員之和: 5+6+7=18
成員的平方和:5²+6²+7²=110

拿到這三個指標以後,拿mr來講,咱們就能夠在每一個map中計算這三個指標,最後在reduce中
執行算法內存

在開方就就恰好和mysql 的std計算結果同樣了

代碼實現:
val rdd1 = sc.makeRDD(Array(("A",1),("A",2),("A",3),("A",4),("A",5),("A",6),("A",7)))

rdd1.combineByKey(
  (v : Int) => List(v,v*v,1),
  (c : List[Int], v : Int) => List(c.apply(0)+v,(c.apply(1)+v*v),c.apply(2)+1),
  (c1 : List[Int], c2 : List[Int]) => List(c1.apply(0)+c1.apply(0),c1.apply(1)+c1.apply(1),c1.apply(2)+c1.apply(2))
).mapValues(x => sqrt((x.apply(1)/x.apply(2)) - (x.apply(0)/x.apply(2))*(x.apply(0)/x.apply(2)))).collect().foreach(println)
 

def sqrtIter(guess: Double, x: Double): Double =
if (isGoodEnough(guess, x))
guess
else
sqrtIter((guess + x / guess)/2, x)class

// 判斷解是否知足要求
def isGoodEnough(guess: Double, x: Double) =
abs(guess * guess - x)< 0.0001

// 輔助函數,求絕對值
def abs(x: Double) =
if (x < 0) -x else x

// 目標函數
def sqrt(x: Double): Double =
sqrtIter(1, x)
```

來看看mysql 的結果是否同樣

獲得了標準差,信度再次基礎上加上子集的計算就能夠了!

相關文章
相關標籤/搜索