首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阿帕奇火花-两样本Kolmogorov-Smirnov试验

阿帕奇火花-两样本Kolmogorov-Smirnov试验
EN

Stack Overflow用户
提问于 2017-09-28 14:15:17
回答 1查看 3.3K关注 0票数 4

我在星火中有两组数据(我们称之为d1,d2)。我想做一个两个样本的Kolmogorov测试,来测试它们潜在的分配函数是否不同。MLLib的Statistics.kolmogorovSmirnovTest能做到这一点吗?

文档提供了以下示例:

代码语言:javascript
复制
import org.apache.spark.mllib.stat.Statistics

val data: RDD[Double] = ... // an RDD of sample data

// perform a KS test using a cumulative distribution function of our making
val myCDF: Double => Double = ...
val testResult2 = Statistics.kolmogorovSmirnovTest(data, myCDF)

我尝试计算了d2的经验累积分布函数(以地图的形式收集),并与d1进行了比较。

代码语言:javascript
复制
Statistics.kolmogorovSmirnovTest(d1, ecdf_map)

测试运行,但结果是错误的。

我做错了什么吗?有可能这样做吗?有什么想法吗?

谢谢你的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-06 13:23:15

在Spark中,KolmogorovSmirnovTest是一个采样和双面的。因此,如果您想要具体的两个样本变体,在这个库中是不可能的。但是,您仍然可以通过计算经验累积分布函数来比较数据集(我找到了一个这样做的库,如果结果好的话,我将更新这个答案),或者使用偏离正态分布的方法。在本例中,我将介绍后面的内容。

KST统计量与正态分布数据集的比较

为了测试的目的,我生成了3个发行版:2个看起来类似的三角状,一个指数型版本,以显示出统计数据的巨大差异。

注:,我找不到任何科学论文,把这个方法描述为可行的分布比较,所以这个想法大多是经验的。 对于每个分布,您最明确地可以找到一个镜像分布,在它的CDF和正态分布之间具有相同的全局最大距离。

下一步是得到具有给定均值和标准差的正态分布的KS结果。我把它们想象成更好的画面:

正如你所看到的,三角分布的结果(KS统计量和p值)是接近的,而指数分布的结果则相差很远。正如我在说明中指出的,您可以很容易地通过镜像数据集来欺骗此方法,但是对于真实世界的数据,这是可以的。

代码语言:javascript
复制
import org.apache.spark._
import org.apache.spark.rdd.RDD
import org.apache.spark.mllib.stat.Statistics

import org.apache.commons.math3.distribution.{ ExponentialDistribution, TriangularDistribution }

import breeze.plot._
import breeze.linalg._
import breeze.numerics._

object Main {

    def main( args: Array[ String ] ): Unit = {

        val conf = 
            new SparkConf()
            .setAppName( "SO Spark" )
            .setMaster( "local[*]" )
            .set( "spark.driver.host", "localhost" )

        val sc = new SparkContext( conf )

        // Create similar distributions
        val triDist1 = new TriangularDistribution( -3, 5, 7 )
        val triDist2 = new TriangularDistribution( -3, 7, 7 )

        // Exponential distribution to show big difference
        val expDist1 = new ExponentialDistribution( 0.6 )

        // Sample data from the distributions and parallelize it
        val n = 100000
        val sampledTriDist1 = sc.parallelize( triDist1.sample( n ) )
        val sampledTriDist2 = sc.parallelize( triDist2.sample( n ) )
        val sampledExpDist1 = sc.parallelize( expDist1.sample( n ) )

        // KS tests
        val resultTriDist1 = Statistics
            .kolmogorovSmirnovTest( sampledTriDist1, 
                                    "norm", 
                                    sampledTriDist1.mean, 
                                    sampledTriDist1.stdev )

        val resultTriDist2 = Statistics
            .kolmogorovSmirnovTest( sampledTriDist2, 
                                    "norm", 
                                    sampledTriDist2.mean, 
                                    sampledTriDist2.stdev )

        val resultExpDist1 = Statistics
            .kolmogorovSmirnovTest( sampledExpDist1, 
                                    "norm", 
                                    sampledExpDist1.mean, 
                                    sampledExpDist1.stdev )

        // Results
        val statsTriDist1 = 
            "Tri1: ( " + 
            resultTriDist1.statistic + 
            ", " + 
            resultTriDist1.pValue + 
            " )"

        val statsTriDist2 = 
            "Tri2: ( " + 
            resultTriDist2.statistic + 
            ", " + 
            resultTriDist2.pValue + 
            " )"

        val statsExpDist1 = 
            "Exp1: ( " + 
            resultExpDist1.statistic + 
            ", " + 
            resultExpDist1.pValue + 
            " )"  

        println( statsTriDist1 )
        println( statsTriDist2 )
        println( statsExpDist1 )

        // Visualize
        val graphCanvas = Figure()

        val mainPlot = 
            graphCanvas
            .subplot( 0 )

        mainPlot.legend = true

        val x = linspace( 1, n, n )      

        mainPlot += plot( x, 
                          sampledTriDist1.sortBy( x => x ).take( n ), 
                          name = statsTriDist1 )

        mainPlot += plot( x, 
                          sampledTriDist2.sortBy( x => x ).take( n ), 
                          name = statsTriDist2 )

        mainPlot += plot( x, 
                          sampledExpDist1.sortBy( x => x ).take( n ), 
                          name = statsExpDist1 )

        mainPlot.xlabel = "x"
        mainPlot.ylabel = "sorted sample"

        mainPlot.title = "KS results for 2 Triangular and 1 Exponential Distributions"

        graphCanvas.saveas( "ks-sample.png", 300 )

        sc.stop()
    }
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46471399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档