Machine Learning on Spark——第三节 统计基础(一)

时间:2021-11-09 20:31:18

作者:周志湖
微信号:zhouzhihubeyond

本文主要内容

本文对了org.apache.spark.mllib.stat包及子包中的相关统计类进行介绍,stat包中包括下图中的类或对象:
Machine Learning on Spark——第三节 统计基础(一)
本文将对其中的部分内容进行详细讲解

  1. 获取矩阵列(column-wise)统计信息
  2. Kernel density estimation(核密度估计)
  3. Hypothesis testing(假设检验)

1. 获取矩阵列(column-wise)统计信息

获取列统计信息指的是以矩阵中的列为单位获取其统计信息(如每列的最大值、最小值、均值等其它统计特征)

package cn.ml.stat

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.stat.Statistics
import org.apache.spark.mllib.stat.MultivariateStatisticalSummary

object StatisticsDemo extends App {
val sparkConf = new SparkConf().setAppName("StatisticsDemo").setMaster("spark://sparkmaster:7077")
val sc = new SparkContext(sparkConf)

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))
//在第一节中,我们使用过该MultivariateStatisticalSummary该类,通过下列方法
// var mss:MultivariateStatisticalSummary=rowMatirx.computeColumnSummaryStatistics()
// 这里是通过Statistics方法去获取相关统计信息,它们的内部实现原理是一致的,最终返回其实都是
// MultivariateOnlineSummarizer的实例(下一小节将讲解该类)
//Statistics.colStats方法它的源码如下:
// def colStats(X: RDD[Vector]): MultivariateStatisticalSummary = {
// new RowMatrix(X).computeColumnSummaryStatistics()
//}
//可以看到 Statistics.colStats方法调用的是RowMatrix中的computeColumnSummaryStatistics方法
val mss:MultivariateStatisticalSummary=Statistics.colStats(rdd1)
//因此下列方面返回的结果与第一节通过调用computeColumnSummaryStatistics得到的结果
//返回值是一致的
mss.max
mss.min
mss.normL1
//其它normL2等统计信息
}

2. Kernel density estimation(核密度估计)

统计学当中,核密度估计(Kernel density estimation,KDE)扮演着十分重要的角色,它是一种非参数化的随机变量概率密度估计方法。设(x1, x2, …, xn)为n个独立同分布的样本,对其概率密度函数作如下定义:
Machine Learning on Spark——第三节 统计基础(一)
其中K(•)被称为核,h 被称为带宽bandwidth,它是一个大于0的平滑参数,更详细的信息参见https://en.wikipedia.org/wiki/Kernel_density_estimation
核函数的种类比较多,但Spark中只实现了高斯核函数:
Machine Learning on Spark——第三节 统计基础(一)

  val sample = sc.parallelize(Seq(0.0, 1.0, 4.0, 4.0))
val kernelDensity=new KernelDensity()
.setSample(sample) //设置密度估计样本
.setBandwidth(3.0) //设置带宽,对高斯核函数来讲就是标准差
//给定相应的点,估计其概率密度
//densities: Array[Double] =
//Array(0.07464879256673691, 0.1113106036883375, 0.08485447240456075)
val densities = kernelDensity.estimate(Array(-1.0, 2.0, 5.0))

3. Hypothesis testing(假设检验)

假设检测在统计学中用于通过假设条件将样本进行总体推断,从而做出接受或拒绝假设判断,假设检验的方法很多,具体可参考http://baike.baidu.com/link?url=f3DhyOL_9OLVupNkCk82fdOhYOvYKzTWSVNyJqDNBD2hqr1nSlxmqpMiStqnWgNrW3ni9U_kZgy2GA5_8kSAHa。目前Spark中只提供了皮尔森chi平方距离检测法(Pearson’s chi-squared ( χ2) ),也称卡方检验,它由统计学家皮尔逊推导。理论证明,实际观察次数(fo)与理论次数(fe)之差的平方再除以理论次数所得的统计量,近似服从卡方分布。卡方检验的两个主要应用:拟合性检验和独立性检验,拟合性检验是用于分析实际次数与理论次数是否相同,适用于单个因素分类的计数数据。独立性检验用于分析各有多项分类的两个或两个以上的因素之间是否有关联或是否独立的问题(参见http://en.wikipedia.org/wiki/Chi-squared_test)。在Spark中,拟合度检验要求输入为Vector, 独立性检验要求输入是Matrix,另外还支持RDD[LabeledPoint]的独立性检验。对应方法如下:

//对带标签的特征向量进行独立性检验LabeledPoint,返回Array[ChiSqTestResult]
//目前只支持PEARSON法即卡方检验
/**
* Conduct Pearson's independence test for each feature against the label across the input RDD.
* The contingency table is constructed from the raw (feature, label) pairs and used to conduct
* the independence test.
* Returns an array containing the ChiSquaredTestResult for every feature against the label.
*/

def chiSquaredFeatures(data: RDD[LabeledPoint],
methodName: String = PEARSON.name): Array[ChiSqTestResult]


//拟合度检验,针对Vector,目前只支持PEARSON法即卡方检验
/*
* Pearson's goodness of fit test on the input observed and expected counts/relative frequencies.
* Uniform distribution is assumed when `expected` is not passed in.
*/

def chiSquared(observed: Vector,
expected: Vector = Vectors.dense(Array[Double]()),
methodName: String = PEARSON.name): ChiSqTestResult

//独立性检验,要求输入为Matrix,目前只支持PEARSON法即卡方检验
/*
* Pearson's independence test on the input contingency matrix.
* TODO: optimize for SparseMatrix when it becomes supported.
*/

def chiSquaredMatrix(counts: Matrix, methodName: String = PEARSON.name): ChiSqTestResult

假设有两块土地,通过下列数据来检验其开红花的比率是否相同:
土地一, 开红花:1000,开兰花:1856
土地二, 开红花:400.,开兰花:560

具体使用代码如下:

val land1 = Vectors.dense(1000.0, 1856.0)
val land2 = Vectors.dense(400, 560)
val c1 = Statistics.chiSqTest(land1, land2)

执行结果:

c1: org.apache.spark.mllib.stat.test.ChiSqTestResult = 
Chi squared test summary:
method: pearson
degrees of freedom = 1
statistic = 52.0048019207683
pValue = 5.536682223805656E-13
Very strong presumption against null hypothesis: observed follows the same distribution as expected..

单从结果来看,两组数据满足相同的分布