기초 통계

기초 통계 (Basic Statistics)

이 페이지에서는 RDD 기반 API(spark.mllib)의 기초 통계 기능을 소개해요. 요약 통계, 상관관계, 층화 샘플링, 가설 검정, 스트리밍 유의성 검정, 랜덤 데이터 생성, 커널 밀도 추정을 다뤄요.

출처: Basic Statistics - RDD-based API

본문

요약 통계(Summary statistics)

Statistics에 있는 colStats 함수를 통해 RDD[Vector]에 대한 컬럼별 요약 통계를 제공해요.

colStats()MultivariateStatisticalSummary 인스턴스를 반환하는데, 컬럼별 최대값, 최소값, 평균, 분산, 0이 아닌 값의 수, 그리고 총 개수를 포함해요.

API에 대한 자세한 내용은 MultivariateStatisticalSummary Python 문서를 참고하세요.

import numpy as np

from pyspark.mllib.stat import Statistics

mat = sc.parallelize(
    [np.array([1.0, 10.0, 100.0]), np.array([2.0, 20.0, 200.0]), np.array([3.0, 30.0, 300.0])]
)  # an RDD of Vectors

# Compute column summary statistics.
summary = Statistics.colStats(mat)
print(summary.mean())  # a dense vector containing the mean value for each column
print(summary.variance())  # column-wise variance
print(summary.numNonzeros())  # number of nonzeros in each column

전체 예제 코드는 Spark 저장소의 "examples/src/main/python/mllib/summary_statistics_example.py"에서 찾을 수 있어요.

colStats()MultivariateStatisticalSummary 인스턴스를 반환하는데, 컬럼별 최대값, 최소값, 평균, 분산, 0이 아닌 값의 수, 그리고 총 개수를 포함해요.

API에 대한 자세한 내용은 MultivariateStatisticalSummary Scala 문서를 참고하세요.

import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.stat.{MultivariateStatisticalSummary, Statistics}

val observations = sc.parallelize(
  Seq(
    Vectors.dense(1.0, 10.0, 100.0),
    Vectors.dense(2.0, 20.0, 200.0),
    Vectors.dense(3.0, 30.0, 300.0)
  )
)

// Compute column summary statistics.
val summary: MultivariateStatisticalSummary = Statistics.colStats(observations)
println(summary.mean)  // a dense vector containing the mean value for each column
println(summary.variance)  // column-wise variance
println(summary.numNonzeros)  // number of nonzeros in each column

전체 예제 코드는 Spark 저장소의 "examples/src/main/scala/org/apache/spark/examples/mllib/SummaryStatisticsExample.scala"에서 찾을 수 있어요.

colStats()MultivariateStatisticalSummary 인스턴스를 반환하는데, 컬럼별 최대값, 최소값, 평균, 분산, 0이 아닌 값의 수, 그리고 총 개수를 포함해요.

API에 대한 자세한 내용은 MultivariateStatisticalSummary Java 문서를 참고하세요.

import java.util.Arrays;

import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.mllib.linalg.Vector;
import org.apache.spark.mllib.linalg.Vectors;
import org.apache.spark.mllib.stat.MultivariateStatisticalSummary;
import org.apache.spark.mllib.stat.Statistics;

JavaRDD<Vector> mat = jsc.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)
  )
); // an RDD of Vectors

// Compute column summary statistics.
MultivariateStatisticalSummary summary = Statistics.colStats(mat.rdd());
System.out.println(summary.mean());  // a dense vector containing the mean value for each column
System.out.println(summary.variance());  // column-wise variance
System.out.println(summary.numNonzeros());  // number of nonzeros in each column

전체 예제 코드는 Spark 저장소의 "examples/src/main/java/org/apache/spark/examples/mllib/JavaSummaryStatisticsExample.java"에서 찾을 수 있어요.

상관관계(Correlations)

두 데이터 시리즈 사이의 상관관계를 계산하는 것은 통계에서 흔한 연산이에요. spark.mllib에서 여러 시리즈 사이의 쌍별 상관관계를 계산할 수 있는 유연성을 제공해요. 지원되는 상관관계 방법은 현재 Pearson과 Spearman 상관관계예요.

