01Basic

[Fastcampus] RDC 강의 내용 정리 - 이부일 강사님

Two Sample t-test

When?
두 개의 독립적인 집단의 평균이 같은지 다른지를 달라졌는지를 통계적으로 검정하는 방법
질적 자료(1개) : 두 집단
양적 자료(1개) :


  • 귀무가설 : 비졸업과 졸업 간에 용돈에 차이가 없다(mu1 = mu2).
  • 대립가설 : 비졸업과 졸업 간에 용돈에 차이가 있다(mu1 is not equal to mu2).

1단계 : 정규성 검정(Normality Test)

by(twosampleDF$money, twosampleDF$group, shapiro.test)

<결과>
twosampleDF$group: 비

	Shapiro-Wilk normality test

data:  dd[x, ]
W = 0.83701, p-value = 0.02885

----------------------------------------------------------------------------------
twosampleDF$group: 졸

	Shapiro-Wilk normality test

data:  dd[x, ]
W = 0.57538, p-value = 6.737e-05

두 집단 모두 정규성 가정이 깨짐 => 2단계로 Wilcoxon's rank sum test를 실시


2단계 : 정규성 가정이 만족이 되면

등분산성 검정(Equality of Variance Test)

  • 귀무가설 : 등분산이다.
  • 대립가설 : 이분산이다.

var.test(datavariable datavariable ~ datavariable)
var.test(양적 자료 ~ 질적 자료)

> var.test(twosampleDF$money ~ twosampleDF$group)

	F test to compare two variances

data:  twosampleDF$money by twosampleDF$group
F = 0.22298, num df = 10, denom df = 11, p-value = 0.02499
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.06324512 0.81720812
sample estimates:
ratio of variances
         0.2229815

> by(twosampleDF$money, twosampleDF$group, var)
twosampleDF$group:[1] 1280.455
----------------------------------------------------------------------------------
twosampleDF$group:[1] 5742.424

결론 : 유의확률이 0.025이므로 유의수준 0.05에서 이분산이다.


3단계 : 이분산이 가정된 독립 2표본 t검정

t.test(data$variable ~ data$vairable,alternative = c("greater", "less", "two.sided"), var.equal = FALSE)

> t.test(twosampleDF$money ~ twosampleDF$group,
         alternative = "two.sided",
         var.equal   = FALSE)

<결과>
Welch Two Sample t-test

data:  twosampleDF$money by twosampleDF$group
t = -0.21741, df = 15.963, p-value = 0.8306
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -57.02012  46.41406
sample estimates:
mean in group 비 mean in group 졸
        76.36364         81.66667

유의확률이 0.831이므로 유의수준 0.05에서 비졸업자과 졸업자의 용돈에는 통계적으로 유의한 차이는 없는 것으로 나타났다.


3단계 : 등분산이 가정된 독립 2표본 t검정

t.test(data$variable ~ data$vairable, alternative = c("greater", "less", "two.sided"), var.equal = TRUE)

> t.test(twosampleDF$money ~ twosampleDF$group,
         alternative = "two.sided",
         var.equal   = TRUE)

	Two Sample t-test

data:  twosampleDF$money by twosampleDF$group
t = -0.21122, df = 21, p-value = 0.8348
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -57.51554  46.90948
sample estimates:
mean in group 비 mean in group 졸
        76.36364         81.66667

유의확률이 0.835이므로 유의수준 0.05에서 비졸업자과 졸업자의 용돈에는 통계적으로 유의한 차이는 없는 것으로 나타났다.


