관측값이 질적 자료(qualitative data) 또는 어떤 속성에 따라 분류되어 범주(category)에 속하는 도수(frequency)로 주어질 경우 이를 범주형 자료(categorical data) 라고 합니다. 범주형 자료의 예로는 학력(초등졸, 중등졸, 고등졸, 대졸, 대학원졸), 연수익(극빈, 하, 중, 상, 극상) 등이 있습니다.

 

앞서의 포스팅에서는 종속변수가 연속형 자료(continuous data)인 경우에 사용하는 검정 방법으로 t-Test와 ANOVA에 대해서 소개하였습니다.

 

이번 포스팅부터는 종속변수가 범주형 자료(categorical data)인 경우에 사용하는 분석기법으로 카이제곱 검정(Chi-Squared Test)에 대해서 알아보도록 하겠습니다.

 

범주형 자료 분석은 크게 적합도 검정(goodness f fit test), 독립성 검정(test of independence), 동질성 검정(test of homogeneity)의 3가지로 분류할 수 있으며, 이번 포스팅에서는 (1) 적합도 검정에 대해서 알아보도록 하겠습니다.

 

 

 

[ 범주형 자료 분석 (categorical data test) ]

 

(1) 적합도 검정(goodness of fit test) : 관측값들이 어떤 이론적 분포를 따르고 있는지를 검정. 한 개의 요인을 대상으로 함 

 

(2) 독립성 검정(test of independence) : 서로 다른 요인들에 의해 분할되어 있는 경우 그 요인들이 관찰값에 영향을 주고 있는지 아닌지, 요인들이 서로 연관이 있는지 없는지를 검정. 두 개의 요인을 대상으로 함.

 

(3) 동질성 검정(test of homogeneity) : 관측값들이 정해진 범주 내에서 서로 비슷하게 나타나고 있는지를 검정. 속성 A, B를 가진 부모집단(subpopulation) 각각으로부터 정해진 표본의 크기만큼 자료를 추출하는 경우에 분할표에서 부모집단의 비율이 동일한가를 검정. 두 개의 요인을 대상으로 함.

 

 

 

 

 

 

적합도 검정(goodness of fit test)은 k개의 범주 (혹은 계급)을 가지는 한 개의 요인(factor)에 대해서 어떤 이론적 분포를 따르고 있는지를 검정하는 방법입니다. 

 

기본 원리는, 도수분포의 각 구간에 있는 관측도수를 O1, O2, ..., Ok 라 하고, 각 범주 ( 혹은 계급)가 일어날 확률을 p1, p2, ..., pk 라고 할 때 기대되는 관측도수 E1, E2, ..., Ek 를 계산하여 실제 관측도수와 기대 관측도수의 차이를 카이제곱 검정 통계량(Chi-squared statistics)을 활용하여 가정한 확률모형에 적합한지를 평가하게 됩니다. 만약 귀무가설 H0가 맞다면 관측도수와 기대도수가 별 차이가 없을 것이므로 검정통계량 X0^2 값이 작을 것이며, 반대로 대립가설 H1이 맞다면 관측도수와 기대도수의 차이가 클 것이므로 검정통계량 X0^2 값이 커질 것입니다.

 

 

 

[ 적합도 검정 가설 및 검정 통계량, 검정 방법 ]

(1) 가설

 

  - 귀무가설 H0 : 관측값의 도수와 가정한 이론 도수(기대 관측도수)가 동일하다
                        ( p1 = p10, p2 = p20, ..., pk = pko )

 

  - 대립가설 H1 : 적어도 하나의 범주 (혹은 계급)의 도수가 가정한 이론 도수(기대 관측도수)와 다르다

                        (적어도 하나의 pi는 가정된 값 pi0과 다르다)

 

 

(2) 검정 통계량

 

 

 

(3) 검정 방법

 

 

 

 

  • (a) chisq.test() of data from text problem

 

아래 문제에 대해서 R의 chisq.test() 함수를 사용해서 풀어보도록 하겠습니다.

 

 

 

(문제)  유전학자 멘델은 콩 교배에 대한 유전의 이론적 모형으로서 잡종비율을 A : B : C = 2 : 3 : 5 라고 주장하였다.  이 이론의 진위를 가리기 위해 두 콩 종자의 교배로 나타난 100개의 콩을 조사하였더니 A형 19개, B형 41개, C형 40개였다.  이러한 관찰값을 얻었을 때 멘델 유전학자의 이론이 맞다고 할 수 있는지를 유의수준 α = 0.05 에서 검정하여라.

 

 

 