Statistics는 시리즈 사이의 상관관계를 계산하는 메서드를 제공해요. 입력 타입에 따라 두 RDD[Double]이면 출력은 Double이 되고, RDD[Vector]이면 상관관계 Matrix가 돼요.

API에 대한 자세한 내용은 Statistics Python 문서를 참고하세요.

from pyspark.mllib.stat import Statistics

seriesX = sc.parallelize([1.0, 2.0, 3.0, 3.0, 5.0])  # a series
# seriesY must have the same number of partitions and cardinality as seriesX
seriesY = sc.parallelize([11.0, 22.0, 33.0, 33.0, 555.0])

# Compute the correlation using Pearson's method. Enter "spearman" for Spearman's method.
# If a method is not specified, Pearson's method will be used by default.
print("Correlation is: " + str(Statistics.corr(seriesX, seriesY, method="pearson")))

data = sc.parallelize(
    [np.array([1.0, 10.0, 100.0]), np.array([2.0, 20.0, 200.0]), np.array([5.0, 33.0, 366.0])]
)  # an RDD of Vectors

# calculate the correlation matrix using Pearson's method. Use "spearman" for Spearman's method.
# If a method is not specified, Pearson's method will be used by default.
print(Statistics.corr(data, method="pearson"))

전체 예제 코드는 Spark 저장소의 "examples/src/main/python/mllib/correlations_example.py"에서 찾을 수 있어요.

Statistics는 시리즈 사이의 상관관계를 계산하는 메서드를 제공해요. 입력 타입에 따라 두 RDD[Double]이면 출력은 Double이 되고, RDD[Vector]이면 상관관계 Matrix가 돼요.

API에 대한 자세한 내용은 Statistics Scala 문서를 참고하세요.

import org.apache.spark.mllib.linalg._
import org.apache.spark.mllib.stat.Statistics
import org.apache.spark.rdd.RDD

val seriesX: RDD[Double] = sc.parallelize(
  immutable.ArraySeq.unsafeWrapArray(Array(1.0, 2.0, 3.0, 3.0, 5.0)))  // a series
// must have the same number of partitions and cardinality as seriesX
val seriesY: RDD[Double] = sc.parallelize(
  immutable.ArraySeq.unsafeWrapArray(Array(11.0, 22.0, 33.0, 33.0, 555.0)))

// compute the correlation using Pearson's method. Enter "spearman" for Spearman's method. If a
// method is not specified, Pearson's method will be used by default.
val correlation: Double = Statistics.corr(seriesX, seriesY, "pearson")
println(s"Correlation is: $correlation")

val data: RDD[Vector] = sc.parallelize(
  Seq(
    Vectors.dense(1.0, 10.0, 100.0),
    Vectors.dense(2.0, 20.0, 200.0),
    Vectors.dense(5.0, 33.0, 366.0))
)  // note that each Vector is a row and not a column

// calculate the correlation matrix using Pearson's method. Use "spearman" for Spearman's method
// If a method is not specified, Pearson's method will be used by default.
val correlMatrix: Matrix = Statistics.corr(data, "pearson")
println(correlMatrix.toString)

전체 예제 코드는 Spark 저장소의 "examples/src/main/scala/org/apache/spark/examples/mllib/CorrelationsExample.scala"에서 찾을 수 있어요.

Statistics는 시리즈 사이의 상관관계를 계산하는 메서드를 제공해요. 입력 타입에 따라 두 JavaDoubleRDD이면 출력은 Double이 되고, JavaRDD<Vector>이면 상관관계 Matrix가 돼요.

API에 대한 자세한 내용은 Statistics Java 문서를 참고하세요.

import java.util.Arrays;

import org.apache.spark.api.java.JavaDoubleRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.mllib.linalg.Matrix;
import org.apache.spark.mllib.linalg.Vector;
import org.apache.spark.mllib.linalg.Vectors;
import org.apache.spark.mllib.stat.Statistics;

JavaDoubleRDD seriesX = jsc.parallelizeDoubles(
  Arrays.asList(1.0, 2.0, 3.0, 3.0, 5.0));  // a series

// must have the same number of partitions and cardinality as seriesX
JavaDoubleRDD seriesY = jsc.parallelizeDoubles(
  Arrays.asList(11.0, 22.0, 33.0, 33.0, 555.0));

