spark ChiSqTest Statistics卡方统计用法示例源码详解
ChiSqTest
用法
源码分析
org.apache.spark.mllib.stat.test.ChiSqTest
是Spark中用于执行卡方检验的类。它提供了计算卡方检验的方法,包括拟合度检验(goodness-of-fit test)和独立性检验(test of independence),以及计算每个特征与标签之间卡方统计量的方法。
关键点总结如下:
- 类定义:
private[spark] object ChiSqTest extends Logging
- 方法:
chiSquaredFeatures
方法:对输入的RDD的每个特征与标签进行Pearson独立性检验,返回一个包含每个特征与标签之间的ChiSquaredTestResult的数组。chiSquared
方法:对输入的观察值和期望值进行Pearson的拟合度检验,返回一个ChiSquaredTestResult对象。chiSquaredMatrix
方法:对输入的列联表进行Pearson的独立性检验,返回一个ChiSquaredTestResult对象。
- 常量:
maxCategories
:索引标签和特征时的最大类别数,默认为10000。
- 内部类:
Method
:表示卡方检验的方法,包括方法名称和计算统计量的函数。NullHypothesis
:枚举类型,表示不同类型卡方检验的零假设。
该类还包含一些辅助方法,如解析方法名称、验证输入参数等。
中文源码
package org.apache.spark.mllib.stat.test
import scala.collection.mutable
import breeze.linalg.{DenseMatrix => BDM}
import org.apache.commons.math3.distribution.ChiSquaredDistribution
import org.apache.spark.SparkException
import org.apache.spark.internal.Logging
import org.apache.spark.mllib.linalg.{Matrices, Matrix, Vector, Vectors}
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.rdd.RDD
/**
* 使用指定的方法对输入的RDD进行卡方检验。
* 对于两个向量,进行拟合度检验(goodness-of-fit test);
* 对于矩阵,进行独立性检验(test of independence),评估列之间是否独立。
* 还提供了一种方法,用于计算输入RDD中每个特征与标签之间的卡方统计量,
* 返回一个大小为特征数量的`Array[ChiSquaredTestResult]`。
*
* 支持的拟合度检验方法:`pearson`(默认)
* 支持的独立性检验方法:`pearson`(默认)
*
* 更多关于卡方检验的信息:http://en.wikipedia.org/wiki/Chi-squared_test
*/
private[spark] object ChiSqTest extends Logging {
/**
* @param name 方法的名称。
* @param chiSqFunc 计算统计量的函数,给定观察值和期望值。
*/
case class Method(name: String, chiSqFunc: (Double, Double) => Double)
// Pearson's chi-squared test: http://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test
val PEARSON = new Method("pearson", (observed: Double, expected: Double) => {
val dev = observed - expected
dev * dev / expected
})
// 不同类型的卡方检验的零假设,将包含在结果中。
object NullHypothesis extends Enumeration {
type NullHypothesis = Value
val goodnessOfFit = Value("观察值遵循与期望值相同的分布。")
val independence = Value("结果的出现是统计独立的。")
}
// 根据输入的方法名称返回对应的方法
private def methodFromString(methodName: String): Method = {
methodName match {
case PEARSON.name => PEARSON
case _ => throw new IllegalArgumentException("未知的卡方检验方法。")
}
}
/**
* 索引标签和特征时的最大类别数
*/
private[spark] val maxCategories: Int = 10000
/**
* 对输入RDD的每个特征与标签进行Pearson独立性检验。
* 构建由原始(特征,标签)对构成的列联表,并用其进行独立性检验。
* 返回一个包含每个特征与标签之间的ChiSquaredTestResult的数组。
*/
def chiSquaredFeatures(data: RDD[LabeledPoint],
methodName: String = PEARSON.name): Array[ChiSqTestResult] = {
val numCols = data.first().features.size
val results = new Array[ChiSqTestResult](numCols)
var labels: Map[Double, Int] = null
// 每次最多处理1000列
val batchSize = 1000
var batch = 0
while (batch * batchSize < numCols) {
// 下面的代码块可以整理并公开为 chiSquared(data: RDD[(V1, V2)]) 方法
val startCol = batch * batchSize
val endCol = startCol + math.min(batchSize, numCols - startCol)
val pairCounts = data.mapPartitions { iter =>
val distinctLabels = mutable.HashSet.empty[Double]
val allDistinctFeatures: Map[Int, mutable.HashSet[Double]] =
Map((startCol until endCol).map(col => (col, mutable.HashSet.empty[Double])): _*)
var i = 1
iter.flatMap { case LabeledPoint(label, features) =>
if (i % 1000 == 0) {
if (distinctLabels.size > maxCategories) {
throw new SparkException(s"卡方检验期望因子(分类值),但发现了超过$maxCategories个不同的标签值。")
}
allDistinctFeatures.foreach { case (col, distinctFeatures) =>
if (distinctFeatures.size > maxCategories) {
throw new SparkException(s"卡方检验期望因子(分类值),但在第$col列中发现了超过$maxCategories个不同的值。")
}
}
}
i += 1
distinctLabels += label
val brzFeatures = features.asBreeze
(startCol until endCol).map { col =>
val feature = brzFeatures(col)
allDistinctFeatures(col) += feature
(col, feature, label)
}
}
}.countByValue()
if (labels == null) {
// 仅对第一列进行此操作,因为标签在特征之间是不变的。
labels =
pairCounts.keys.filter(_._1 == startCol).map(_._3).toArray.distinct.zipWithIndex.toMap
}
val numLabels = labels.size
pairCounts.keys.groupBy(_._1).foreach { case (col, keys) =>
val features = keys.map(_._2).toArray.distinct.zipWithIndex.toMap
val numRows = features.size
val contingency = new BDM(numRows, numLabels, new Array[Double](numRows * numLabels))
keys.foreach { case (_, feature, label) =>
val i = features(feature)
val j = labels(label)
contingency(i, j) += pairCounts((col, feature, label))
}
results(col) = chiSquaredMatrix(Matrices.fromBreeze(contingency), methodName)
}
batch += 1
}
results
}
/*
* 对输入的观察值和期望值进行Pearson的拟合度检验。
* 当没有传入`expected`时,假设服从均匀分布。
*/
def chiSquared(observed: Vector,
expected: Vector = Vectors.dense(Array.empty[Double]),
methodName: String = PEARSON.name): ChiSqTestResult = {
// 验证输入参数
val method = methodFromString(methodName)
if (expected.size != 0 && observed.size != expected.size) {
throw new IllegalArgumentException("观察值和期望值必须具有相同的大小。")
}
val size = observed.size
if (size > 1000) {
logWarning("由于期望频率较低,卡方近似可能不准确,这是由于类别数较多导致的: $size.")
}
val obsArr = observed.toArray
val expArr = if (expected.size == 0) Array.tabulate(size)(_ => 1.0 / size) else expected.toArray
if (!obsArr.forall(_ >= 0.0)) {
throw new IllegalArgumentException("观察向量中不允许出现负值。")
}
if (expected.size != 0 && !expArr.forall(_ >= 0.0)) {
throw new IllegalArgumentException("期望向量中不允许出现负值。")
}
// 确定期望的缩放因子
val obsSum = obsArr.sum
val expSum = if (expected.size == 0.0) 1.0 else expArr.sum
val scale = if (math.abs(obsSum - expSum) < 1e-7) 1.0 else obsSum / expSum
// 计算卡方统计量
val statistic = obsArr.zip(expArr).foldLeft(0.0) { case (stat, (obs, exp)) =>
if (exp == 0.0) {
if (obs == 0.0) {
throw new IllegalArgumentException("由于观察值和期望值都为0,无法计算卡方统计量。")
} else {
return new ChiSqTestResult(0.0, size - 1, Double.PositiveInfinity, PEARSON.name,
NullHypothesis.goodnessOfFit.toString)
}
}
if (scale == 1.0) {
stat + method.chiSqFunc(obs, exp)
} else {
stat + method.chiSqFunc(obs, exp * scale)
}
}
val df = size - 1
val pValue = 1.0 - new ChiSquaredDistribution(df).cumulativeProbability(statistic)
new ChiSqTestResult(pValue, df, statistic, PEARSON.name, NullHypothesis.goodnessOfFit.toString)
}
/*
* 对输入的列联表进行Pearson的独立性检验。
* TODO: 在支持稀疏矩阵时进行优化。
*/
def chiSquaredMatrix(counts: Matrix, methodName: String = PEARSON.name): ChiSqTestResult = {
val method = methodFromString(methodName)
val numRows = counts.numRows
val numCols = counts.numCols
// 获取行和列的和
val colSums = new Array[Double](numCols)
val rowSums = new Array[Double](numRows)
val colMajorArr = counts.toArray
val colMajorArrLen = colMajorArr.length
var i = 0
while (i < colMajorArrLen) {
val elem = colMajorArr(i)
if (elem < 0.0) {
throw new IllegalArgumentException("列联表不能包含负值。")
}
colSums(i / numRows) += elem
rowSums(i % numRows) += elem
i += 1
}
val total = colSums.sum
// 第二次遍历计算统计量
var statistic = 0.0
var j = 0
while (j < colMajorArrLen) {
val col = j / numRows
val colSum = colSums(col)
if (colSum == 0.0) {
throw new IllegalArgumentException("由于第 [$col] 列的和为0,无法计算输入矩阵的卡方统计量。")
}
val row = j % numRows
val rowSum = rowSums(row)
if (rowSum == 0.0) {
throw new IllegalArgumentException("由于第 [$row] 行的和为0,无法计算输入矩阵的卡方统计量。")
}
val expected = colSum * rowSum / total
statistic += method.chiSqFunc(colMajorArr(j), expected)
j += 1
}
val df = (numCols - 1) * (numRows - 1)
if (df == 0) {
// 只有1列或1行。常数分布与任何内容都是独立的。
// 在这种情况下,pValue = 1.0 和 statistic = 0.0。
new ChiSqTestResult(1.0, 0, 0.0, methodName, NullHypothesis.independence.toString)
} else {
val pValue = 1.0 - new ChiSquaredDistribution(df).cumulativeProbability(statistic)
new ChiSqTestResult(pValue, df, statistic, methodName, NullHypothesis.independence.toString)
}
}
}
Statistics
用法
Spark MLlib的Statistics
类提供了一组用于统计分析的方法。以下是对每个方法的总结和用法:
-
colStats(X: RDD[Vector]): MultivariateStatisticalSummary
- 计算输入RDD[Vector]的列统计摘要。
- 返回包含列统计摘要的
MultivariateStatisticalSummary
对象。 - 示例:
val X: RDD[Vector] = ??? val summary: MultivariateStatisticalSummary = Statistics.colStats(X)
-
corr(X: RDD[Vector]): Matrix
- 计算输入RDD[Vector]的Pearson相关矩阵。
- 返回比较X中列的Pearson相关矩阵。
- 示例:
val X: RDD[Vector] = ??? val corrMatrix: Matrix = Statistics.corr(X)
-
corr(X: RDD[Vector], method: String): Matrix
- 使用指定的方法计算输入RDD[Vector]的相关矩阵。
- 目前支持的方法有
pearson
(默认)和spearman
。 - 示例:
val X: RDD[Vector] = ??? val corrMatrix: Matrix = Statistics.corr(X, "spearman")
-
corr(x: RDD[Double], y: RDD[Double]): Double
- 计算两个输入RDD[Double]的Pearson相关系数。
- 返回两个输入RDD[Double]之间的Pearson相关系数。
- 示例:
val x: RDD[Double] = ??? val y: RDD[Double] = ??? val correlation: Double = Statistics.corr(x, y)
-
corr(x: RDD[Double], y: RDD[Double], method: String): Double
- 使用指定的方法计算两个输入RDD[Double]的相关系数。
- 目前支持的方法有
pearson
(默认)和spearman
。 - 返回使用指定方法计算的两个输入RDD[Double]之间的相关系数。
- 示例:
val x: RDD[Double] = ??? val y: RDD[Double] = ??? val correlation: Double = Statistics.corr(x, y, "spearman")
-
chiSqTest(observed: Vector, expected: Vector): ChiSqTestResult
- 对观测数据进行Pearson卡方拟合度检验,验证其是否符合期望的分布。
- 返回包含检验统计量、自由度、p-value、使用的方法和零假设的
ChiSqTestResult
对象。 - 示例:
val observed: Vector = ??? val expected: Vector = ??? val result: ChiSqTestResult = Statistics.chiSqTest(observed, expected)
-
chiSqTest(observed: Vector): ChiSqTestResult
- 对观测数据进行Pearson卡方拟合度检验,验证其是否符合均匀分布。
- 返回包含检验统计量、自由度、p-value、使用的方法和零假设的
ChiSqTestResult
对象。 - 示例:
val observed: Vector = ??? val result: ChiSqTestResult = Statistics.chiSqTest(observed)
-
chiSqTest(observed: Matrix): ChiSqTestResult
- 对输入的列联表进行Pearson独立性检验。
- 返回包含检验统计量、自由度、p-value、使用的方法和零假设的
ChiSqTestResult
对象。 - 示例:
val observed: Matrix = ??? val result: ChiSqTestResult = Statistics.chiSqTest(observed)
-
chiSqTest(data: RDD[LabeledPoint]): Array[ChiSqTestResult]
- 在输入RDD上对每个特征相对于标签进行Pearson独立性检验。
- 返回包含每个特征相对于标签的
ChiSqTestResult
的数组。 - 示例:
val data: RDD[LabeledPoint] = ??? val results: Array[ChiSqTestResult] = Statistics.chiSqTest(data)
-
kolmogorovSmirnovTest(data: RDD[Double], cdf: Double => Double): KolmogorovSmirnovTestResult
- 对从连续分布中采样的数据进行双边Kolmogorov-Smirnov(KS)检验。
- 返回包含测试统计量、p-value和零假设的
KolmogorovSmirnovTestResult
对象。 - 示例:
val data: RDD[Double] = ??? val cdf: Double => Double = ??? val result: KolmogorovSmirnovTestResult = Statistics.kolmogorovSmirnovTest(data, cdf)
-
kolmogorovSmirnovTest(data: RDD[Double], distName: String, params: Double*): KolmogorovSmirnovTestResult
- 进行一样本、双边Kolmogorov-Smirnov(KS)概率分布相等性检验的便捷函数。
- 支持的理论分布有正态分布(
distName = "norm"
)。 - 返回包含测试统计量、p-value和零假设的
KolmogorovSmirnovTestResult
对象。 - 示例:
val data: RDD[Double] = ??? val distName: String = ??? val params: Double* = ??? val result: KolmogorovSmirnovTestResult = Statistics.kolmogorovSmirnovTest(data, distName, params: _*)
这些方法可以帮助您进行统计分析,例如计算列统计摘要、相关矩阵、相关系数,以及进行卡方拟合度检验和KS检验。根据您的需求,选择适当的方法并提供所需的输入数据即可。
示例
package org.example.spark
import org.apache.spark.mllib.linalg._
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.stat.{MultivariateStatisticalSummary, Statistics}
import org.apache.spark.mllib.stat.test.ChiSqTestResult
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession
object StatisticsExample {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder()
.appName("StatisticsExample")
.master("local[*]")
.getOrCreate()
val sc = spark.sparkContext
sc.setLogLevel("error")
// 示例数据
val vec: Vector = Vectors.dense(0.1, 0.15, 0.2, 0.3, 0.25)
val mat: Matrix = Matrices.dense(3, 3, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0,7.0,8.0,9.0))
val obs: RDD[LabeledPoint] = sc.parallelize(Seq(
LabeledPoint(1.0, Vectors.dense(1.0, 0.0, 3.0)),
LabeledPoint(1.0, Vectors.dense(1.0, 2.0, 0.0)),
LabeledPoint(-1.0, Vectors.dense(-1.0, 0.0, -0.5))
))
val v1 = Vectors.dense(176, 406)
val v2 = Vectors.dense(210, 372)
// 计算列统计摘要
val summary: MultivariateStatisticalSummary = Statistics.colStats(obs.map(_.features))
println("Column Summary Statistics:")
println(s"Mean: ${summary.mean}")
println(s"Variance: ${summary.variance}")
// 计算Pearson相关矩阵
val corrMatrix: Matrix = Statistics.corr(obs.map(_.features), "pearson")
println("\nPearson Correlation Matrix:")
println(corrMatrix)
// 进行卡方拟合度检验
val observed: Vector = Vectors.dense(10, 20, 30)
val expected: Vector = Vectors.dense(15, 15, 30)
val chiSqTestResult: ChiSqTestResult = Statistics.chiSqTest(observed, expected)
println("\nChi-Square Goodness of Fit Test:")
println(chiSqTestResult)
// 进行独立性检验
val independenceTestResult: ChiSqTestResult = Statistics.chiSqTest(mat)
println("\nChi-Square Independence Test:")
println(independenceTestResult)
// 对每个特征相对于标签进行独立性检验
val featureTestResults: Array[ChiSqTestResult] = Statistics.chiSqTest(obs)
println("\nFeature Independence Tests:")
featureTestResults.zipWithIndex.foreach { case (result, index) =>
println(s"Feature ${index + 1}:")
println(result)
}
// chi test
val chiTestResult = Statistics.chiSqTest(v1, v2)
println(chiTestResult)
spark.stop()
}
}
//Column Summary Statistics:
//Mean: [0.3333333333333333,0.6666666666666666,0.8333333333333333]
//Variance: [1.3333333333333333,1.3333333333333333,3.5833333333333335]
//
//Pearson Correlation Matrix:
//1.0 0.5 0.6099942813304188
//0.5 1.0 -0.3812464258315116
//0.6099942813304188 -0.3812464258315116 1.0
//
//Chi-Square Goodness of Fit Test:
//Chi squared test summary:
//method: pearson
//degrees of freedom = 2
//statistic = 3.3333333333333335
//pValue = 0.1888756028375621
//No presumption against null hypothesis: observed follows the same distribution as expected..
//
//Chi-Square Independence Test:
//Chi squared test summary:
//method: pearson
//degrees of freedom = 4
//statistic = 1.78125
//pValue = 0.7759109366353244
//No presumption against null hypothesis: the occurrence of the outcomes is statistically independent..
//
//Feature Independence Tests:
//Feature 1:
//Chi squared test summary:
//method: pearson
//degrees of freedom = 1
//statistic = 3.0000000000000004
//pValue = 0.08326451666354884
//Low presumption against null hypothesis: the occurrence of the outcomes is statistically independent..
//Feature 2:
//Chi squared test summary:
//method: pearson
//degrees of freedom = 1
//statistic = 0.75
//pValue = 0.3864762307712326
//No presumption against null hypothesis: the occurrence of the outcomes is statistically independent..
//Feature 3:
//Chi squared test summary:
//method: pearson
//degrees of freedom = 2
//statistic = 3.0
//pValue = 0.22313016014843035
//No presumption against null hypothesis: the occurrence of the outcomes is statistically independent..
//Chi squared test summary:
//method: pearson
//degrees of freedom = 1
//statistic = 8.612288786482335
//pValue = 0.003339024479776409
//Very strong presumption against null hypothesis: observed follows the same distribution as expected..
//
//
中文源码
/**
* MLlib中统计函数的API。
*/
@Since("1.1.0")
object Statistics {
/**
* 计算输入RDD[Vector]的列统计摘要。
*
* @param X 要计算列统计摘要的RDD[Vector]。
* @return 包含列统计摘要的[[MultivariateStatisticalSummary]]对象。
*/
@Since("1.1.0")
def colStats(X: RDD[Vector]): MultivariateStatisticalSummary = {
new RowMatrix(X).computeColumnSummaryStatistics()
}
/**
* 计算输入RDD[Vector]的Pearson相关矩阵。
* 协方差为0的列在相关矩阵中产生NaN条目。
*
* @param X 要计算相关矩阵的RDD[Vector]。
* @return 比较X中列的Pearson相关矩阵。
*/
@Since("1.1.0")
def corr(X: RDD[Vector]): Matrix = Correlations.corrMatrix(X)
/**
* 使用指定的方法计算输入RDD[Vector]的相关矩阵。
* 目前支持的方法:`pearson`(默认)、`spearman`。
*
* @param X 要计算相关矩阵的RDD[Vector]。
* @param method 指定用于计算相关性的方法的字符串。
* 支持:`pearson`(默认)、`spearman`
* @return 比较X中列的相关矩阵。
*
* @note 对于Spearman相关性(一种等级相关性),我们需要为每列创建一个RDD[Double],
* 并对其进行排序以获取排名,然后将列重新连接成一个RDD[Vector],这是非常耗时的操作。
* 在调用`method = "spearman"`的corr之前,先缓存输入RDD,以避免重新计算公共血统。
*/
@Since("1.1.0")
def corr(X: RDD[Vector], method: String): Matrix = Correlations.corrMatrix(X, method)
/**
* 计算两个输入RDD[Double]的Pearson相关系数。
* 如果任一向量方差为0,则返回NaN。
*
* @param x 与y具有相同基数的RDD[Double]。
* @param y 与x具有相同基数的RDD[Double]。
* @return 包含两个输入RDD[Double]之间的Pearson相关系数的Double。
*
* @note 两个输入RDD需要具有相同数量的分区和每个分区中的相同数量的元素。
*/
@Since("1.1.0")
def corr(x: RDD[Double], y: RDD[Double]): Double = Correlations.corr(x, y)
/**
* `corr()`的Java友好版本
*/
@Since("1.4.1")
def corr(x: JavaRDD[java.lang.Double], y: JavaRDD[java.lang.Double]): Double =
corr(x.rdd.asInstanceOf[RDD[Double]], y.rdd.asInstanceOf[RDD[Double]])
/**
* 使用指定的方法计算两个输入RDD[Double]的相关系数。
* 目前支持的方法:`pearson`(默认)、`spearman`。
*
* @param x 与y具有相同基数的RDD[Double]。
* @param y 与x具有相同基数的RDD[Double]。
* @param method 指定用于计算相关性的方法的字符串。
* 支持:`pearson`(默认)、`spearman`
* @return 包含使用指定方法计算的两个输入RDD[Double]之间的相关系数的Double。
*
* @note 两个输入RDD需要具有相同数量的分区和每个分区中的相同数量的元素。
*/
@Since("1.1.0")
def corr(x: RDD[Double], y: RDD[Double], method: String): Double = Correlations.corr(x, y, method)
/**
* `corr()`的Java友好版本
*/
@Since("1.4.1")
def corr(x: JavaRDD[java.lang.Double], y: JavaRDD[java.lang.Double], method: String): Double =
corr(x.rdd.asInstanceOf[RDD[Double]], y.rdd.asInstanceOf[RDD[Double]], method)
/**
* 对观测数据进行Pearson卡方拟合度检验,以验证其是否符合期望的分布。
*
* @param observed 包含观测分类计数/相对频率的向量。
* @param expected 包含期望分类计数/相对频率的向量。
* 如果`expected`总和与`observed`总和不同,则会重新调整`expected`。
* @return 包含检验统计量、自由度、p-value、使用的方法和零假设的ChiSquaredTestResult对象。
*
* @note 两个输入向量需要具有相同的大小。
* `observed`不能包含负值。
* `expected`不能包含非正值。
*/
@Since("1.1.0")
def chiSqTest(observed: Vector, expected: Vector): ChiSqTestResult = {
ChiSqTest.chiSquared(observed, expected)
}
/**
* 对观测数据进行Pearson卡方拟合度检验,以验证其是否符合均匀分布,
* 其中每个类别的期望频率为`1 / observed.size`。
*
* @param observed 包含观测分类计数/相对频率的向量。
* @return 包含检验统计量、自由度、p-value、使用的方法和零假设的ChiSquaredTestResult对象。
*
* @note `observed`不能包含负值。
*/
@Since("1.1.0")
def chiSqTest(observed: Vector): ChiSqTestResult = ChiSqTest.chiSquared(observed)
/**
* 对输入的列联表进行Pearson独立性检验,其中不能包含负条目或列或行总和为0。
*
* @param observed 列联表(包含计数或相对频率)。
* @return 包含检验统计量、自由度、p-value、使用的方法和零假设的ChiSquaredTestResult对象。
*/
@Since("1.1.0")
def chiSqTest(observed: Matrix): ChiSqTestResult = ChiSqTest.chiSquaredMatrix(observed)
/**
* 在输入RDD上对每个特征相对于标签进行Pearson独立性检验。
* 对于每个特征,(特征,标签)对被转换为列联表,并计算卡方统计量。
* 所有标签和特征值必须是分类的。
*
* @param data 包含具有分类特征的标记数据集的`RDD[LabeledPoint]`。
* 实数特征将被视为每个不同值都是分类的。
* @return 包含每个特征相对于标签的ChiSquaredTestResult的数组。
* 返回的数组中元素的顺序反映了输入特征的顺序。
*/
@Since("1.1.0")
def chiSqTest(data: RDD[LabeledPoint]): Array[ChiSqTestResult] = {
ChiSqTest.chiSquaredFeatures(data)
}
/**
* `chiSqTest()`的Java友好版本
*/
@Since("1.5.0")
def chiSqTest(data: JavaRDD[LabeledPoint]): Array[ChiSqTestResult] = chiSqTest(data.rdd)
/**
* 对从连续分布中采样的数据进行双边Kolmogorov-Smirnov(KS)检验。
* 通过比较样本数据的经验累积分布与理论分布之间的最大差异,
* 我们可以提供一个测试,用于验证样本数据是否来自该理论分布的零假设。
* 有关KS检验的更多信息:
* @see <a href="https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test">
* Kolmogorov-Smirnov test (Wikipedia)</a>
*
* @param data 要测试的样本数据的`RDD[Double]`。
* @param cdf 计算给定值处的理论CDF的`Double => Double`函数。
* @return 包含测试统计量、p-value和零假设的[[org.apache.spark.mllib.stat.test.KolmogorovSmirnovTestResult]]对象。
*/
@Since("1.5.0")
def kolmogorovSmirnovTest(data: RDD[Double], cdf: Double => Double)
: KolmogorovSmirnovTestResult = {
KolmogorovSmirnovTest.testOneSample(data, cdf)
}
/**
* 进行一样本、双边Kolmogorov-Smirnov(KS)概率分布相等性检验的便捷函数。
* 当前支持正态分布,参数为均值和标准差。
* (distName = "norm")
* @param data 要测试的样本数据的`RDD[Double]`。
* @param distName 理论分布的名称的字符串。
* @param params 用于理论分布的参数的`Double*`。
* @return 包含测试统计量、p-value和零假设的[[org.apache.spark.mllib.stat.test.KolmogorovSmirnovTestResult]]对象。
*/
@Since("1.5.0")
@varargs
def kolmogorovSmirnovTest(data: RDD[Double], distName: String, params: Double*)
: KolmogorovSmirnovTestResult = {
KolmogorovSmirnovTest.testOneSample(data, distName, params: _*)
}
/**
* `kolmogorovSmirnovTest()`的Java友好版本
*/
@Since("1.5.0")
@varargs
def kolmogorovSmirnovTest(
data: JavaDoubleRDD,
distName: String,
params: Double*): KolmogorovSmirnovTestResult = {
kolmogorovSmirnovTest(data.rdd.asInstanceOf[RDD[Double]], distName, params: _*)
}
}