1. 程式人生 > >Spark Mllib之基本統計

Spark Mllib之基本統計

1.概要統計(Summary statistics)

我們通過Statistics中提供的函式colStats為RDD [Vector]提供列摘要統計資訊。

colStats()返回MultivariateStatisticalSummary的一個例項,其中包含列的max,min,mean,variance和非零數,以及總計數。

SparkConf conf = new SparkConf().setMaster("local").setAppName("BasicStatistics");

       JavaSparkContext context = new JavaSparkContext(

conf);

       JavaRDD<Vector> mat = context.parallelize(Arrays.asList(Vectors.dense(1.0, 10.0, 100.0),

              Vectors.dense(2.0, 20.0, 200.0), Vectors.dense(3.0, 30.0, 300.0)));

       // 計算列的摘要統計

       MultivariateStatisticalSummary summary = Statistics.colStats(mat.rdd());

       System.

out.println(summary.mean());// 密集向量,表示每一列的平均值

       System.out.println(summary.variance()); // 列方差

       System.out.println(summary.numNonzeros());// 每一列的非零值數目

       context.stop();

2.相關性

計算兩個資料系列之間的相關性是統計學中的常見操作。在spark.mllib中,我們提供了計算許多系列之間成對相關性的靈活性。目前支援的相關方法是Pearson和Spearman的相關性。

 提供了計算序列之間相關性的方法。根據輸入型別,兩個JavaDoubleRDD或JavaRDD <Vector>,輸出將分別為Double或相關矩陣。

// 相關性計算

       JavaDoubleRDD seriesX = context.parallelizeDoubles(Arrays.asList(1.0, 2.0, 3.0, 3.0, 5.0));

       JavaDoubleRDD seriesY = context.parallelizeDoubles(Arrays.asList(11.0, 22.0, 33.0, 33.0, 555.0));

       double correlation = Statistics.corr(seriesX.srdd(), seriesY.srdd(), "pearson");// 預設使用pearson相關性

       System.out.println("相關性為:" + correlation);

       JavaRDD<Vector> data = context.parallelize(Arrays.asList(Vectors.dense(1.0, 10.0, 100.0),

              Vectors.dense(2.0, 20.0, 200.0), Vectors.dense(5.0, 33.0, 366.0)));

       // 計算相關性矩陣

       Matrix matrix = Statistics.corr(data.rdd());

       System.out.println(matrix);

3.分層抽樣(Stratified sampling)

與駐留在spark.mllib中的其他統計函式不同,可以對RDD的鍵值對執行分層抽樣方法sampleByKey和sampleByKeyExact。對於分層抽樣,可以將鍵視為標籤,將值視為特定屬性。例如,鍵可以是人或女人,或文件ID,並且相應的值可以是人口中的人的年齡列表或文件中的單詞列表。sampleByKey方法將翻轉硬幣以決定是否對樣本進行取樣,因此需要對資料進行一次傳遞,並提供預期的樣本大小。sampleByKeyExact比sampleByKey中使用的每層簡單隨機抽樣需要更多的資源,但是會提供99.99%置信度的精確抽樣大小。 python目前不支援sampleByKeyExact。

sampleByKeyExact()允許使用者準確地取樣⌈fk⋅nk⌉∀k∈K項,其中fk是鍵k的期望分數,nk是鍵k的鍵值對的數量 ,K是一組鍵。

// 分層抽樣

       List<Tuple2<Integer, Character>> list = Arrays.asList(new Tuple2<Integer, Character>(1, 'a'),

              new Tuple2<Integer, Character>(1, 'b'), new Tuple2<Integer, Character>(2, 'c'),

              new Tuple2<Integer, Character>(2, 'd'), new Tuple2<Integer, Character>(2, 'e'),

              new Tuple2<Integer, Character>(3, 'f'));

       JavaPairRDD<Integer, Character> data1 = context.parallelizePairs(list);

       ImmutableMap<Integer, Double> fractions = ImmutableMap.of(1, 0.1, 2, 0.6, 3, 0.3);

       JavaPairRDD<Integer, Character> javaPairRDD = data1.sampleByKey(false, fractions);

       JavaPairRDD<Integer, Character> javaPairRDD2 = data1.sampleByKey(false, fractions);

       javaPairRDD.foreach(x -> System.out.print(x + " "));

       System.out.println();

       javaPairRDD2.foreach(x -> System.out.print(x + " "));

       System.out.println();