// compute the correlation using Pearson's method. Enter "spearman" for Spearman's method.
// If a method is not specified, Pearson's method will be used by default.
double correlation = Statistics.corr(seriesX.srdd(), seriesY.srdd(), "pearson");
System.out.println("Correlation is: " + correlation);

// note that each Vector is a row and not a column
JavaRDD<Vector> data = jsc.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)
  )
);

// calculate the correlation matrix using Pearson's method.
// Use "spearman" for Spearman's method.
// If a method is not specified, Pearson's method will be used by default.
Matrix correlMatrix = Statistics.corr(data.rdd(), "pearson");
System.out.println(correlMatrix.toString());

전체 예제 코드는 Spark 저장소의 "examples/src/main/java/org/apache/spark/examples/mllib/JavaCorrelationsExample.java"에서 찾을 수 있어요.

층화 샘플링(Stratified sampling)

spark.mllib에 있는 다른 통계 함수와 달리, 층화 샘플링 메서드인 sampleByKeysampleByKeyExact는 키-값 쌍의 RDD에서 수행할 수 있어요. 층화 샘플링에서 키는 레이블로, 값은 특정 속성으로 생각할 수 있어요. 예를 들어 키는 남자나 여자, 또는 문서 ID일 수 있고, 각각의 값은 모집단 사람들의 나이 목록이나 문서의 단어 목록일 수 있어요. sampleByKey 메서드는 동전 던지기로 관측치를 샘플할지 말지 결정하므로 데이터를 한 번 순회하며 기대 샘플 크기를 제공해요. sampleByKeyExactsampleByKey에서 쓰는 층별 단순 랜덤 샘플링보다 훨씬 많은 자원을 필요로 하지만, 99.99% 신뢰도로 정확한 샘플링 크기를 제공해요. sampleByKeyExact는 현재 Python에서 지원되지 않아요.

sampleByKey()는 사용자가 각 키 $k \in K$에 대해 대략 $\lceil f_k \cdot n_k \rceil$개 항목을 샘플할 수 있게 해주는데, $f_k$는 키 $k$의 원하는 비율, $n_k$는 키 $k$의 키-값 쌍 수, $K$는 키 집합이에요.

참고: sampleByKeyExact()는 현재 Python에서 지원되지 않아요.

# an RDD of any key value pairs
data = sc.parallelize([(1, 'a'), (1, 'b'), (2, 'c'), (2, 'd'), (2, 'e'), (3, 'f')])

# specify the exact fraction desired from each key as a dictionary
fractions = {1: 0.1, 2: 0.6, 3: 0.3}

approxSample = data.sampleByKey(False, fractions)

전체 예제 코드는 Spark 저장소의 "examples/src/main/python/mllib/stratified_sampling_example.py"에서 찾을 수 있어요.

sampleByKeyExact()는 사용자가 각 키 $k \in K$에 대해 정확히 $\lceil f_k \cdot n_k \rceil$개 항목을 샘플할 수 있게 해주는데, $f_k$는 키 $k$의 원하는 비율, $n_k$는 키 $k$의 키-값 쌍 수, $K$는 키 집합이에요. 비복원 샘플링은 샘플 크기를 보장하기 위해 RDD를 한 번 더 순회해야 하고, 복원 샘플링은 두 번 더 순회해야 해요.

// an RDD[(K, V)] of any key value pairs
val data = sc.parallelize(
  Seq((1, 'a'), (1, 'b'), (2, 'c'), (2, 'd'), (2, 'e'), (3, 'f')))

// specify the exact fraction desired from each key
val fractions = Map(1 -> 0.1, 2 -> 0.6, 3 -> 0.3)

// Get an approximate sample from each stratum
val approxSample = data.sampleByKey(withReplacement = false, fractions = fractions)
// Get an exact sample from each stratum
val exactSample = data.sampleByKeyExact(withReplacement = false, fractions = fractions)

전체 예제 코드는 Spark 저장소의 "examples/src/main/scala/org/apache/spark/examples/mllib/StratifiedSamplingExample.scala"에서 찾을 수 있어요.

