xwMOOC 기계학습
범주형 변수와 표
학습목표
- 범주형 변수와 짝꿍인 표를 생성하는 작업흐름을 이해한다.
- 표를 생성하는 3가지 자료구조를 이해한다.
- 표를 생성하고, 표현하고, 시각화 과정을 실습한다.
1. R로 표 작성 1
데이터를 표로 생성하는 것은 상황에 따라서 별것 아니기도 하지만, 매우 복잡한 작업이 되기도 한다. 종국에는 데이터를 계수하는 것으로 종결된다. 하지만, 2차원 이상일 경우, R로 표현되는 데이터 자료형이 다양하고, 기술적으로도 추상화 개념을 도입할 필요가 있다. 따라서, 데이터를 요구되는 표로 나타내고 처리하는데 경우에 따라서 매우 많은 함수를 취사선택하게 된다.
범주형 데이터분석은 표를 작성하면서 시작한다고 해도 과언은 아니다. R에는 2차원 혹은 다차원 표를 가지고 작업하는데 필요한 도구가 상당히 많이 존재하지만 완벽하지는 않는다. DescTools
팩키지에는 실무적인 측면에서 이런 간극을 매울 수 있는 도구를 일부 제공한다.
2. 표 생성
분할표(Contingency Table) 데이터를 R에 입력하는 방법은 다수 있다. 다음 표는 Agresti (2007) p.39, 정당과 성별를 표로 작성한 교차표다. 이를 R 데이터로 저장한다.
Party | ||||
---|---|---|---|---|
Democrat | Independent | Republican | ||
Gender | M | 762 | 327 | 468 |
F | 484 | 239 | 477 |
TextToTable()
함수 활용 :DescTools
팩키지에서 지원되는 함수.
txt <- "
Democrat, Independent, Republican
M, 762, 327, 468
F, 484, 239, 477"
TextToTable(txt, sep=",", dimnames=c("gender", "party"))
party
gender Democrat Independent Republican
M 762 327 468
F 484 239 477
as.table()
함수와rbind()
함수 사용
rbind()
함수와 as.table()
함수를 사용해서 입력 데이터를 table
자료형으로 변환시키고 나서, dimnames()
함수로 표에 사용되는 라벨을 부여하여 분할표를 완성시킨다.
tab <- as.table(rbind(c(762, 327, 468), c(484, 239, 477)))
dimnames(tab) <- list(gender = c("M", "F"),
party = c("Democrat", "Independent", "Republican"))
tab
party
gender Democrat Independent Republican
M 762 327 468
F 484 239 477
matrix()
함수를 사용
matrix()
함수를 사용하여 동일하게 표를 구성할 수도 있다. 이 경우 byrow=TRUE
로 설정해서 행렬이 행으로 쌓이게 한다.
as.table(matrix(c(762, 327, 468, 484, 239, 477), nrow=2, byrow=TRUE,
dimnames=list(gender= c("M", "F"),
party = c("Democrat", "Independent", "Republican"))))
party
gender Democrat Independent Republican
M 762 327 468
F 484 239 477
- 다차원 표
다차원 표, 예를 들어 \(2 \times 2 \times 2\) 표를 생성할 경우 배열을 사용한다. 이럴 경우 첫번째 차원은 행, 두번째 차원은 열, 세번째 차원은 깊이 순으로 저장된다.
salary <- array(
c(38, 12, 102, 141, 12, 9, 136, 383),
dim=c(2, 2, 2),
dimnames=list(exposure = c("exposed", "not"),
disease = c("case", "control"),
salary = c("<1000", ">=1000"))
)
read.ftable()
함수를 사용해서 고차원 표를 텍스트 파일로 표현된 정보를 표로 표현할 수도 있다.
txt <-
" Sex Male Female
Eye Brown Blue Hazel Green Brown Blue Hazel Green
Hair
Black 32 11 10 3 36 9 5 2
Brown 53 50 25 15 66 34 29 14
Red 10 10 7 7 16 7 7 7
Blond 3 30 5 8 4 64 5 8
"
tab <- as.table(read.ftable(textConnection(txt)))
2.1. 숫자형 변수에서 범주형 자료 생성
DescTools
팩키지의 Freq()
함수를 활용해서 숫자형 변수를 범주형으로 표현하기 수월하다. Freq()
함수는 hist()
함수의 기본설정을 그대로 사용하여 숫자형 변수를 범주형으로 변경시킨다.
Freq(d.pizza$temperature)
level freq perc cumfreq cumperc
1 [15,20] 3e+00 0.3% 3e+00 0.3%
2 (20,25] 3e+01 2.6% 3e+01 2.8%
3 (25,30] 6e+01 5.0% 9e+01 7.8%
4 (30,35] 5e+01 4.1% 1e+02 11.9%
5 (35,40] 1e+02 8.5% 2e+02 20.4%
6 (40,45] 1e+02 11.1% 4e+02 31.5%
7 (45,50] 2e+02 18.7% 6e+02 50.3%
8 (50,55] 3e+02 22.9% 9e+02 73.2%
9 (55,60] 2e+02 20.6% 1e+03 93.8%
10 (60,65] 7e+01 6.2% 1e+03 100.0%
2.2. expand 기능 활용
빈도수가 크지 않는 표를 작성하는 경우 expand.grid()
함수를 활용하여 빈도수를 입력하는 것이 여러모로 편리하다. 요인을 expand.grid() 함수로 처리하고, 벡터로 빈도수를 c()
함수로 작성한다. expand.grid()
함수로 요인사이 가능한 모든 조합을 표현하고, count
변수로 조합하여 데이터프레임으로 생성시킨다. 그리고 나서 xtabs
함수를 사용해서 표로 변환시킨다.
tab <- data.frame(expand.grid(
Hair = c("Black", "Brown", "Red", "Blond"),
Eye = c("Brown", "Blue", "Hazel", "Green"),
Sex = c("Male", "Female")),
count = c(32,53,10,3,11,50,10,30,10,25,7,5,3,15,7,8,
36,66,16,4,9,34,7,64,5,29,7,5,2,14,7,8) )
tab %>% head
Hair Eye Sex count
1 Black Brown Male 32
2 Brown Brown Male 53
3 Red Brown Male 10
4 Blond Brown Male 3
5 Black Blue Male 11
6 Brown Blue Male 50
3. 범주형 데이터 구성
표를 작성하는데 있어 가장 먼저 확인해야 되는 사항은 범주형 자료구조를 확인하는데 있다.
- 관측점 하나에 빈도수 하나인 경우(Case-by-Case):
data.frame
혹은 행렬에 원자료에 각행에 사례 한가지만 기록되어 저장되어 있는 경우.
Untable()
함수는 데이터프레임을 입력받아 관측점 하나에 빈도수 하나인 데이터프레임으로 변환시킨다.
Untable(UCBAdmissions) %>% head
Admit Gender Dept
1 Admitted Male A
2 Admitted Male A
3 Admitted Male A
4 Admitted Male A
5 Admitted Male A
6 Admitted Male A
- 빈도수(Frequency)
각 요인별 조합을 유일무이한 값으로 계수하여 각 행에 저장함. 흔히 가중치(weights)라고도 하고, Freq
칼럼이 이에 해당함.
data.frame(UCBAdmissions) %>% head
Admit Gender Dept Freq
1 Admitted Male A 512
2 Rejected Male A 313
3 Admitted Female A 89
4 Rejected Female A 19
5 Admitted Male B 353
6 Rejected Male B 207
- 표(Table)
다차원 표, 배열, 행렬이 이에 해당.
UCBAdmissions[,,Dept=c("A", "B")]
, , Dept = A
Gender
Admit Male Female
Admitted 512 89
Rejected 313 19
, , Dept = B
Gender
Admit Male Female
Admitted 353 17
Rejected 207 8
세가지 범주형 데이터 표현방식은 각기 다른 사용도와 의미가 내포되어 있다. 예를 들어 2번 표현은 1번 표현보다 훨씬 적은 저장공간을 차지하게 되고, 1번 표현방식은 즉각적으로 데이터를 표로 작성하는데 용이하다.
4. 표 만들기(Tabulate)
DescTools
팩키지에 포함된 HairEyeColor
객체는 table
자료형을 갖고 있다. 이를 Untable
명령어를 통해 한 행에 빈도수 하나만 갖는 데이터로 변환을 시킨다. 그리고 이를 바탕으로 다양한 표를 생성시켜 보자.
4.1. 단변량 범주형 변수
d.col <- Untable(HairEyeColor)
d.col %>% dplyr::filter(Sex=="Male", Hair=="Blond", Eye=="Brown")
Hair Eye Sex
1 Blond Brown Male
2 Blond Brown Male
3 Blond Brown Male
요인형 자료를 갖고 표를 생성시키는 방법은 table
함수로 빈도수, prop.table
함수로 백분율을 표로 표현한다.
table(d.col$Hair)
Black Brown Red Blond
108 286 71 127
prop.table(table(d.col$Hair))
Black Brown Red Blond
0.1824324 0.4831081 0.1199324 0.2145270
Freq
함수를 사용해서 단변량 범주형 변수의 경우 빈도수와 백분율을 간단히 표로 표현한다.
Freq(d.col$Hair, ord="desc")
level freq perc cumfreq cumperc
1 Brown 3e+02 48.3% 3e+02 48.3%
2 Blond 1e+02 21.5% 4e+02 69.8%
3 Black 1e+02 18.2% 5e+02 88.0%
4 Red 7e+01 12.0% 6e+02 100.0%
4.2. 이변량 범주형 변수
이변량 범주형 변수를 표로 표현하는 전통적인 방식은 table
과 prop.table
함수를 사용하는 것은 동일하다. 하지만, 행 백분율/열 백분율/전체 백분율을 표현하여야 하기 때문에 margin=
인수를 넣어 제어한다.
margin=1
: 행 백분율margin=2
: 열 백분율margin=NULL
: 전체 백분율
with(d.col, table(Hair, Sex))
Sex
Hair Male Female
Black 56 52
Brown 143 143
Red 34 37
Blond 46 81
혹은 plyr
, dplyr
팩키지의 count()
함수를 사용하면 table
, as.data.frame
단계를 거치지 않고 일관된 방식으로 표생성에 필요한 데이터를 만들어 낼 수 있다. 이를 xtabs
함수와 결합하여 표
dplyr_tbl <- d.col %>% count(Hair, Sex)
xtabs(n~Hair+Sex, dplyr_tbl)
Sex
Hair Male Female
Black 56 52
Brown 143 143
Red 34 37
Blond 46 81
with(d.col, prop.table(table(Hair, Eye), 1)) # 행기준
Eye
Hair Brown Blue Hazel Green
Black 0.62962963 0.18518519 0.13888889 0.04629630
Brown 0.41608392 0.29370629 0.18881119 0.10139860
Red 0.36619718 0.23943662 0.19718310 0.19718310
Blond 0.05511811 0.74015748 0.07874016 0.12598425
with(d.col, prop.table(table(Hair, Eye), 2)) # 열기준
Eye
Hair Brown Blue Hazel Green
Black 0.30909091 0.09302326 0.16129032 0.07812500
Brown 0.54090909 0.39069767 0.58064516 0.45312500
Red 0.11818182 0.07906977 0.15053763 0.21875000
Blond 0.03181818 0.43720930 0.10752688 0.25000000
with(d.col, prop.table(table(Hair, Eye), margin=NULL)) # 전체
Eye
Hair Brown Blue Hazel Green
Black 0.114864865 0.033783784 0.025337838 0.008445946
Brown 0.201013514 0.141891892 0.091216216 0.048986486
Red 0.043918919 0.028716216 0.023648649 0.023648649
Blond 0.011824324 0.158783784 0.016891892 0.027027027
PercTable()
함수를 rfrq=
인자를 상대빈도수를 제어한다. 011
은 행과 열 백분율만 출력한다.
- rfrq 첫번째 : 전체 백분율
- rfrq 두번째 : 행 백분율
- rfrq 세번째 : 열 백분율
PercTable(Hair ~ Eye, data=d.col, rfrq="111", margins=c(1,2))
Eye
Brown Blue Hazel Green Sum
Hair
Black freq 7e+01 2e+01 2e+01 5e+00 1e+02
perc 11.5% 3.4% 2.5% 0.8% 18.2%
p.row 63.0% 18.5% 13.9% 4.6% .
p.col 30.9% 9.3% 16.1% 7.8% .
Brown freq 1e+02 8e+01 5e+01 3e+01 3e+02
perc 20.1% 14.2% 9.1% 4.9% 48.3%
p.row 41.6% 29.4% 18.9% 10.1% .
p.col 54.1% 39.1% 58.1% 45.3% .
Red freq 3e+01 2e+01 1e+01 1e+01 7e+01
perc 4.4% 2.9% 2.4% 2.4% 12.0%
p.row 36.6% 23.9% 19.7% 19.7% .
p.col 11.8% 7.9% 15.1% 21.9% .
Blond freq 7e+00 9e+01 1e+01 2e+01 1e+02
perc 1.2% 15.9% 1.7% 2.7% 21.5%
p.row 5.5% 74.0% 7.9% 12.6% .
p.col 3.2% 43.7% 10.8% 25.0% .
Sum freq 2e+02 2e+02 9e+01 6e+01 6e+02
perc 37.2% 36.3% 15.7% 10.8% 100.0%
p.row . . . . .
p.col . . . . .
Margins(HairEyeColor, ord="desc")
명령어처럼 Margins()
함수가 있어 표 자료형을 입력받아 각 표차원별로 표를 신속하게 생성할 수 있다.
5. 표 데이터 자료형 변환
표데이터를 다음과 같이 Case-by-Case
, 빈도수 가중치
, 표
세가지 자료형이 존재한다.
- 관측점 하나에 빈도수 하나인 경우(Case-by-Case):
d.col <- Untable(HairEyeColor)
- 빈도수(Frequency):
d.weight <- as.data.frame(HairEyeColor)
- 표(Table):
tab <- HairEyeColor
사례별(Case-by-Case)
→빈도수(Frequency)
:as.data.frame(table(d.col))
사례별(Case-by-Case)
→ 표(Table) →빈도수(Frequency)
변환시킴
빈도수(Frequency)
→사례별(Case-by-Case)
:Untable(d.weight)
library(DescTools)
팩키지Untable()
함수 사용
사례별(Case-by-Case)
→표(Table)
:table(d.col)
표(Table)
→사례별(Case-by-Case)
:Untable(tab)
빈도수(Frequency)
→표(Table)
:xtabs(Freq ~ ., d.weight)
표(Table)
→빈도수(Frequency)
:as.data.frame(tab)
6. 시각화
mosaicplot()
모자이크 그래프를 사용하여 범주형 데이터를 시각화 한다. 먼저 데이터를 준비하고 색상을 정의한다. 그리고 나서 PlotMosaic()
함수를 호출하여 도식화한다.
tab <- as.table(apply(HairEyeColor, c(1,2), sum))
tab <- tab[,c("Brown","Hazel","Green","Blue")]
cols <- SetAlpha(c("sienna4", "burlywood", "chartreuse3", "slategray1"), 0.6)
PlotMosaic(tab, col=cols, main = "Hair ~ Eye")
PercTable(tab, freq=FALSE, rfrq="010")
Eye
Brown Hazel Green Blue
Hair
Black 63.0% 13.9% 4.6% 18.5%
Brown 41.6% 18.9% 10.1% 29.4%
Red 36.6% 19.7% 19.7% 23.9%
Blond 5.5% 7.9% 12.6% 74.0%
prop.table(margin.table(tab, 1))
Hair
Black Brown Red Blond
0.1824324 0.4831081 0.1199324 0.2145270
horiz = FALSE
인자를 넘겨 행과 열을 바꿔 모자이크 그래프로 도식화도 가능하다.
cols <- SetAlpha(c("moccasin", "salmon1", "wheat3", "gray32"), 0.8)
PlotMosaic(tab, col=cols, main = "Hair ~ Eye", horiz = FALSE)
PercTable(tab, freq=FALSE, rfrq="001")
Eye
Brown Hazel Green Blue
Hair
Black 30.9% 16.1% 7.8% 9.3%
Brown 54.1% 58.1% 45.3% 39.1%
Red 11.8% 15.1% 21.9% 7.9%
Blond 3.2% 10.8% 25.0% 43.7%
prop.table(margin.table(tab, 2))
Eye
Brown Hazel Green Blue
0.3716216 0.1570946 0.1081081 0.3631757
PlotCirc()
함수를 통해 두 변수의 각 수준별 관련성을 도식화하는 것도 가능하다.
# 원그래프
cols <- c("moccasin", "salmon1",
"wheat3", "gray32",
"slategray1", "chartreuse3",
"burlywood", "sienna4")
PlotCirc(t(tab), acol=cols)