R 다변량 그래프 (5) 체르노프 얼굴그림 (Chernoff faces) : aplpack package, faces() 함수
R 분석과 프로그래밍/R 그래프_시각화 2016. 3. 5. 13:25변수 3개 이상의 다변량 데이터(multivariate data set)를 2차원 평면에 효과적으로 시각화할 수 있는 방법으로
(1) 레이더 차트 (radar chart) or 거미줄 그림(spider plot)
(2) 별 그래프 (star graph) (레이더 차트와 유사, 중심점 차이 존재)
(3) 평행 좌표 그림 (parallel coordinate plot)
(4) 3차원 산점도 (3 dimensional scatter plot)
(5) 체르노프 얼굴그림 (Chernoff faces)
(6) 산점도 행렬(scatter plot matrix)
등이 있습니다.
이번 포스팅에서는 (5) 체르노프 얼굴그림 (Chernoff faces)에 대해서 소개하겠습니다.
체르노프 얼굴그림은 다변량 변수의 속성값들을 아래의 표에 나오는 것처럼 15가지의 얼굴의 생김새(얼굴 높이, 얼굴 넓이, 입 높이, 입 넓이...등) 특성에 매핑해서 얼굴 모양이 달라지게 하는 방식입니다.
얼굴 특성 (face characteristics) |
다변량 변수 (multivariate mapping) | |
1. 얼굴의 높이 |
"height of face " | "Price" |
2. 얼굴의 넓이 |
"width of face " |
"MPG.highway" |
3. 얼굴의 구조 |
"structure of face" |
"Horsepower" |
4. 입의 높이 |
"height of mouth " |
"RPM" |
5. 입의 넓이 |
"width of mouth " |
"Length" |
6. 웃음 |
"smiling " |
"Weight" |
7. 눈의 높이 |
"height of eyes " |
"Price" |
8. 눈의 넓이 |
"width of eyes " |
"MPG.highway" |
9. 머리카락 높이 |
"height of hair " |
"Horsepower" |
10. 머리카락 넓이 |
"width of hair " |
"RPM" |
11. 헤어스타일 |
"style of hair " |
"Length" |
12. 코 높이 |
"height of nose " |
"Weight" |
13. 코 넓이 |
"width of nose " |
"Price" |
14. 귀 넓이 |
"width of ear " |
"MPG.highway" |
15. 귀 높이 |
"height of ear " |
"Horsepower" |
체르노프 얼굴그림은 얼굴 모양을 가지고 데이터 관측치들의 특성을 직관적으로 파악할 수 있다는 장점이 있습니다. 다만, 각 변수가 얼굴 모양의 어느 특성에 매핑이 되었는지를 확인하고자 한다면 앞서 살펴본 레이터 차트나 별그림, 평행좌표그림 등에 비해 불편한 편이고, 왠지 official한 느낌은 덜 듭니다. 그래서 저 같은 경우는 회사에서 보고서에 체르노프 얼굴그림을 사용해본 적은 아직까지는 없습니다. ^^; 그래도 다변량 데이터를 신속하게, 직관적으로 탐색적분석 하는 용도로는 알아듬직 하므로 이번 포스팅을 이어가 보겠습니다.
예제에 사용할 데이터는 MASS Package에 내장되어있는 Cars93 dataframe을 사용하겠으며, 전체 93개의 관측치가 있는데요, 이를 모두 그리자니 너무 많아서요, 1번째 관측치부터 20번째 관측치까지만 사용하겠습니다. 체르노프 얼굴그림 그릴 때 사용할 변수로는 가격("Price"), 고속도로연비("MPG.highway"), 마력("Horsepower"), RPM("RPM"), 차길이("Length"), 차무게("Weight")의 5개만 선별해서 사용하겠습니다. 아래처럼 Cars93_1 이라는 새로운 이름의 데이터프레임을 만들었습니다.
> # dataset preparation > library(MASS) > 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 ... >
> Cars93_1 <- Cars93[c(1:20),c("Price", "MPG.highway", "Horsepower", "RPM", "Length", "Weight")] > Cars93_1 Price MPG.highway Horsepower RPM Length Weight 1 15.9 31 140 6300 177 2705 2 33.9 25 200 5500 195 3560 3 29.1 26 172 5500 180 3375 4 37.7 26 172 5500 193 3405 5 30.0 30 208 5700 186 3640 6 15.7 31 110 5200 189 2880 7 20.8 28 170 4800 200 3470 8 23.7 25 180 4000 216 4105 9 26.3 27 170 4800 198 3495 10 34.7 25 200 4100 206 3620 11 40.1 25 295 6000 204 3935 12 13.4 36 110 5200 182 2490 13 11.4 34 110 5200 184 2785 14 15.1 28 160 4600 193 3240 15 15.9 29 110 5200 198 3195 16 16.3 23 170 4800 178 3715 17 16.6 20 165 4000 194 4025 18 18.8 26 170 4200 214 3910 19 38.0 25 300 5000 179 3380 20 18.4 28 153 5300 203 3515 |
체로노프 얼굴그림을 그리기 위해 R의 aplpack Package의 faces() 함수를 사용하겠습니다.
install.package() 함수를 써서 설치하고, library() 함수로 호출해 보겠습니다.
> install.packages("aplpack") Installing package into ‘C:/Users/Owner/Documents/R/win-library/3.2’ (as ‘lib’ is unspecified) trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/aplpack_1.3.0.zip' Content type 'application/zip' length 3156450 bytes (3.0 MB) downloaded 3.0 MB package ‘aplpack’ successfully unpacked and MD5 sums checked The downloaded binary packages are in C:\Users\Owner\AppData\Local\Temp\Rtmpk3jrgb\downloaded_packages > > library(aplpack) 필요한 패키지를 로딩중입니다: tcltk
|
이제 faces() 함수로 체르노프 얼굴 그림을 그려보겠습니다.
faces(dataset, face.type = 0/1/2, main = "title") 의 형식으로 사용합니다.
face.type = 0 (line drawing faces)은 색깔 없이 선으로만 얼굴을 그립니다.
face.type = 1 (the elements of the faces are painted)는 색깔도 같이 칠해서 얼굴을 그려줍니다.
face.type = 2 (Santa Claus faces are drawn)는 산타클로스 얼굴에 색을 칠해서 그려주고요.
아래에 하나씩 예를 들어보겠습니다.
- face.type = 0 (line drawing faces)
|
- face.type = 1 (the elements of the faces are painted)
> # face.type = 1 : the elements of the faces are painted > faces(Cars93_1, face.type = 1, main = "Chernoff faces: face.type = 1") effect of variables: modified item Var "height of face " "Price" "width of face " "MPG.highway" "structure of face" "Horsepower" "height of mouth " "RPM" "width of mouth " "Length" "smiling " "Weight" "height of eyes " "Price" "width of eyes " "MPG.highway" "height of hair " "Horsepower" "width of hair " "RPM" "style of hair " "Length" "height of nose " "Weight" "width of nose " "Price" "width of ear " "MPG.highway" "height of ear " "Horsepower"
|
- face.type = 2 (Santa Claus faces are drawn)
> # face.type = 2 : Santa Claus faces are drawn > faces(Cars93_1, face.type = 2, main = "Chernoff faces: face.type = 2") effect of variables: modified item Var "height of face " "Price" "width of face " "MPG.highway" "structure of face" "Horsepower" "height of mouth " "RPM" "width of mouth " "Length" "smiling " "Weight" "height of eyes " "Price" "width of eyes " "MPG.highway" "height of hair " "Horsepower" "width of hair " "RPM" "style of hair " "Length" "height of nose " "Weight" "width of nose " "Price" "width of ear " "MPG.highway" "height of ear " "Horsepower"
|
산타클로스 얼굴은 정신이 하도 산만해서 관측치들간의 유사성이나 차이가 눈에 잘 안들어오네요. @@~
- 체로노프 얼굴그림에 이름 추가하기 : labels =
> # putting labels as face names : labels> faces(Cars93_1, face.type = 1, labels = Cars93[1:20,]$Model, + main = "putting labels as face names : labels = ")effect of variables: modified item Var "height of face " "Price" "width of face " "MPG.highway" "structure of face" "Horsepower" "height of mouth " "RPM" "width of mouth " "Length" "smiling " "Weight" "height of eyes " "Price" "width of eyes " "MPG.highway" "height of hair " "Horsepower" "width of hair " "RPM" "style of hair " "Length" "height of nose " "Weight" "width of nose " "Price" "width of ear " "MPG.highway" "height of ear " "Horsepower"
|
- 산점도에 체르노프 얼굴그림 겹쳐 그르기 (overlapping chernoff faces over scatter plot)
(1) 먼저 산점도를 plot() 함수를 사용해서 그립니다.
(2) 그 다음에 faces() 함수로 체르노프 얼굴그림을 실행시킵니다. 이때 scale = TRUE, plot = FALSE 옵션을 사용해줍니다. 그래프는 화면에 안나타나구요, (3)번 스텝에서 그래프가 그려질 수 있도록 데이터가 준비된 상태입니다.
(3) plot.faces() 함수를 사용해서 산점도 위에 (2)번에서 생성해 놓은 체르노프 얼굴그림을 겹쳐서 그려줍니다. width 와 height 는 x축과 y축의 단위를 보고서 trial & error 를 해보면서 숫자를 조금씩 바꿔가면서 그려본 후에 가장 마음에 드는 걸로 선택하면 되겠습니다.
체르노프 얼굴그림을 산점도에 겹쳐서 그리니 제법 유용한 다차원 그래프이지 않은가요? ^^
> # Overlapping Chernoff faces over scatter plot (MPG.highway*Weight) > plot(Cars93_1[,c("MPG.highway", "Weight")], + bty="n", # To make a plot with no box around the plot area + main = "Chernoff faces of Cars93")
> Cars93_1_faces <- faces(Cars93_1, scale = TRUE, plot=FALSE) effect of variables: modified item Var "height of face " "Price" "width of face " "MPG.highway" "structure of face" "Horsepower" "height of mouth " "RPM" "width of mouth " "Length" "smiling " "Weight" "height of eyes " "Price" "width of eyes " "MPG.highway" "height of hair " "Horsepower" "width of hair " "RPM" "style of hair " "Length" "height of nose " "Weight" "width of nose " "Price" "width of ear " "MPG.highway" "height of ear " "Horsepower" > > plot.faces(Cars93_1_faces, + Cars93_1[,c("MPG.highway")], + Cars93_1[,c("Weight")], + width = 2, + height = 250)
|
체르노프 얼굴그림에 대해서 좀더 알고 싶은 분은 아래의 Reference를 참고하시기 바랍니다.
[ Reference ] http://www.inside-r.org/packages/cran/aplpack/docs/faces
많은 도움 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^