sampleByKeyExact()는 사용자가 각 키 $k \in K$에 대해 정확히 $\lceil f_k \cdot n_k \rceil$개 항목을 샘플할 수 있게 해주는데, $f_k$는 키 $k$의 원하는 비율, $n_k$는 키 $k$의 키-값 쌍 수, $K$는 키 집합이에요. 비복원 샘플링은 샘플 크기를 보장하기 위해 RDD를 한 번 더 순회해야 하고, 복원 샘플링은 두 번 더 순회해야 해요.

import java.util.*;

import scala.Tuple2;

import org.apache.spark.api.java.JavaPairRDD;

List<Tuple2<Integer, Character>> list = Arrays.asList(
    new Tuple2<>(1, 'a'),
    new Tuple2<>(1, 'b'),
    new Tuple2<>(2, 'c'),
    new Tuple2<>(2, 'd'),
    new Tuple2<>(2, 'e'),
    new Tuple2<>(3, 'f')
);

JavaPairRDD<Integer, Character> data = jsc.parallelizePairs(list);

// specify the exact fraction desired from each key Map<K, Double>
Map<Integer, Double> fractions = Map.of(1, 0.1, 2, 0.6, 3, 0.3);

// Get an approximate sample from each stratum
JavaPairRDD<Integer, Character> approxSample = data.sampleByKey(false, fractions);
// Get an exact sample from each stratum
JavaPairRDD<Integer, Character> exactSample = data.sampleByKeyExact(false, fractions);

전체 예제 코드는 Spark 저장소의 "examples/src/main/java/org/apache/spark/examples/mllib/JavaStratifiedSamplingExample.java"에서 찾을 수 있어요.

가설 검정(Hypothesis testing)

가설 검정은 어떤 결과가 통계적으로 유의한지, 그 결과가 우연히 일어났는지 여부를 판단하기 위한 통계에서 강력한 도구예요. spark.mllib는 현재 적합도(goodness of fit)와 독립성(independence)에 대한 Pearson의 카이제곱($\chi^2$) 검정을 지원해요. 입력 데이터 타입에 따라 적합도 검정 또는 독립성 검정이 수행돼요. 적합도 검정은 Vector 입력 타입이 필요하고, 독립성 검정은 Matrix 입력이 필요해요.

spark.mllib는 또한 카이제곱 독립성 검정을 통한 피처 선택을 가능하게 하기 위해 RDD[LabeledPoint] 입력 타입을 지원해요.

Statistics는 Pearson의 카이제곱 검정을 실행하는 메서드를 제공해요. 다음 예제는 가설 검정을 어떻게 실행하고 해석하는지 보여줘요.

API에 대한 자세한 내용은 Statistics Python 문서를 참고하세요.

from pyspark.mllib.linalg import Matrices, Vectors
from pyspark.mllib.regression import LabeledPoint
from pyspark.mllib.stat import Statistics

vec = Vectors.dense(0.1, 0.15, 0.2, 0.3, 0.25)  # a vector composed of the frequencies of events

# compute the goodness of fit. If a second vector to test against
# is not supplied as a parameter, the test runs against a uniform distribution.
goodnessOfFitTestResult = Statistics.chiSqTest(vec)

# summary of the test including the p-value, degrees of freedom,
# test statistic, the method used, and the null hypothesis.
print("%s\n" % goodnessOfFitTestResult)

mat = Matrices.dense(3, 2, [1.0, 3.0, 5.0, 2.0, 4.0, 6.0])  # a contingency matrix

# conduct Pearson's independence test on the input contingency matrix
independenceTestResult = Statistics.chiSqTest(mat)

# summary of the test including the p-value, degrees of freedom,
# test statistic, the method used, and the null hypothesis.
print("%s\n" % independenceTestResult)

obs = sc.parallelize(
    [LabeledPoint(1.0, [1.0, 0.0, 3.0]),
     LabeledPoint(1.0, [1.0, 2.0, 0.0]),
     LabeledPoint(1.0, [-1.0, 0.0, -0.5])]
)  # LabeledPoint(label, feature)

# The contingency table is constructed from an RDD of LabeledPoint and used to conduct
# the independence test. Returns an array containing the ChiSquaredTestResult for every feature
# against the label.
featureTestResults = Statistics.chiSqTest(obs)

for i, result in enumerate(featureTestResults):
    print("Column %d:\n%s" % (i + 1, result))

전체 예제 코드는 Spark 저장소의 "examples/src/main/python/mllib/hypothesis_testing_example.py"에서 찾을 수 있어요.