4.假設檢驗

假設檢驗是統計學中一種強有力的工具,用於確定結果是否具有統計顯著性,無論該結果是否偶然發生。spark.mllib目前支援Pearson的卡方(χ2)檢驗,以確保擬合度和獨立性。輸入資料型別確定是否進行擬合優度或獨立性測試。擬合優度測試需要輸入型別的Vector,而獨立性測試需要Matrix作為輸入。spark.mllib還支援輸入型別RDD [LabeledPoint],以通過卡方獨立測試啟用特徵選擇。

提供了執行Pearson卡方檢驗的方法。 以下示例演示瞭如何執行和解釋假設檢驗。

//假設檢驗

       Vector vec=Vectors.dense(0.1,0.15,0.2,0.3,0.25);

       //計算適合度。 如果未提供要測試的第二個向量作為引數,則測試針對均勻分佈執行。

       ChiSqTestResult chiSqTestResult=Statistics.chiSqTest(vec);

       System.out.println(chiSqTestResult+"\n");

       //建立應變矩陣((1.0,2.0),(3.0,4.0),(5.0,6.0))

       Matrices.dense(3, 2, new double[]{1.0,3.0,5.0,2.0,4.0,6.0});

       //對輸入應變矩陣進行Pearson獨立性檢驗

       ChiSqTestResult chiSqTestResult2=Statistics.chiSqTest(matrix);

       System.out.println(chiSqTestResult2+"\n");

5.流重要性測試

spark.mllib提供了一些測試的線上實現,以支援A / B測試等用例。這些測試可以在Spark Streaming DStream [(Boolean,Double)]上執行,其中每個元組的第一個元素表示控制組(false)或處理組(true),第二個元素是觀察值。

流式重要性測試支援以下引數:

peacePeriod - 要忽略的流中的初始資料點數,用於緩解新奇效應。

windowSize - 執行假設檢驗的過去批次數。 設定為0將使用所有先前批次執行累積處理。

StreamingTest提供流式假設測試。

JavaDStream<BinarySample> data = ssc.textFileStream(dataDir).map(line -> {

  String[] ts = line.split(",");

  boolean label = Boolean.parseBoolean(ts[0]);

  double value = Double.parseDouble(ts[1]);

  return new BinarySample(label, value);

});

StreamingTest streamingTest = new StreamingTest()

  .setPeacePeriod(0)

  .setWindowSize(0)

  .setTestMethod("welch");

JavaDStream<StreamingTestResult> out = streamingTest.registerStream(data);

out.print();

6.隨機資料生成

隨機資料生成對於隨機演算法,原型設計和效能測試非常有用。spark.mllib支援使用i.i.d從給定分佈繪製的值:均勻,標準正太或泊松分佈生成隨機RDD。RandomRDDs提供工廠方法來生成隨機doubleRDD或vecors RDD。以下示例生成隨機doubleRDD,其值遵循標準正態分佈N(0,1),然後將其對映到N(1,4)。

// 隨機資料生成

       JavaDoubleRDD javaDoubleRDD = RandomRDDs.normalJavaRDD(context, 1000000L, 10);// 10

                                                                             // partitions.

       javaDoubleRDD.mapToDouble(x -> 1.0 + 2.0 * x);

7.核密度估計

 是一種可用於視覺化經驗概率分佈的技術,無需假設觀察到的樣本的特定分佈。它計算隨機變數的概率密度函式的估計值,在給定的一組點處進行評估。它通過將特定點的經驗分佈的PDF表示為以每個樣本為中心的正態分佈的PDF的平均值來實現該估計。KernelDensity提供了從樣本的RDD計算核密度估計的方法。 以下示例演示瞭如何執行此操作。

// 核密度估計

       JavaRDD<Double> data2= context

              .parallelize(Arrays.asList(1.0, 1.0, 1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.0));

       //使用樣本資料和高斯核的標準偏差構造密度估計器

       KernelDensity density=new KernelDensity().setSample(data2).setBandwidth(3.0);

       //計算給定值的密度估計

       double[] densitys=density.estimate(new double[]{-1.0,2.0,5.0});

       System.out.println(Arrays.toString(densitys));