14.5 체르노프 얼굴그림 (Chernoff faces) : aplpack
package, faces()
함수
이번 포스팅에서는 (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한 느낌은 덜 듭니다. 그래서 저 같은 경우는 회사에서 보고서에 체르노프 얼굴그림을 사용해본 적은 아직까지는 없습니다. ^^; 그래도 다변량 데이터를 신속하게, 직관적으로 탐색적분석 하는 용도로는 알아듬직 하므로 이번 포스팅을 이어가 보겠습니다.
14.5.1 데이터 세트
예제에 사용할 데이터는 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 ...
# sampling observations from 1st to 20th, selecting 5 variables
<- Cars93[c(1:20),c("Price", "MPG.highway", "Horsepower",
Cars93_1 "RPM", "Length", "Weight")]
Cars93_1
## Price MPG.highway Horsepower RPM Length Weight
## 1 16 31 140 6300 177 2705
## 2 34 25 200 5500 195 3560
## 3 29 26 172 5500 180 3375
## 4 38 26 172 5500 193 3405
## 5 30 30 208 5700 186 3640
## 6 16 31 110 5200 189 2880
## 7 21 28 170 4800 200 3470
## 8 24 25 180 4000 216 4105
## 9 26 27 170 4800 198 3495
## 10 35 25 200 4100 206 3620
## 11 40 25 295 6000 204 3935
## 12 13 36 110 5200 182 2490
## 13 11 34 110 5200 184 2785
## 14 15 28 160 4600 193 3240
## 15 16 29 110 5200 198 3195
## 16 16 23 170 4800 178 3715
## 17 17 20 165 4000 194 4025
## 18 19 26 170 4200 214 3910
## 19 38 25 300 5000 179 3380
## 20 18 28 153 5300 203 3515
14.5.2 체로노프 얼굴그림 그리기
14.5.2.1 패키지 불러오기
체로노프 얼굴그림을 그리기 위해 R의 aplpack Package의 faces() 함수를 사용하겠습니다.
install.package() 함수를 써서 설치하고, library() 함수로 호출해 보겠습니다.
# install.packages("aplpack")
library(aplpack)
14.5.2.2 faces()
함수의 형식
이제 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)는 산타클로스 얼굴에 색을 칠해서 그려주고요.
아래에 하나씩 예를 들어보겠습니다.
14.5.2.3 체르노프 얼굴 그림 그리기
14.5.2.3.1 face.type = 0 (line drawing faces)
# face.type = 0 : line drawing faces
faces(Cars93_1, face.type = 0, main = "Chernoff faces: face.type = 0")
## 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"
14.5.2.3.2 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"
14.5.2.3.3 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"
산타클로스 얼굴은 정신이 하도 산만해서 관측치들간의 유사성이나 차이가 눈에 잘 안들어오네요. @@~
14.5.2.3.4 체로노프 얼굴그림에 이름 추가하기 : 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"
14.5.3 산포도에 체르노프 얼굴그림 겹쳐 그르기
먼저 산포도를
plot()
함수를 사용해서 그립니다.그 다음에
faces()
함수로 체르노프 얼굴그림을 실행시킵니다. 이때scale = TRUE, plot = FALSE
옵션을 사용해줍니다. 그래프는 화면에 안나타나구요, (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")
<- faces(Cars93_1, scale = TRUE, plot=FALSE) Cars93_1_faces
## 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,
c("MPG.highway")],
Cars93_1[,c("Weight")],
Cars93_1[,width = 2,
height = 250)
체르노프 얼굴그림에 대해서 좀더 알고 싶은 분은 아래의 Reference를 참고하시기 바랍니다.
- [ Reference ] http://www.inside-r.org/packages/cran/aplpack/docs/faces