제가 일하는 (주)에스이랩에서는 정기적으로 한장강의라는 것을 PDF 파일로 만들어서 발송합니다. IDL, ENVI, SARscape 등과 같은 Harris Geospatial의 제품들에 관한 사용법이나 팁 등을 한 장(두 페이지) 분량으로 담아서 등록된 고객들에게 이메일로 발송하는 서비스입니다. 그 중에서 최근에 발송되었던 "IDL에서 기초통계를 해봅시다"라는 제목의 한장강의가 있었습니다. 이 블로그에 방문하시는 분들 중에서 이 한장강의를 메일로 수신하신 분들도 있겠지만 그렇지 않은 분들도 있을 것 같습니다. 그래서 제가 여기에도 첨부를 하겠습니다.
이 한장강의의 내용은 제가 작성한 것입니다. 사실 IDL을 많이 사용해오신 분들이라면 대부분 아실만한 내용이긴 합니다. 그런데 제가 이 한장강의를 작성하면서 지면 관계상 미처 담지 못했던 추가적인 내용들이 있었습니다. 그래서 이 자리를 빌어서 그 내용을 마저 소개하고 관련된 보충 설명을 드려보고자 합니다. 먼저 위에 첨부한 PDF 파일의 내용을 한번 보시고, 오늘 제가 마저 소개하는 내용을 보시면 좋을 것 같습니다.
이 한장강의에서는 IDL에서 다양한 종류의 기초 통계량 값들을 산출하는데 있어서 사용할만한 주요 내장함수들을 소개하였습니다. MOMENT와 같은 통합적인 역할의 함수도 있고 각 통계량의 종류에 따라 MEAN, MEDIAN, VARIANCE, STDDEV 등과 같은 함수를 사용할 수도 있습니다. 그런데 이러한 내장함수들을 사용하여 통계량을 얻을 때 주의를 해야 할 부분이 있습니다. 특히 이러한 내장함수들을 사용하여 분산, 표준편차, 왜도, 첨도 등의 통계량들을 산출할 때 주의해야 하는 부분인데, 바로 표본(Sample)을 대상으로 한 통계량들이 계산된다는 것입니다. 아시다시피 통계에서는 모집단(Population)과 표본(Sample)의 구분이 중요한데, IDL의 주요 통계 기능 함수들의 경우 모집단을 대상으로 하는 것이 아니라 표본을 대상으로 하는 통계량을 산출한다는 것입니다. IDL 도움말에서 MOMENT 함수에 관한 내용을 보면 각종 기초 통계량들을 계산하는데 사용된 수식들이 소개되어 있는데, 이 수식들을 보면 알 수 있습니다.
여기서 분산(Variance)을 산출할 때 사용되는 수식을 보면 분모가 (N-1)로 되어 있는데 이게 바로 표본(Sample)에 대한 분산입니다. 만약 모집단(Population)일 경우에는 (N-1) 대신 N이 사용되어야 합니다. 아무래도 일반적으로는 모집단보다는 표본을 다루는 경우가 훨씬 더 많기 때문에 IDL에서도 이러한 수식을 기반으로 한 내장함수가 지원되는 것이라고 봅니다. 하지만 경우에 따라서는 표본이 아닌 모집단을 대상으로 한 통계량을 계산해야 할 경우도 전혀 없지는 않을 것입니다. 만약 진짜로 모집단을 대상으로 통계량을 얻어야 하는데 IDL의 관련 내장함수를 그대로 사용하여 결과를 얻는다면 그 결과는 틀릴 수 밖에 없습니다. 따라서 계산에 앞서서 대상 데이터가 표본이냐 아니면 모집단이냐 여부를 명확히 구분할 필요가 있습니다. 그리고 만약 표본이 아닌 모집단에 대한 통계량을 얻어야 하는 상황이라면 안타깝게도 IDL의 관련 내장함수들을 그대로 사용해서는 안될 것입니다. 그 경우에는 수식을 기반으로 하여 직접 코딩을 하여 계산하는 것이 필요합니다. 한장강의에서 사용되었던 예제 데이터에 대하여 먼저 표본이라는 가정하에서 분산의 값을 구하려면 다음과 같이 내장함수 VARIANCE를 바로 이용하면 됩니다.
data = [13, 8, 11, 11, 7, 8, 15, 10, 8, 9, 6]
var_sam = VARIANCE(data)
PRINT, 'variance (sample) :', var_sam
그러나 모집단이라는 가정하에서 분산의 값을 구하려면 해당 수식을 기반으로 다음과 같이 직접 코딩하여 연산 결과를 얻는 수 밖에 없습니다.
n = N_ELEMENTS(data)
mn = MEAN(data)
var_pop = TOTAL((data-mn)^2)/n
PRINT, 'variance (population) :', var_pop
출력된 값들은 다음과 같습니다. 당연히 두 값은 서로 다릅니다.
variance (sample) : 7.25455
variance (population) : 6.59504
표준편차의 경우도 마찬가지로 표본을 가정한다면 내장함수 STDDEV를 사용하면 되고, 모집단을 가정한다면 위에서 수식으로 계산한 모집단 기준의 분산에 대하여 제곱근을 취하면 됩니다.
sdv_sam = STDDEV(data)
PRINT, 'stddev (sample) :', sdv_sam
sdv_pop = SQRT(var_pop)
PRINT, 'stddev (population) :', sdv_pop
출력된 값들은 다음과 같습니다. 역시 당연히 두 값은 서로 다릅니다.
stddev (sample) : 2.69343
stddev (population) : 2.56808
이와 같은 표본/모집단의 구분은 왜도(Skewness), 첨도(Kurtosis)와 같은 통계량의 계산에서도 마찬가지입니다. 앞서 소개한 수식에서도 나와있듯이 이러한 통계량들의 계산에 있어서도 분산이라는 인자가 포함되기 때문입니다. 그러면 왜도(Skewness)부터 살펴봅시다. 먼저 표본을 가정하여 내장함수 SKEWNESS를 사용하여 왜도 값을 계산 및 출력을 해보면 다음과 같습니다.
skn_sam = SKEWNESS(data)
PRINT, 'skewness (sample) :', skn_sam
skewness (sample) : 0.547464
그리고 모집단을 가정하여 수식을 직접 사용하여 계산해봅시다. 위의 왜도 수식에서 분산 제곱근은 결국 표준편차인데 당연히 모집단 표준편차를 사용해야 하므로 다음과 같이 해주면 됩니다.
skn_pop = TOTAL(((data-mn)/sdv_pop)^3)/n
PRINT, 'skewness (population) :', skn_pop
이 때 출력된 값은 다음과 같습니다.
skewness (population) : 0.631603
이와 같이 왜도의 경우도 표본이냐 모집단이냐에 따라 값이 다르게 산출됩니다. 그런데 여기서 한가지 더 짚어볼만한 부분이 있습니다. 현재 사용중인 예제 데이터를 그대로 사용하여 마이크로소프트 엑셀(Excel)에서 왜도 값을 한번 계산해보았습니다. 엑셀에서는 왜도 계산용 함수가 두 종류가 지원되는데 SKEW와 SKEW.P입니다. SKEW는 표본 기준이고 SKEW.P는 모집단 기준입니다. 그런데 엑셀에서 두 함수를 사용하여 결과를 얻어보면 각각 0.7360, 0.6316이 나옵니다. 즉 모집단 기준의 왜도 값은 앞서 IDL에서 수식으로 계산한 것과 엑셀의 값이 일치합니다. 그런데 표본 기준의 왜도값은 IDL이 0.5475이고 엑셀은 0.7360입니다. 즉 표본 기준의 왜도 값은 IDL과 엑셀이 서로 완전히 다르다는 것을 확인할 수 있습니다. 이것는 누가 맞고 누가 틀리냐의 문제가 아니라 그냥 서로 다르다의 문제입니다. 즉 표본 기준의 왜도의 계산에 있어서 내부적으로 어떤 수식이 사용되었느냐의 차이입니다. 엑셀에서 SKEW 함수에 관한 도움말을 참조해보면 계산에 사용되는 수식이 나와있는데, 이 수식을 똑같이 적용하여 IDL에서 계산해보려면 다음과 같이 하면 됩니다.
skn_excel = TOTAL(((data-mn)/sdv_sam)^3)*n/(n-1.)/(n-2.)
PRINT, 'skewness (Excel) :', skn_excel
그리고 결과는 다음과 같이 출력됩니다.
skewness (Excel) : 0.736035
이 값은 엑셀에서 얻은 표본 기준의 왜도 값과 동일합니다. 사실 여기서 IDL과 엑셀 중 어느 것이 맞느냐를 따지는 것은 무의미합니다. 왜냐하면 둘 다 맞기 때문입니다. 통계에서 왜도라는 값을 계산의 방식 자체가 여러 종류이기 때문에, IDL과 엑셀에서 그 중 어느 것이 채택되었느냐의 문제입니다. 제가 다른 언어나 응용프로그램들까지 모두 테스트해보지는 않았지만, IDL 말고 Python이나 R 등의 타 언어에서는 또 다른 값이 산출될 수도 있습니다. 중요한 것은 내장함수를 사용하여 산출된 값이 실제로 어떤 수식을 기반으로 한 것이냐에 대하여 세세하게 따져보는 것이 필요할 수 있다는 것입니다.
이러한 문제는 첨도(Kurtosis)의 경우도 동일합니다. 즉 IDL의 내장함수를 이용하여 표본 기준으로 계산된 값과 직접 수식을 코딩하여 계산한 모집단 기준의 값은 당연히 서로 다릅니다.
krt_sam = KURTOSIS(data)
PRINT, 'kurtosis (sample) :', krt_sam
krt_pop = TOTAL(((data-mn)/sdv_pop)^4)/n-3
PRINT, 'kurtosis (population) :', krt_pop
kurtosis (sample) : -0.914356
kurtosis (population) : -0.476369
그런데 표본 기준의 첨도 역시 엑셀에서도 KURT 함수를 사용하여 계산할 수 있는데 이 값이 IDL에서 얻은 값과 또 다릅니다. 실제로 엑셀에서 계산해보면 그 값은 0.0394로 나옵니다. 하지만 그 이유 역시 마찬가지로 엑셀에서는 다른 수식이 사용되기 때문입니다. 엑셀에서 사용되는 수식을 그대로 적용하여 IDL에서 다시 계산해보면 다음과 같습니다. 수식이 좀 복잡합니다.
krt_excel = (n+1.)*n*(n-1.)/(n-2.)/(n-3.)*TOTAL((data-mn)^4)/TOTAL((data-mn)^2)^2-3*(n-1.)^2/(n-2.)/(n-3.)
PRINT, 'kurtosis (Excel) :', krt_excel
이 결과는 다음과 같이 출력됩니다.
kurtosis (Excel) : 0.0393834
이와 같이 엑셀의 경우와 동일한 값을 얻을 수 있습니다. 결국 이러한 부분 역시 앞서 언급했던대로 어떤 툴(Tool)에서 계산을 했든간에 내부적으로 어떤 수식을 기반으로 하여 계산된 것이냐에 대하여 따져보는 것이 매우 중요할 수도 있다는 점을 시사합니다. 사실 이러한 차이를 세세하게 따져야 하는 경우가 그리 많지는 않을 것이라고 봅니다. 하지만 작업의 특성에 따라서는 이러한 부분들까지도 살펴보는 것이 필요할 수도 있다는 점을 염두에 두는 것이 좋을 것입니다.
마지막으로 평균값(Mean or Average)에 대해서도 언급해보고자 합니다. 우리가 흔히 사용하는 평균값은 산술평균(Arithmetic Mean)입니다. 이 값을 계산하는 방법은 대상 데이터의 모든 값들을 합한 총합을 갯수로 나눠주는 것입니다. 평균값을 계산하는 IDL의 내장함수인 MEAN 함수에서도 산술평균을 산출합니다. 따라서 다음과 같이 MEAN 함수를 사용하든 아니면 공식을 직접 코딩하여 계산하든 결과는 정확히 동일합니다.
mn_ari_1 = MEAN(data)
PRINT, 'mean (arithmetic 1) :', mn_ari_1
mn_ari_2 = TOTAL(data)/N_ELEMENTS(data)
PRINT, 'mean (arithmetic 2) :', mn_ari_2
mean (arithmetic 1) : 9.63636
mean (arithmetic 2) : 9.63636
그런데 산술평균 외에도 또 다른 종류의 평균값들이 있습니다. 바로 기하평균(Geometric Mean)과 조화평균(Harmonic Mean)입니다. 아쉽게도 IDL에서는 이러한 종류의 평균값을 산출하는 내장함수는 없기 때문에, 필요하다면 공식을 직접 코딩하여 계산해야 합니다. 먼저 기하평균을 계산하려면 모든 값들을 곱한 총곱에 대하여 (1/n)승을 해줘야 합니다. 따라서 다음과 같이 코딩하여 계산하면 됩니다.
mn_geo = PRODUCT(data)^(1./N_ELEMENTS(data))
PRINT, 'mean (geometric) :', mn_geo
mean (geometric) : 9.3122133
그리고 조화평균의 경우는 모든 값들에 대한 역수(Reciprocal)들의 산술평균의 역수로 계산해야 합니다. 따라서 다음과 같이 코딩하여 계산하면 됩니다.
mn_har = 1./(MEAN(1./data))
PRINT, 'mean (harmonic) :', mn_har
mean (harmonic) : 9.00869
이상과 같은 방법으로 산술, 기하, 조화 평균값들을 계산할 수 있다는 것을 염두에 두시면 좋을 것 같습니다. 그러면 오늘 소개하고자 했던 내용은 모두 설명이 된 것 같습니다. IDL에서 각종 통계 관련 계산을 하는 일에 관해서는 제가 이전에도 이 블로그에 올렸던 내용들이 있지만, 향후에도 도움이 될만한 내용이 있다면 언제든 여기서 다루도록 하겠습니다. 그러면 오늘은 여기서 마치겠습니다.
'IDL > Math' 카테고리의 다른 글
구면상의 지점 분포 데이터에 대한 격자화 및 유의사항 (0) | 2020.12.18 |
---|---|
NaN, Infinity와 FINITE 함수 (0) | 2020.08.10 |
Kriging 기법의 이용 방법 (0) | 2020.06.01 |
INT_2D를 이용한 2-변수(Bivariate) 함수의 적분 (0) | 2020.04.02 |
행렬곱의 속도 향상에 관하여 (IDL 8.7.3) (0) | 2020.02.26 |