Statistics는 Pearson의 카이제곱 검정을 실행하는 메서드를 제공해요. 다음 예제는 가설 검정을 어떻게 실행하고 해석하는지 보여줘요.

import org.apache.spark.mllib.linalg._
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.stat.Statistics
import org.apache.spark.mllib.stat.test.ChiSqTestResult
import org.apache.spark.rdd.RDD

// a vector composed of the frequencies of events
val vec: Vector = Vectors.dense(0.1, 0.15, 0.2, 0.3, 0.25)

// compute the goodness of fit. If a second vector to test against is not supplied
// as a parameter, the test runs against a uniform distribution.
val goodnessOfFitTestResult = Statistics.chiSqTest(vec)
// summary of the test including the p-value, degrees of freedom, test statistic, the method
// used, and the null hypothesis.
println(s"$goodnessOfFitTestResult\n")

// a contingency matrix. Create a dense matrix ((1.0, 2.0), (3.0, 4.0), (5.0, 6.0))
val mat: Matrix = Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))

// conduct Pearson's independence test on the input contingency matrix
val independenceTestResult = Statistics.chiSqTest(mat)
// summary of the test including the p-value, degrees of freedom
println(s"$independenceTestResult\n")

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)
      )
    )
  ) // (label, feature) pairs.

// The contingency table is constructed from the raw (label, feature) pairs and used to conduct
// the independence test. Returns an array containing the ChiSquaredTestResult for every feature
// against the label.
val featureTestResults: Array[ChiSqTestResult] = Statistics.chiSqTest(obs)
featureTestResults.zipWithIndex.foreach { case (k, v) =>
  println(s"Column ${(v + 1)} :")
  println(k)
}  // summary of the test

전체 예제 코드는 Spark 저장소의 "examples/src/main/scala/org/apache/spark/examples/mllib/HypothesisTestingExample.scala"에서 찾을 수 있어요.

Statistics는 Pearson의 카이제곱 검정을 실행하는 메서드를 제공해요. 다음 예제는 가설 검정을 어떻게 실행하고 해석하는지 보여줘요.

API에 대한 자세한 내용은 ChiSqTestResult Java 문서를 참고하세요.

import java.util.Arrays;

import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.mllib.linalg.Matrices;
import org.apache.spark.mllib.linalg.Matrix;
import org.apache.spark.mllib.linalg.Vector;
import org.apache.spark.mllib.linalg.Vectors;
import org.apache.spark.mllib.regression.LabeledPoint;
import org.apache.spark.mllib.stat.Statistics;
import org.apache.spark.mllib.stat.test.ChiSqTestResult;

// a vector composed of the frequencies of events
Vector vec = Vectors.dense(0.1, 0.15, 0.2, 0.3, 0.25);

// compute the goodness of fit. If a second vector to test against is not supplied
// as a parameter, the test runs against a uniform distribution.
ChiSqTestResult goodnessOfFitTestResult = Statistics.chiSqTest(vec);
// summary of the test including the p-value, degrees of freedom, test statistic,
// the method used, and the null hypothesis.
System.out.println(goodnessOfFitTestResult + "\n");

// Create a contingency matrix ((1.0, 2.0), (3.0, 4.0), (5.0, 6.0))
Matrix mat = Matrices.dense(3, 2, new double[]{1.0, 3.0, 5.0, 2.0, 4.0, 6.0});

// conduct Pearson's independence test on the input contingency matrix
ChiSqTestResult independenceTestResult = Statistics.chiSqTest(mat);
// summary of the test including the p-value, degrees of freedom...
System.out.println(independenceTestResult + "\n");

// an RDD of labeled points
JavaRDD<LabeledPoint> obs = jsc.parallelize(
  Arrays.asList(
    new LabeledPoint(1.0, Vectors.dense(1.0, 0.0, 3.0)),
    new LabeledPoint(1.0, Vectors.dense(1.0, 2.0, 0.0)),
    new LabeledPoint(-1.0, Vectors.dense(-1.0, 0.0, -0.5))
  )
);

