1. 요약 통계 (Summary Statistics)
Spark MLlib은 RDD[Vector] 형태의 데이터에 대해 열 단위의 요약 통계 기능을 제공합니다. 이를 위해 Statistics 클래스의 colStats 메서드를 사용하며, 이 메서드는 각 컬럼의 최대값, 최소값, 평균, 분산 등을 포함하는 MultivariateStatisticalSummary 객체를 반환합니다.
import org.apache.spark.mllib.linalg.Vector
import org.apache.spark.mllib.stat.{MultivariateStatisticalSummary, Statistics}
import org.apache.spark.rdd.RDD
// 벡터 형태의 RDD 생성
val inputData: RDD[Vector] = ...
// 컬럼별 요약 통계 계산
val statResult: MultivariateStatisticalSummary = Statistics.colStats(inputData)
// 결과 출력 예시
println(s"컬럼별 평균: ${statResult.mean}") // 각 컬럼의 평균값을 담은 DenseVector
println(s"컬럼별 분산: ${statResult.variance}") // 각 컬럼의 분산
println(s"0이 아닌 요소 개수: ${statResult.numNonzeros}") // 각 컬럼 내 비정상(non-zero) 데이터 수
2. 상관관계 분석 (Correlations)
두 데이터셋 간의 연관성을 파악하는 것은 통계 분석의 핵심입니다. MLlib은 기본적으로 피어슨(Pearson)과 스피어만(Spearman) 두 가지 상관계수 계산 방식을 지원합니다.
상관계수 모델의 특징
- Pearson 상관계수: 데이터가 정규 분포를 따르며 등간 척도인 경우에 주로 사용하며, 선형적 관계의 강도를 측정합니다.
- Spearman 상관계수: 데이터의 순위를 기준으로 계산하며, 정규 분포를 따르지 않는 비모수적 데이터셋에도 적용 가능합니다.
import org.apache.spark.SparkContext
import org.apache.spark.mllib.linalg._
import org.apache.spark.mllib.stat.Statistics
import org.apache.spark.rdd.RDD
val sc: SparkContext = ...
// 두 개의 Double 타입 RDD 간의 상관관계 계산
val sequenceA: RDD[Double] = ...
val sequenceB: RDD[Double] = ...
val pearsonCorr: Double = Statistics.corr(sequenceA, sequenceB, "pearson")
// 벡터 RDD를 이용한 상관관계 행렬 생성
val matrixData: RDD[Vector] = ...
val correlationMatrix: Matrix = Statistics.corr(matrixData, "spearman")
3. 층화 추출 (Stratified Sampling)
층화 추출법은 모집단을 서로 겹치지 않는 여러 개의 하위 집단(층)으로 나누고, 각 층에서 정해진 비율에 따라 샘플을 무작위로 추출하는 방식입니다. Spark에서는 Key-Value 형태의 RDD에서 Key를 기준으로 샘플링을 수행합니다.
주요 메서드
sampleByKey: 각 데이터를 순회하며 설정된 확률에 따라 샘플링 여부를 결정합니다. 근사적인 샘플 크기를 얻을 때 사용됩니다.sampleByKeyExact: 설정된 비율에 맞춰 정확하게 샘플링을 수행합니다. 연산 비용은 더 높지만 99.9% 이상의 정확도를 보장합니다.
import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
val sc: SparkContext = ...
val rawData: RDD[(String, Int)] = ... // (Key, Value) 형태의 데이터
// 각 키별로 추출할 비율 설정
val samplingWeights = Map("GroupA" -> 0.1, "GroupB" -> 0.5, "GroupC" -> 0.3)
// 근사치 기반 층화 추출
val approxSample = rawData.sampleByKey(withReplacement = false, fractions = samplingWeights)
// 정확한 비율 기반 층화 추출
val exactSample = rawData.sampleByKeyExact(withReplacement = false, fractions = samplingWeights)
추출 방식에 있어 중복을 허용하는 경우(withReplacement = true)에는 포아송(Poisson) 분포가 활용되며, 중복을 허용하지 않는 경우에는 베르누이(Bernoulli) 분포가 활용됩니다.