> ##---------------------------------------------------------------------
> ## categorical data analysis - (1) goodness of fit test : chisq.test()
> ##---------------------------------------------------------------------
> 
> obs <- c(19, 41, 40)
> null.probs <- c(2/10, 3/10, 5/10)
> 
> chisq.test(obs, p=null.probs)

	Chi-squared test for given probabilities

data:  obs
X-squared = 6.0833, df = 2, p-value = 0.04776

 

 

위 분석결과를 보면 P-value가 0.04776 이므로 유의수준 α 0.05보다 작으므로 귀무가설 H0를 기각하고 대립가설 H1을 채택하여 "멘델이 주장한 콩의 잡종비율 이론적 분포는 적합하지 않다"고 판단할 수 있겠습니다.

 

 

 참고로, R로 통계분석을 하면 콘솔 창에 보여지는 내용 말고도 실제로 다양한 통계량이 계산이 되어 list 형태로 메모리상에 가지고 있으며 단지 눈에 보이지 않을 뿐인데요, indexing 기법을 활용하면 chisq.test() 함수로 카이제곱 검정 실행한 후에 다양한 통계량들을 선별해서 볼 수도 있고, 통계량을 다른 분석 혹은 애플리케이션에 input으로 넣어 재활용할 수도 있습니다.  R의 큰 장점 중의 하나이니 팁으로 알아두면 좋겠습니다. 주요 통계량 몇 개를 아래에 소개합니다.

 

 

> # To see results of chisquared test
> chisq.test_output_1 <- chisq.test(obs, p=null.probs)
> 
> chisq.test_output_1$observed # observed frequency
[1] 19 41 40
> chisq.test_output_1$expected # expected frequeycy
[1] 20 30 50
> chisq.test_output_1$residuals # residual between observed and expected frequecy
[1] -0.2236068  2.0083160 -1.4142136
> 
> chisq.test_output_1$statistic # chi-squared statistics
X-squared 
 6.083333 
> chisq.test_output_1$parameter # degrees of freedom
df 
 2 
> chisq.test_output_1$p.value # P-value
[1] 0.04775523

 

 

 

참고로 하나더, 검정통계량 X^2는 귀무가설 H0가 참이라는 가정 하에 근사적으로 자유도가 k-1 인 카이제곱분포를 따르는 것으로 알려져 있습니다.  (☞ 카이제곱 분포(Chi-squared distribution) 참고 포스팅)

 

카이제곱 검정에 사용하는 카이제곱 분포는 범주형 자료의 도수 추정에 사용되는데요, 이때 도수가 너무 작으면 "카이제곱 approximation)이 정확하지 않을 수도 있습니다" 라는 경고메시지가 뜹니다.

 

 

> # Warning message when there are not sufficient frequencies > # R will issue a warning message if any of the EFs fall below 5

> obs_2 <- c(5, 5) > null.probs_2 <- c(0.3, 0.7) > > chisq.test(obs_2, p=null.probs_2) Chi-squared test for given probabilities data: obs_2 X-squared = 1.9048, df = 1, p-value = 0.1675 Warning message: In chisq.test(obs_2, p = null.probs_2) : 카이제곱 approximation은 정확하지 않을수도 있습니다

 

 

 

 

  • (b) chisqtest() of data from a table object

위의 문제는 텍스트 문제로 도수와 확률이 주어지면 'x'와 'p'를 직접 입력하였는데요, 데이터가 Table object 형태로 주어졌을 때 카이제곱 검정으로 적합도 검정하는 방법을 소개하겠습니다.

 

R에 내장된 HairEyeColor table 데이터셋에 있는 Hair 요인 변수를 대상으로, Hair의 요인 수준(factor levels, 혹은 계급 class) 별로 생물학자가 주장하기를 확률이 Black 20%, Brown 50%, Red 10%, Blond 20% 라고 하는데요, 유의수준 α 0.05 로 검정을 해보겠습니다.

 

> ##------------
> # chisq.test() of data from a table object
> str(HairEyeColor) 
 table [1:4, 1:4, 1:2] 32 53 10 3 11 50 10 30 10 25 ...
 - attr(*, "dimnames")=List of 3
  ..$ Hair: chr [1:4] "Black" "Brown" "Red" "Blond"
  ..$ Eye : chr [1:4] "Brown" "Blue" "Hazel" "Green"
  ..$ Sex : chr [1:2] "Male" "Female"
> 
> HairEyeColor 
, , Sex = Male

       Eye
Hair    Brown Blue Hazel Green
  Black    32   11    10     3
  Brown    53   50    25    15
  Red      10   10     7     7
  Blond     3   30     5     8

, , Sex = Female

       Eye
Hair    Brown Blue Hazel Green
  Black    36    9     5     2
  Brown    66   34    29    14
  Red      16    7     7     7
  Blond     4   64     5     8