// The contingency table is constructed from the raw (label, feature) pairs and used to conduct
// the independence test. Returns an array containing the ChiSquaredTestResult for every feature
// against the label.
ChiSqTestResult[] featureTestResults = Statistics.chiSqTest(obs.rdd());
int i = 1;
for (ChiSqTestResult result : featureTestResults) {
  System.out.println("Column " + i + ":");
  System.out.println(result + "\n");  // summary of the test
  i++;
}

전체 예제 코드는 Spark 저장소의 "examples/src/main/java/org/apache/spark/examples/mllib/JavaHypothesisTestingExample.java"에서 찾을 수 있어요.

추가로 spark.mllib는 확률 분포의 동등성을 검정하는 1-표본, 양측 Kolmogorov-Smirnov(KS) 검정을 제공해요. 이론적 분포의 이름(현재는 정규 분포만 지원)과 그 파라미터를 제공하거나, 주어진 이론적 분포에 따라 누적 분포를 계산하는 함수를 제공하면, 사용자는 자신의 표본이 그 분포에서 추출됐다는 귀무 가설을 검정할 수 있어요. 정규 분포(distName="norm")에 대해 검정하면서 분포 파라미터를 제공하지 않으면, 검정은 표준 정규 분포로 초기화되고 적절한 메시지를 로그로 남겨요.

Statistics는 1-표본, 양측 Kolmogorov-Smirnov 검정을 실행하는 메서드를 제공해요. 다음 예제는 가설 검정을 어떻게 실행하고 해석하는지 보여줘요.

API에 대한 자세한 내용은 Statistics Python 문서를 참고하세요.

from pyspark.mllib.stat import Statistics

parallelData = sc.parallelize([0.1, 0.15, 0.2, 0.3, 0.25])

# run a KS test for the sample versus a standard normal distribution
testResult = Statistics.kolmogorovSmirnovTest(parallelData, "norm", 0, 1)
# summary of the test including the p-value, test statistic, and null hypothesis
# if our p-value indicates significance, we can reject the null hypothesis
# Note that the Scala functionality of calling Statistics.kolmogorovSmirnovTest with
# a lambda to calculate the CDF is not made available in the Python API
print(testResult)

전체 예제 코드는 Spark 저장소의 "examples/src/main/python/mllib/hypothesis_testing_kolmogorov_smirnov_test_example.py"에서 찾을 수 있어요.

Statistics는 1-표본, 양측 Kolmogorov-Smirnov 검정을 실행하는 메서드를 제공해요. 다음 예제는 가설 검정을 어떻게 실행하고 해석하는지 보여줘요.

API에 대한 자세한 내용은 Statistics Scala 문서를 참고하세요.

import org.apache.spark.mllib.stat.Statistics
import org.apache.spark.rdd.RDD

val data: RDD[Double] = sc.parallelize(Seq(0.1, 0.15, 0.2, 0.3, 0.25))  // an RDD of sample data

// run a KS test for the sample versus a standard normal distribution
val testResult = Statistics.kolmogorovSmirnovTest(data, "norm", 0, 1)
// summary of the test including the p-value, test statistic, and null hypothesis if our p-value
// indicates significance, we can reject the null hypothesis.
println(testResult)
println()

// perform a KS test using a cumulative distribution function of our making
val myCDF = Map(0.1 -> 0.2, 0.15 -> 0.6, 0.2 -> 0.05, 0.3 -> 0.05, 0.25 -> 0.1)
val testResult2 = Statistics.kolmogorovSmirnovTest(data, myCDF)
println(testResult2)

전체 예제 코드는 Spark 저장소의 "examples/src/main/scala/org/apache/spark/examples/mllib/HypothesisTestingKolmogorovSmirnovTestExample.scala"에서 찾을 수 있어요.

Statistics는 1-표본, 양측 Kolmogorov-Smirnov 검정을 실행하는 메서드를 제공해요. 다음 예제는 가설 검정을 어떻게 실행하고 해석하는지 보여줘요.

API에 대한 자세한 내용은 Statistics Java 문서를 참고하세요.

import java.util.Arrays;

import org.apache.spark.api.java.JavaDoubleRDD;
import org.apache.spark.mllib.stat.Statistics;
import org.apache.spark.mllib.stat.test.KolmogorovSmirnovTestResult;

JavaDoubleRDD data = jsc.parallelizeDoubles(Arrays.asList(0.1, 0.15, 0.2, 0.3, 0.25));
KolmogorovSmirnovTestResult testResult =
  Statistics.kolmogorovSmirnovTest(data, "norm", 0.0, 1.0);
