728x90

붓스트랩(Bootstrap)

1979년:  미국 Stanforrd 대학교, 브래들리 에프런 (Bradley Efron) 교수 1977년 창안, 붓스트랩 소개

그 후 붓스트랩은 현재 통계학에서는 없어서는 안 될 중요한 주제라고...

붓스트랩은

원 데이터 (개수n)에서 랜덤으로 추출하는데,  

복원 추출하여 (... 데이터가 중복되는 것을 허락)
원래의 데이터 개수n만큼 추출하여 분석하는 방법입니다.

 

일반적으로 표준오차(평균의 표준편차)를 구하는 방법을 다음과 같습니다.
원 데이터에서 표준편차를 구하고(쉽게 구할 수 있습니다)

이 표준편차/ (데이터 갯수의 제곱근) 으로 구합니다.

set.seed(12345) 
norm_x <- rnorm(50,mean=100,sd=5) 
mean(norm_x) 
sd(norm_x) 
sd(norm_x)/sqrt(length(norm_x)) 

(1) set.seed(12345)

# 동일한 난수를 발생하도록 시드 지정

 

(2) norm_x <- rnorm(50,mean=100,sd=5)

# 평균이 100, 표준편차가 5인 난수 50개를 만듬(정규분포가 아니더라도 상관없음)

 

(3) mean(norm_x) 

# 생성된 난수 50개의 평균 구하기, 100.8978

 

(4) sd(norm_x)

# 생성된 난수 50개의 표준편차 구하기 5.48293

 

(5) sd(norm_x)/sqrt(length(norm_x))

# 생성된 난수 50개를 이용하여 표준오차  구하기 0.754034

 

실행결과        r_mod_boot_01

복원 추출하여 붓스트랩(Bootstrap)

set.seed(12345)
mean_val <- numeric(70)
for (i in 1:70) {
  mean_val[i] <- mean(sample(norm_x,replace=T))
}
mean_val
sd(mean_val)  

set.seed(12345)
mean_val <- numeric(70)
for (i in 1:70) {
  mean_val[i] <- mean(sample(norm_x,replace=T))
}

(1) 앞에서의 데이터(50개)를 이용하여 복원추출(중복을 허락하여) 50개의 샘플데이터를 만든 다음

(2) 이 샘플데이터에서 평균을 구하고, 변수 mean_val[i] 에 저장

(3) (1)~(2) 를  평균을 구하기를 70번 반복하고, 그 평균들을 mean_val[i] 에 저장


mean_val
sd(mean_val)  

(4) 평균값 70개를 구한, 평균값들의 표준편차를 구합니다. 0.7344992

(5) 그리하여 앞에서 실행한 표준오차와 비교해 봅니다.

r_mod_boot_02

 

패키지 boot

붓스트렙을 지원하는 패키지 boot가 있습니다. 패키지 boot를 이용하는 방법이 좀 특이합니다.

 

set.seed(12345)
norm_x <- rnorm(50,mean=100,sd=5)  
df01 <- as.data.frame(norm_x)          
str(df01)
my.mean <- function(df,indices=1:NROW(df),x1="norm_x") 
{
(sd(df[,x1])/ sqrt(length(df[,x1])) )
}
avgBoot <- boot(data=df,statistic = my.mean,R=1200)  # 패키지 boot, 함수 boot를 사용 1200 번 붓스트랩 시행
avgBoot
boot.ci(avgBoot,conf=0.95,type="norm")

set.seed(12345)

norm_x <- rnorm(50,mean=100,sd=5)

    50개의 숫자를구함(정규분포가 아니어도 상관없음)

 

df01 <- as.data.frame(norm_x)          
str(df01)

     데이터프레임으로 변환하고 구조를 살펴보기

     50개의 관측치와 norm_x 라는 변수가 있음

     'data.frame': 50 obs. of  1 variable:
     $ norm_x: num  102.9 103.5 99.5 97.7 103 ...

 

my.mean <- function(df,indices=1:NROW(df),x1="norm_x")

{
   (sd(df[,x1])/ sqrt(length(df[,x1])) )

 }

     # my.mean 이라는 함수를 만듬. 표준오차를 만드는 함수

 

avgBoot <- boot(data=df01,statistic = my.mean, R=1200) 

     # 패키지 boot, 함수 boot를 사용, data는 dt01, static에는 my.mean 함수를 이용,  1200 번 붓스트랩 시행

avgBoot

r_mod_boot_03

boot.ci(avgBoot,conf=0.95,type="norm")

     신뢰구간 구하기

 

 

주어진 데이터를 이용하여 전 데이터를 이용하여 회귀분석을 하면(lm함수 이용)

회귀계수를 한 번)에 구할 수 있습니다. 

이러기 보다는 주어진 데이터의 일부분을 추출하여 회귀분석을 하고,

또 다시 일부분을 추출하여 회귀분석을 하고 

이와 같이 회귀계수을 여러 번하여 얻는 통계치들을 평균하는 것이 보다 안정(?)적인 것이 아닐까?

이러한 것이 붓스트랩입니다.

 

그러면 이런 개념을 확대 적용해 보면

각종 머신러닝 기법을 적용하여 나온 결과, 모델이 어느 정도 좋은 것인가? 평가하는 모델성능평가를 하는데

정확도, MSE 등을 구하는데 한 번만 하는 것보다 샘플을 추출하여 여러 번 해 보고,

정확도 또는 MSE 등을 평균하는 것이 안정(?)인 것이 아닐까?

 

붓스트랩 개선 - K-fold

그럼 좀 더 나아가 볼까?
붓스트랩처럼 대책없이(?) 복원추출하는 것보다(랜덤으로 복원추출하면 분석에 포함되지 않는 데이터도 발생)

좀 더 세련되게 하는 방법은 없는 것일까?
데이터셋을 10개로 구분하고, 이 중에서 1-9번까지 데이터셋으로 분석하고, 나머지 10번째로 평가하고

2~10번까지 데이터셋으로 분석하고, 1번 데이터셋으로 평가하고... 이런식으로 하면...

이것이 k-fold 입니다. 여기서 관측치를 1/10 이 아니고, 관측치 한개를 제외하고 나머지로 분석하고

하는 식이면 One Leave Out CrossValidation 이라 합니다.

이런 식으로 머신러닝에서 모형평가하는 방법이 점차 개선되어 나갑니다.

 

참고문헌:

데이터분서그로 배우는 알짜 테크닉(인사이트, 제리드 렌더)

THE R BOOK (WILEY, Michael J.Crawley)

SPSS Statistics 비모수적 방법과 붓스트랩 방법(데이터솔루션, 허명회)

 

 

 

  

 

 

+ Recent posts