私は2つのデータセットを持っています(d1、d2と呼ぶ)スパークで2つのサンプルのKolmogorov-Smirnovテストを実行して、それらの根本的なPoplation分布関数が異なるかどうかをテストしたいと思います。 MLLibは可能ですか? Statistics.kolmogorovSmirnovTest これを行う?
ドキュメントには、次の例があります。
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の経験的な累積分布関数を計算して(それをMapとして収集する)、それをd1と比較しようとしました。
Statistics.kolmogorovSmirnovTest(d1, ecdf_map)
テストは実行されますが、結果は間違っています。
私は何か間違っているのですか?これは可能ですか?何か案は?
お手伝いありがとう!
回答:
回答№1は2Spark Mllibで KolmogorovSmirnovTest 1サンプリングされ、両面である。 したがって、具体的に2標本化されたバリアントが必要な場合は、このライブラリ内では不可能ですが、経験的な累積分布関数を計算することでデータセットを比較することができます(ライブラリを見つけました。または正常な分布からの偏差を使用して)。この例では、後で説明します。
KST統計によるデータセットの正規分布との比較
このテストの目的のために私は3つのディストリビューションを生成しました:2 三角 同じように見える 指数関数的 1つは統計情報に大きな違いがあります。
注意: 私は、この方法を記述している科学論文を流通比較のために実行可能なものと見なすことができなかったので、その考えはほとんど実証的である。
すべての分布について、CDFと正規分布の間に同じグローバルな最大距離を持つ、ミラーリングされたものを見つけることができます。
次のステップは、与えられた平均および標準偏差で正規分布に対してKS結果を得ることであった。私はより良い画像を得るためにそれらを視覚化しました:
あなたが見ることができるように、結果(KS統計三角分布のp値は互いに近似しており、一方指数関数はオフである。私がこのノートで述べたように、この方法はデータセットをミラーリングすることで簡単にだますことができますが、実際の世界のデータでは問題ありません。
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()
}
}