// summary of the test including the p-value, test statistic, and null hypothesis
// if our p-value indicates significance, we can reject the null hypothesis
System.out.println(testResult);

전체 예제 코드는 Spark 저장소의 "examples/src/main/java/org/apache/spark/examples/mllib/JavaHypothesisTestingKolmogorovSmirnovTestExample.java"에서 찾을 수 있어요.

스트리밍 유의성 검정(Streaming Significance Testing)

spark.mllib는 A/B 테스트 같은 사용 사례를 지원하기 위해 일부 검정의 온라인 구현을 제공해요. 이 검정들은 Spark Streaming DStream[(Boolean, Double)]에서 수행될 수 있는데, 각 튜플의 첫 번째 요소는 대조군(false) 또는 처치군(true)을 나타내고, 두 번째 요소는 관측값이에요.

스트리밍 유의성 검정은 다음 파라미터를 지원해요.

  • peacePeriod — 신제품 효과(novelty effects)를 완화하기 위해 무시할 스트림의 초기 데이터 포인트 수
  • windowSize — 가설 검정을 수행할 과거 배치 수. 0으로 설정하면 모든 이전 배치를 사용한 누적 처리를 수행해요.

StreamingTest는 스트리밍 가설 검정을 제공해요.

val data = ssc.textFileStream(dataDir).map(line => line.split(",") match {
  case Array(label, value) => BinarySample(label.toBoolean, value.toDouble)
})

val streamingTest = new StreamingTest()
  .setPeacePeriod(0)
  .setWindowSize(0)
  .setTestMethod("welch")

val out = streamingTest.registerStream(data)
out.print()

전체 예제 코드는 Spark 저장소의 "examples/src/main/scala/org/apache/spark/examples/mllib/StreamingTestExample.scala"에서 찾을 수 있어요.

StreamingTest는 스트리밍 가설 검정을 제공해요.

import org.apache.spark.mllib.stat.test.BinarySample;
import org.apache.spark.mllib.stat.test.StreamingTest;
import org.apache.spark.mllib.stat.test.StreamingTestResult;

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();

전체 예제 코드는 Spark 저장소의 "examples/src/main/java/org/apache/spark/examples/mllib/JavaStreamingTestExample.java"에서 찾을 수 있어요.

랜덤 데이터 생성(Random data generation)

랜덤 데이터 생성은 무작위 알고리즘, 프로토타이핑, 성능 테스트에 유용해요. spark.mllib는 주어진 분포(균등, 표준 정규, 포아송)에서 추출한 i.i.d. 값을 가진 랜덤 RDD 생성을 지원해요.

RandomRDDs는 랜덤 double RDD 또는 벡터 RDD를 생성하는 팩토리 메서드를 제공해요. 다음 예제는 값이 표준 정규 분포 N(0, 1)을 따르는 랜덤 double RDD를 생성한 뒤 N(1, 4)로 매핑해요.

API에 대한 자세한 내용은 RandomRDDs Python 문서를 참고하세요.

from pyspark.mllib.random import RandomRDDs

sc = ... # SparkContext

# Generate a random double RDD that contains 1 million i.i.d. values drawn from the
# standard normal distribution `N(0, 1)`, evenly distributed in 10 partitions.
u = RandomRDDs.normalRDD(sc, 1000000L, 10)
# Apply a transform to get a random double RDD following `N(1, 4)`.
v = u.map(lambda x: 1.0 + 2.0 * x)

RandomRDDs는 랜덤 double RDD 또는 벡터 RDD를 생성하는 팩토리 메서드를 제공해요. 다음 예제는 값이 표준 정규 분포 N(0, 1)을 따르는 랜덤 double RDD를 생성한 뒤 N(1, 4)로 매핑해요.

API에 대한 자세한 내용은 RandomRDDs Scala 문서를 참고하세요.

import org.apache.spark.SparkContext
import org.apache.spark.mllib.random.RandomRDDs._

val sc: SparkContext = ...

// Generate a random double RDD that contains 1 million i.i.d. values drawn from the
// standard normal distribution `N(0, 1)`, evenly distributed in 10 partitions.
val u = normalRDD(sc, 1000000L, 10)
// Apply a transform to get a random double RDD following `N(1, 4)`.
val v = u.map(x => 1.0 + 2.0 * x)