> 
> dimnames(HairEyeColor)
$Hair
[1] "Black" "Brown" "Red"   "Blond"

$Eye
[1] "Brown" "Blue"  "Hazel" "Green"

$Sex
[1] "Male"   "Female"

> 
> margin.table(HairEyeColor, 1) # Hair
Hair
Black Brown   Red Blond 
  108   286    71   127 
> margin.table(HairEyeColor, 2) # Eye
Eye
Brown  Blue Hazel Green 
  220   215    93    64 
> margin.table(HairEyeColor, 3) # Sex
Sex
  Male Female 
   279    313 
> 
> # vector of observed frequencies and probabilities
> Hair_Freq <- c(margin.table(HairEyeColor, 1))
> Hair_Freq
Black Brown   Red Blond 
  108   286    71   127 
> Hair_Prob <- c(0.2, 0.5, 0.1, 0.2)
> 
> chisq.test(x=Hair_Freq, p=Hair_Prob)

	Chi-squared test for given probabilities

data:  Hair_Freq
X-squared = 4.228, df = 3, p-value = 0.2379

 

 

 

  • (c) chisq.test() of data from Data Frame

 

데이터가 텍스트, Table object가 아니고 Data Frame일 경우에 카이제급 검정하는 방법도 소개해드리겠습니다.  MASS 패키지에 내장된 Cars93 Data Frame 을 이용하며, 자동차종(Type)의 이론상 분포 Compact 20%,  Large 10%, Midsize 20%, Small 20%, Sporty  20%, Van 10% 에 대해서 유의수준 α 0.05로 검정해보겠습니다. 

data(data frame, package="xxx"), table() 함수를 이용합니다.

 

> ##------------
> # chisq.test() of data from data frame
> data(Cars93, package="MASS")
> head(Cars93)
  Manufacturer   Model    Type Min.Price Price Max.Price MPG.city MPG.highway            AirBags
1        Acura Integra   Small      12.9  15.9      18.8       25          31               None
2        Acura  Legend Midsize      29.2  33.9      38.7       18          25 Driver & Passenger
3         Audi      90 Compact      25.9  29.1      32.3       20          26        Driver only
4         Audi     100 Midsize      30.8  37.7      44.6       19          26 Driver & Passenger
5          BMW    535i Midsize      23.7  30.0      36.2       22          30        Driver only
6        Buick Century Midsize      14.2  15.7      17.3       22          31        Driver only
  DriveTrain Cylinders EngineSize Horsepower  RPM Rev.per.mile Man.trans.avail Fuel.tank.capacity
1      Front         4        1.8        140 6300         2890             Yes               13.2
2      Front         6        3.2        200 5500         2335             Yes               18.0
3      Front         6        2.8        172 5500         2280             Yes               16.9
4      Front         6        2.8        172 5500         2535             Yes               21.1
5       Rear         4        3.5        208 5700         2545             Yes               21.1
6      Front         4        2.2        110 5200         2565              No               16.4
  Passengers Length Wheelbase Width Turn.circle Rear.seat.room Luggage.room Weight  Origin
1          5    177       102    68          37           26.5           11   2705 non-USA
2          5    195       115    71          38           30.0           15   3560 non-USA
3          5    180       102    67          37           28.0           14   3375 non-USA
4          6    193       106    70          37           31.0           17   3405 non-USA
5          4    186       109    69          39           27.0           13   3640 non-USA
6          6    189       105    69          41           28.0           16   2880     USA
           Make
