bash script2023. 10. 12. 20:24

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/634977

awk를 이용해서 파일에 저장된 값들의 분산(variance)과 표준편차(standard deviation)를 계산하는 방법이다. 표준편차를 계산하려면 우선 평균을 알아야 한다. awk를 이용한 평균값 계산은 이전 게시물을 참고하자. 여기로

 

전에 사용한 것과 동일한 예시를 사용해서 표준편차를 계산해 보자. data.txt 파일에 저장된 자료는 아래와 같다.

# data.txt 내용 확인
cat data.txt
john 12.35
jane -34.5
thomas 3.9

우선 평균을 계산하여 변수 mean에 할당한다.

# 평균값을 계산하여 변수 mean에 할당
mean=`awk '{ sum += $2; cnt++ } END { print sum/cnt }' data.txt`

평균을 알았으니 이제 분산을 계산할 수 있다. 분산은 각 자료값과 평균값의 차이를 제곱하여 모두 더한 후에, 이 값을 자료의 수로 나누면 된다. 자료가 전체 모집단(population)이라는 가정하에서다. 만약 자료가 모집단에서 일부를 추출한 표본(sample)이라면 합산한 값을 (자료의 수 - 1)로 나누어 준다.

awk에서 먼저 계산한 평균값을 사용해야 하므로 -v 옵션을 통해서 shell의 변수 mean에 저장된 값을 사용해야 한다. (awk의 -v 옵션에 대한 이전 게시물은 여기에)

 

# 분산을 계산하여 변수 variance_p에 할당 (모집단)
variance_p=`awk -v m="$mean" '{ sum += ($2 - m)^2; cnt++ } END { print sum/cnt }' data.txt`

-v 옵션으로 평균값을 awk 내부에서 변수 m에 할당하고, data.txt의 두번째 항목($2)과 평균값의 차이를 제곱해서 더하여 변수 sd에 할당. 자료의 수를 세기 위해 변수 cnt를 1씩 증가시킨다. 합산 작업이 끝나고 나면(END) 변수 sd를 cnt로 나눈다.

위의 계산식은 자료가 전체 모집단(polulation)이라는 가정하에서다. 만약 자료가 모집단에서 일부를 추출한 표본(sample)이라면 합산한 값을 자료의 수 cnt가 아니라 (cnt-1)로 나눈다.

# 분산을 계산하여 변수 variance_s에 할당(표본)
variance_s=`awk -v m="$mean" '{ sum += ($2 - m)^2; cnt++ } END { print sum/(cnt-1) }' data.txt`

표준편차는 분산의 제곱근을 취하면 된다. 이미 분산값을 알고 있으므로 bc를 이용해서 계산하면 되겠다. (bc에 대한 이전 게시물은 여기에)

# 표준편차 계산 - stdev_p(모집단), stdev_s(표본)
stdev_p=`echo "sqrt($variance_p)" | bc`

stdev_s=`echo "sqrt($variance_s)" | bc`

awk에도 제곱근 계산용 내부 함수가 있으므로, 분산을 계산하지 않고 awk에서 바로 표준편차를 계산할 수도 있다. 함수 이름은 sqrt로 같다.

# 표준편차 계산
stdev_p=`awk -v m="$mean" '{ sd += ($2 - m)^2; cnt++ } END { print sqrt(sd/cnt) }' data.txt`

stdev_s=`awk -v m="$mean" '{ sd += ($2 - m)^2; cnt++ } END { print sqrt(sd/(cnt-1)) }' data.txt`

728x90
Posted by 반달가면