2단계 : 윌콕슨의 순위합 검정(Wilcoxon's rank sum test)

wilcox.test(data$variable ~ data$variable, alternative = c("two.sided", "greater", "less"))

> wilcox.test(twosampleDF$money ~ twosampleDF$group,
              alternative = "two.sided")

	Wilcoxon rank sum test with continuity correction

data:  twosampleDF$money by twosampleDF$group
W = 78, p-value = 0.4594
alternative hypothesis: true location shift is not equal to 0

유의확률이 0.459이므로 유의수준 0.05에서 비졸업자과 졸업자의 용돈에는 통계적으로 유의한 차이는 없는 것으로 나타났다.



Quiz 1.

  • yr_built : 1900이상 ~ 2000미만 : group = "old"
  • yr_built : 2000이상 : group = "new"
  • 귀무가설 : old와 new 간에 price에 차이가 없다.
  • 대립가설 : old가 new보다 price가 작다.
# 사용 데이터
houseDF <- readxl::read_excel(path      = "kc_house_data.xlsx",
                              sheet     = 1,
                              col_names = TRUE)

houseDF$group <-  cut(houseDF$yr_built,
                      breaks = c(1900, 2000, 2020),
                      right  = FALSE)
levels(houseDF$group) <- c("old", "new")
by(houseDF$price, houseDF$group, ad.test)
wilcox.test(houseDF$price ~ houseDF$group,
            alternative = "less")

result <- var.test(houseDF$price ~ houseDF$group)
result$p.value


Quiz 02.

id, date, yr_built를 제외한 모든 변수에 대해서 아래 가설검정을 실시

  • 귀무가설 : old와 new는 같다.
  • 대립가설 : new와 old는 같지 않다.

최종 결과 형태

variableName Normaility Method Equality TW pvalue
price yes t.test yes 1.234 0.123
bedrooms no wilcox.test non 1.234 0.123
houseDF <- read_excel(path      = "path/kc_house_data.xlsx",
                      sheet     = 1,
                      col_names = TRUE)
houseDF <- data.frame(houseDF)
# 분석에 사용하지 않는 변수 제거
# 1) dplyr (전처리에 많이 활용되는 라이브러리입니다.)
# select(변수 벡터)          => 지정벡터(열)만 추출
# select(-one_of(변수 벡터)) => 지정벡터(열)   제거
exceptVariable <- c("id", "date", "yr_built")
analysis.variable <- houseDF %>%
  select(-one_of(exceptVariable))

# 2) grep(base library)
analysis.variable <- colnames(houseDF)[-grep("^id|^date|^yr_built|^group",
                                             colnames(houseDF))]


# group 변수 생성
# ifelse를 활용하여 group - new/old 변수 생성 => 가설검정에서는 old를 기준으로 분석해야한다.
# default는 factor에서 new, old순서이기 때문에
# factor 형태 변환시 levels와 labels를 사용해서 old, new순서로 변경
# *주의) 데이터 형 변환시 as.factor와 factor는 동일한 기능을 수행하지만
#        levels와 lables를 argument로 가질 수 있는 것은 factor
houseDF$group <- ifelse(houseDF$yr_built >= 2000, "new","old")
str(houseDF$group)
table(houseDF$group)
houseDF$group <- factor(houseDF$group,
                        levels = c("old", "new"),
                        labels = c("old", "new"))
table(houseDF$group)

# 최종 결과를 저장하기 위한 빈 벡터 생성
Normality <- c()
Method    <- c()
Equality  <- c()
TW        <- c()
PValue    <- c() 

# for문(반복 횟수는 in (조건)에 들어간 벡터의 길이로 결정됩니다.)
# analysis.variable에서 변수를 한개씩 가져와서 실행
# for문의 반복 횟수는 19번(length(anaylsis.variable))
# 19번 동안 i에는 각각의 char타입의 열이름이 들어가서 실행
for(i in analysis.variable){

  # 1) 정규성 검정
  # 왜 unlist를 사용해야 하는가?
  # 우측 houseDF의 타입 : data.frame vs tbl_df
  # data.frame의 경우 houseDF[,i] 결과가 numveric vector입니다.
  # tbl_df의 경우 houseDF[,i] 결과가 tbl_df, data.frame형태의 class입니다.
  # 따라서, tbl_df형태를 가지는 houseDF는
  # 1) unlist를 통해서 벡터형태로 변환해주거나
  # 2) houseDF[, i]$변수명 형태로 한번더 슬라이싱을 해줘야 하는 문제가 있습니다.
    result.normality <- by(unlist(houseDF[ , i]), houseDF$group, ad.test)
    # result.normality <- by((houseDF[ , i]$i), houseDF$group, ad.test)
    # houseDF를 data.frame으로 변경하고 사용할 시
    # result.normality <- by(houseDF[ , i], houseDF$group, ad.test)

  # 2) 정규성 검정 결과를 통해 모수적 방법과 비모수적 방법 구분
  # 2-1) old와 new의 p-value가 둘중 하나라도 0.05 미만일 경우 정규성이 깨진다.
  #      => 비모수적행 방법 : wilcox.test
    if( (result.normality$old$p.value < 0.05) | (result.normality$new$p.value < 0.05)){
      # wilcox.test 결과 저장
        Normality <- c(Normality, "No")
        Method    <- c(Method, "wilcox.test")
        Equality  <- c(Equality, "Non")

        # 위의 unlist 설명과 동일
        # 대립 가설이 `old와 new가 같지 않다`이기 때문에 양측검정(two.sided)
        result.wilcox <- wilcox.test(unlist(houseDF[ , i])~ houseDF$group,
                                     alternative = "two.sided")

        # 필요한 부분만 추출하여 저장
        # str(result.wilcox)를 통해 wilcox 결과가 가지는 데이터의 구조를 확인 할 수 있습니다.
        TW     <- c(TW, result.wilcox$statistic)
        PValue <- c(PValue, result.wilcox$p.value)


  # 2-2) old와 newd의 p-value가 둘 모두 0.05 이상일 경우 정규성을 따른다.
  #     => 모수적 방법 : t-test
    }else{
        Normality <- c(Normality, "Yes")
        Method    <- c(Method, "t.test")

        # 3) 등분산성 검정
        # 귀무가설 : 등분산이다.
        # 대립가설 : 이분산이다.
        result.equality <- var.test(unlist(houseDF[ , i])~ houseDF$group)

        # p-value가 0.05 미만일 경우 이분산 (var.equal = FALSE)
        if(result.equality$p.value < 0.05){
            Equality  <- c(Equality, "No")
            result.ttest <- t.test(unlist(houseDF[ , i])~ houseDF$group,
                                   alternative = "two.sided",
                                   var.equal   = FALSE)
            TW     <- c(TW, result.ttest$statistic)
            PValue <- c(PValue, result.ttest$p.value)

        # p-value가 0.05 이상일 경우 등분산 (var.equal = TRUE)
        }else{
            Equality  <- c(Equality, "Yes")
            result.ttest <- t.test(unlist(houseDF[ , i])~ houseDF$group,
                                   alternative = "two.sided",
                                   var.equal   = TRUE)
            TW     <- c(TW, result.ttest$statistic)
            PValue <- c(PValue, result.ttest$p.value)
        }
    }
}

# for문을 6개의 벡터가 생성되었습니다.
# 하나의 결과로 저장
outputTest <- data.frame(Variable = analysis.variable,
                         Normality,
                         Method,
                         Equality,
                         TW,
                         PValue)
# 결과 내보내기
writexl::write_xlsx(outputTest, path = "outputTest.xlsx")

+ Recent posts