1 Acura Integra
2  Acura Legend
3       Audi 90
4      Audi 100
5      BMW 535i
6 Buick Century
> str(Cars93)
'data.frame':	93 obs. of  27 variables:
 $ Manufacturer      : Factor w/ 32 levels "Acura","Audi",..: 1 1 2 2 3 4 4 4 4 5 ...
 $ Model             : Factor w/ 93 levels "100","190E","240",..: 49 56 9 1 6 24 54 74 73 35 ...
 $ Type              : Factor w/ 6 levels "Compact","Large",..: 4 3 1 3 3 3 2 2 3 2 ...
 $ Min.Price         : num  12.9 29.2 25.9 30.8 23.7 14.2 19.9 22.6 26.3 33 ...
 $ Price             : num  15.9 33.9 29.1 37.7 30 15.7 20.8 23.7 26.3 34.7 ...
 $ Max.Price         : num  18.8 38.7 32.3 44.6 36.2 17.3 21.7 24.9 26.3 36.3 ...
 $ MPG.city          : int  25 18 20 19 22 22 19 16 19 16 ...
 $ MPG.highway       : int  31 25 26 26 30 31 28 25 27 25 ...
 $ AirBags           : Factor w/ 3 levels "Driver & Passenger",..: 3 1 2 1 2 2 2 2 2 2 ...
 $ DriveTrain        : Factor w/ 3 levels "4WD","Front",..: 2 2 2 2 3 2 2 3 2 2 ...
 $ Cylinders         : Factor w/ 6 levels "3","4","5","6",..: 2 4 4 4 2 2 4 4 4 5 ...
 $ EngineSize        : num  1.8 3.2 2.8 2.8 3.5 2.2 3.8 5.7 3.8 4.9 ...
 $ Horsepower        : int  140 200 172 172 208 110 170 180 170 200 ...
 $ RPM               : int  6300 5500 5500 5500 5700 5200 4800 4000 4800 4100 ...
 $ Rev.per.mile      : int  2890 2335 2280 2535 2545 2565 1570 1320 1690 1510 ...
 $ Man.trans.avail   : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 1 1 1 ...
 $ Fuel.tank.capacity: num  13.2 18 16.9 21.1 21.1 16.4 18 23 18.8 18 ...
 $ Passengers        : int  5 5 5 6 4 6 6 6 5 6 ...
 $ Length            : int  177 195 180 193 186 189 200 216 198 206 ...
 $ Wheelbase         : int  102 115 102 106 109 105 111 116 108 114 ...
 $ Width             : int  68 71 67 70 69 69 74 78 73 73 ...
 $ Turn.circle       : int  37 38 37 37 39 41 42 45 41 43 ...
 $ Rear.seat.room    : num  26.5 30 28 31 27 28 30.5 30.5 26.5 35 ...
 $ Luggage.room      : int  11 15 14 17 13 16 17 21 14 18 ...
 $ Weight            : int  2705 3560 3375 3405 3640 2880 3470 4105 3495 3620 ...
 $ Origin            : Factor w/ 2 levels "USA","non-USA": 2 2 2 2 2 1 1 1 1 1 ...
 $ Make              : Factor w/ 93 levels "Acura Integra",..: 1 2 4 3 5 6 7 9 8 10 ...
> 
> Car_Type <- table(Cars93$Type)
> Car_Type

Compact   Large Midsize   Small  Sporty     Van 
     16      11      22      21      14       9 
> Car_Type_Prob <- c(0.2, 0.1, 0.2, 0.2, 0.2, 0.1)
> 
> chisq.test(x=Car_Type, p=Car_Type_Prob)

	Chi-squared test for given probabilities

data:  Car_Type
X-squared = 2.7527, df = 5, p-value = 0.738

 

 

 

이상으로 다양한 형태의 데이터셋을 활용해서 적합도 검정(goodness of fit test)을 카이제곱 검정 기법을 사용해서 하는 방법을 소개하였습니다.

 

=> 카이제곱 적합도 검정으로 관측치가 포아송분포로 부터의 데이터인지 여부를 검정하는 예시는 http://rfriend.tistory.com/362 를 참고하세요.

 

다음번 포스팅에서는 (2) 독립성 검정(test of independence) , (3) 동질성 검정 (test of homogeneity)대해서 알아보도록 하겠습니다.

 

많은 도움이 되었기를 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요. ^^

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. dfdf 2016.10.03 17:01  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. p-value < 2.2e-16 이렇게 결과값이 나오는데 어떻게 해야 하는건가요??

    • dfdf 2016.10.03 18:00  댓글주소  수정/삭제

      아, 찾아보니 p-value < 2.2e-16 는 컴퓨터에서 나타낼 수 있는 최소의 값이라고 하네요... 그냥 귀무가설을 기각하면 될 것 같습니다.

      그런데, R에서 카이 검정을 하다가 X-squared = 60.186, df=6, p-value 4.125e-11이 나왔는데, 이것도 위와 같이 해석해도 되나요? 그리고 보통 이렇게 나오는 경우가 무엇일까요? 통계를 갓 접한 새내기라 부족한 부분이 많습니다. 죄송합니다 ㅠㅠ

    • R Friend R_Friend 2016.10.03 18:51 신고  댓글주소  수정/삭제

      dfdf님,
      지수표기라서 보기에 좀 애매하지요?
      숫자표기로 변경하는 방법은 아래 링크 참조하세요.

      http://rfriend.tistory.com/224

      참고로, 지수표기 0.1e-5 는 숫자표기로는 0.00001 입니다.

  2. 이철규 2017.04.05 15:21 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요! 글 잘 읽고 있습니다. 궁금한게 하나 생겼는데요
    남녀간 갤럭시와 아이폰 선호도 차이가 있는지 없는지 조사하려면
    적합도 검정을 사용할 수 있나요? 독립성 검정도 사용할 수 있는건가요?