RandomRDDs는 랜덤 double RDD 또는 벡터 RDD를 생성하는 팩토리 메서드를 제공해요. 다음 예제는 값이 표준 정규 분포 N(0, 1)을 따르는 랜덤 double RDD를 생성한 뒤 N(1, 4)로 매핑해요.

API에 대한 자세한 내용은 RandomRDDs Java 문서를 참고하세요.

import org.apache.spark.SparkContext;
import org.apache.spark.api.JavaDoubleRDD;
import static org.apache.spark.mllib.random.RandomRDDs.*;

JavaSparkContext jsc = ...

// Generate a random double RDD that contains 1 million i.i.d. values drawn from the
// standard normal distribution `N(0, 1)`, evenly distributed in 10 partitions.
JavaDoubleRDD u = normalJavaRDD(jsc, 1000000L, 10);
// Apply a transform to get a random double RDD following `N(1, 4)`.
JavaDoubleRDD v = u.mapToDouble(x -> 1.0 + 2.0 * x);

커널 밀도 추정(Kernel density estimation)

커널 밀도 추정은 관측된 표본이 추출된 특정 분포에 대한 가정 없이 경험적 확률 분포를 시각화하는 데 유용한 기법이에요. 주어진 점 집합에서 평가된 확률 변수의 확률 밀도 함수 추정을 계산해요. 특정 점에서 경험적 분포의 PDF를, 각 표본을 중심으로 한 정규 분포의 PDF 평균으로 표현해 이 추정을 달성해요.

KernelDensity는 표본 RDD에서 커널 밀도 추정을 계산하는 메서드를 제공해요. 다음 예제는 그 방법을 보여줘요.

API에 대한 자세한 내용은 KernelDensity Python 문서를 참고하세요.

from pyspark.mllib.stat import KernelDensity

# an RDD of sample data
data = sc.parallelize([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])

# Construct the density estimator with the sample data and a standard deviation for the Gaussian
# kernels
kd = KernelDensity()
kd.setSample(data)
kd.setBandwidth(3.0)

# Find density estimates for the given values
densities = kd.estimate([-1.0, 2.0, 5.0])

전체 예제 코드는 Spark 저장소의 "examples/src/main/python/mllib/kernel_density_estimation_example.py"에서 찾을 수 있어요.

KernelDensity는 표본 RDD에서 커널 밀도 추정을 계산하는 메서드를 제공해요. 다음 예제는 그 방법을 보여줘요.

API에 대한 자세한 내용은 KernelDensity Scala 문서를 참고하세요.

import org.apache.spark.mllib.stat.KernelDensity
import org.apache.spark.rdd.RDD

// an RDD of sample data
val data: RDD[Double] = sc.parallelize(Seq(1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9))

// Construct the density estimator with the sample data and a standard deviation
// for the Gaussian kernels
val kd = new KernelDensity()
  .setSample(data)
  .setBandwidth(3.0)

// Find density estimates for the given values
val densities = kd.estimate(Array(-1.0, 2.0, 5.0))

전체 예제 코드는 Spark 저장소의 "examples/src/main/scala/org/apache/spark/examples/mllib/KernelDensityEstimationExample.scala"에서 찾을 수 있어요.

KernelDensity는 표본 RDD에서 커널 밀도 추정을 계산하는 메서드를 제공해요. 다음 예제는 그 방법을 보여줘요.

API에 대한 자세한 내용은 KernelDensity Java 문서를 참고하세요.

import java.util.Arrays;

import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.mllib.stat.KernelDensity;

// an RDD of sample data
JavaRDD<Double> data = jsc.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));

// Construct the density estimator with the sample data
// and a standard deviation for the Gaussian kernels
KernelDensity kd = new KernelDensity().setSample(data).setBandwidth(3.0);

// Find density estimates for the given values
double[] densities = kd.estimate(new double[]{-1.0, 2.0, 5.0});

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

전체 예제 코드는 Spark 저장소의 "examples/src/main/java/org/apache/spark/examples/mllib/JavaKernelDensityEstimationExample.java"에서 찾을 수 있어요.

더 알아보기 (Learn more)