[R] R로 구현하는 주성분 분석(Principal Component Analysis)
R로 구현하는 주성분 분석(Principal Component Analysis)
Superkong1
주성분 분석 이론 설명
주성분 분석(PCA: Principal Component Analysis)
은 서로 상관성이 높은 변수들이 있는 데이터의 차원을 축소하는 기법으로,
여러 변수들의 일정 비율로 이루어진 주성분으로 변수를 설명할 수 있게 한다.
보통 변수 하나를 하나의 차원으로 비유한다. 그래서 2개 변수의 관계(x,y 그래프)를 시각화할 때에는 2차원으로,
3개 변수의 관계를 시각화한다면 3차원으로 표현한다.
3차원 이상으로 넘어가면 한 집단(분류)을 구분하기가 힘들어지는데,
이때 주성분 분석으로 차원을 축소하여 일정 비율 이상의 데이터를 설명하는 효율적인 방법을 사용하곤 한다.
또한, 머신러닝(Machine Learning)을 통한 분류, 회귀 분석 진행 시 변수들간의 상관관계가 높은 다중공선성이 존재할 수 있다.
다중공선성은 특히 회귀분석의 전제 가정을 위배하는 것이므로 이를 해결해야 제대로 된 모델을 생성할 수 있다.
이에 대한 해결방법으로 변수를 제거하거나 상관관계의 원인을 파악해도 되지만, 주성분 분석 역시 하나의 해결방법이다.
Data Set
앞서 Knn, Naive Bayes 구현을 위해 사용하였던
zoo2.csv(신체 특징을 통해 척추동물의 종류를 구별하는 Data Set)를 동일하게 사용하였다. (Data Set 링크)
아마 대부분의 기계학습은 해당 Data로 계속 진행할 것 같다.
Data Set에 대한 설명은 링크를 참조하면 되겠다.
zoo<-read.csv("C:/Users/user/Documents/zoo.csv", header=T, stringsAsFactors = F)
head(zoo)
hair feathers eggs milk airborne aquatic predator toothed backbone
1 1 0 0 1 0 0 1 1 1
2 1 0 0 1 0 0 0 1 1
3 0 0 1 0 0 1 1 1 1
4 1 0 0 1 0 0 1 1 1
5 1 0 0 1 0 0 1 1 1
6 1 0 0 1 0 0 0 1 1
breathes venomous fins legs tail domestic catsize type
1 1 0 0 4 0 0 1 1
2 1 0 0 4 1 0 1 1
3 0 0 1 0 1 0 0 4
4 1 0 0 4 0 0 1 1
5 1 0 0 4 1 0 1 1
6 1 0 0 4 1 0 1 1
str(zoo)
'data.frame': 101 obs. of 17 variables:
$ hair : int 1 1 0 1 1 1 1 0 0 1 ...
$ feathers: int 0 0 0 0 0 0 0 0 0 0 ...
$ eggs : int 0 0 1 0 0 0 0 1 1 0 ...
$ milk : int 1 1 0 1 1 1 1 0 0 1 ...
$ airborne: int 0 0 0 0 0 0 0 0 0 0 ...
$ aquatic : int 0 0 1 0 0 0 0 1 1 0 ...
$ predator: int 1 0 1 1 1 0 0 0 1 0 ...
$ toothed : int 1 1 1 1 1 1 1 1 1 1 ...
$ backbone: int 1 1 1 1 1 1 1 1 1 1 ...
$ breathes: int 1 1 0 1 1 1 1 0 0 1 ...
$ venomous: int 0 0 0 0 0 0 0 0 0 0 ...
$ fins : int 0 0 1 0 0 0 0 1 1 0 ...
$ legs : int 4 4 0 4 4 4 4 0 0 4 ...
$ tail : int 0 1 1 0 1 1 1 1 1 0 ...
$ domestic: int 0 0 0 0 0 0 1 1 0 1 ...
$ catsize : int 1 1 0 1 1 1 1 0 0 0 ...
$ type : int 1 1 4 1 1 1 1 4 4 1 ...
dim(zoo)
[1] 101 17
summary(zoo)
hair feathers eggs milk
Min. :0.0000 Min. :0.000 Min. :0.0000 Min. :0.0000
1st Qu.:0.0000 1st Qu.:0.000 1st Qu.:0.0000 1st Qu.:0.0000
Median :0.0000 Median :0.000 Median :1.0000 Median :0.0000
Mean :0.4257 Mean :0.198 Mean :0.5842 Mean :0.4059
3rd Qu.:1.0000 3rd Qu.:0.000 3rd Qu.:1.0000 3rd Qu.:1.0000
Max. :1.0000 Max. :1.000 Max. :1.0000 Max. :1.0000
airborne aquatic predator toothed
Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.000
1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.000
Median :0.0000 Median :0.0000 Median :1.0000 Median :1.000
Mean :0.2376 Mean :0.3564 Mean :0.5545 Mean :0.604
3rd Qu.:0.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.000
Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.000
backbone breathes venomous fins
Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000
1st Qu.:1.0000 1st Qu.:1.0000 1st Qu.:0.00000 1st Qu.:0.0000
Median :1.0000 Median :1.0000 Median :0.00000 Median :0.0000
Mean :0.8218 Mean :0.7921 Mean :0.07921 Mean :0.1683
3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:0.00000 3rd Qu.:0.0000
Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000
legs tail domestic catsize
Min. :0.000 Min. :0.0000 Min. :0.0000 Min. :0.0000
1st Qu.:2.000 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.0000
Median :4.000 Median :1.0000 Median :0.0000 Median :0.0000
Mean :2.842 Mean :0.7426 Mean :0.1287 Mean :0.4356
3rd Qu.:4.000 3rd Qu.:1.0000 3rd Qu.:0.0000 3rd Qu.:1.0000
Max. :8.000 Max. :1.0000 Max. :1.0000 Max. :1.0000
type
Min. :1.000
1st Qu.:1.000
Median :2.000
Mean :2.832
3rd Qu.:4.000
Max. :7.000
zoo Data Set의 변수들끼리 상관성이 있나 확인해보자!
변수들 간의 상관성을 알아보는 함수 중 R 내장 함수로 cor
함수가 있으며
라벨값인 type 변수를 빼고 데이터를 넣어보았다.
zoo2<-zoo[ , -17]
cor(zoo2)
hair feathers eggs milk airborne
hair 1.00000000 -0.42785117 -0.81738155 0.87850272 -0.198431398
feathers -0.42785117 1.00000000 0.41924812 -0.41076061 0.656553076
eggs -0.81738155 0.41924812 1.00000000 -0.93884787 0.376646041
milk 0.87850272 -0.41076061 -0.93884787 1.00000000 -0.366765280
airborne -0.19843140 0.65655308 0.37664604 -0.36676528 1.000000000
aquatic -0.47355439 -0.05855169 0.37624403 -0.36261333 -0.172637658
predator -0.15476873 -0.10442986 0.01160505 -0.02972103 -0.295180850
toothed 0.49253051 -0.61363117 -0.64215012 0.62816850 -0.594310575
backbone 0.19168062 0.23140338 -0.34042022 0.38495814 -0.104718392
breathes 0.44114858 0.25458754 -0.38277692 0.42352686 0.286038777
venomous -0.10424462 -0.14573907 0.09868876 -0.24244868 0.008528302
fins -0.28031307 -0.22354106 0.16479610 -0.15632771 -0.251156878
legs 0.39400851 -0.20668605 -0.22491847 0.21419633 0.043711931
tail 0.04897317 0.29256915 -0.22108960 0.21002596 0.009482093
domestic 0.20720814 0.03158624 -0.15561004 0.16392762 0.063273788
catsize 0.45501978 -0.13593437 -0.51465031 0.57490606 -0.349768123
aquatic predator toothed backbone breathes
hair -0.47355439 -0.15476873 0.49253051 0.19168062 0.44114858
feathers -0.05855169 -0.10442986 -0.61363117 0.23140338 0.25458754
eggs 0.37624403 0.01160505 -0.64215012 -0.34042022 -0.38277692
milk -0.36261333 -0.02972103 0.62816850 0.38495814 0.42352686
airborne -0.17263766 -0.29518085 -0.59431058 -0.10471839 0.28603878
aquatic 1.00000000 0.37597813 0.05314971 0.02246291 -0.63750633
predator 0.37597813 1.00000000 0.12945232 0.05102225 -0.26293134
toothed 0.05314971 0.12945232 1.00000000 0.57508512 -0.06569043
backbone 0.02246291 0.05102225 0.57508512 1.00000000 0.20766627
breathes -0.63750633 -0.26293134 -0.06569043 0.20766627 1.00000000
venomous 0.08791512 0.11539058 -0.06234447 -0.24661051 -0.12075153
fins 0.60449157 0.19030177 0.36429222 0.20949903 -0.61721880
legs -0.36063790 -0.09972295 -0.19347599 -0.43285611 0.36986780
tail -0.03464228 0.01894662 0.31036765 0.73176197 0.08895163
domestic -0.22430819 -0.30979361 0.06943046 0.10173335 0.12406829
catsize -0.11186587 0.14478959 0.34400985 0.35697597 0.20412473
venomous fins legs tail domestic
hair -0.104244620 -0.28031307 0.39400851 0.048973171 0.207208138
feathers -0.145739075 -0.22354106 -0.20668605 0.292569150 0.031586240
eggs 0.098688757 0.16479610 -0.22491847 -0.221089599 -0.155610045
milk -0.242448679 -0.15632771 0.21419633 0.210025957 0.163927618
airborne 0.008528302 -0.25115688 0.04371193 0.009482093 0.063273788
aquatic 0.087915124 0.60449157 -0.36063790 -0.034642281 -0.224308186
predator 0.115390578 0.19030177 -0.09972295 0.018946619 -0.309793614
toothed -0.062344465 0.36429222 -0.19347599 0.310367651 0.069430463
backbone -0.246610510 0.20949903 -0.43285611 0.731761968 0.101733346
breathes -0.120751535 -0.61721880 0.36986780 0.088951634 0.124068289
venomous 1.000000000 -0.03395607 0.02296377 -0.162724257 -0.003251785
fins -0.033956074 1.00000000 -0.60565181 0.204349213 -0.093886712
legs 0.022963774 -0.60565181 1.00000000 -0.348294672 0.073931181
tail -0.162724257 0.20434921 -0.34829467 1.000000000 0.023433531
domestic -0.003251785 -0.09388671 0.07393118 0.023433531 1.000000000
catsize -0.183748367 0.03170468 0.06879053 0.243277085 0.020072531
catsize
hair 0.45501978
feathers -0.13593437
eggs -0.51465031
milk 0.57490606
airborne -0.34976812
aquatic -0.11186587
predator 0.14478959
toothed 0.34400985
backbone 0.35697597
breathes 0.20412473
venomous -0.18374837
fins 0.03170468
legs 0.06879053
tail 0.24327709
domestic 0.02007253
catsize 1.00000000
숫자가 1에 가까울수록 양의 상관관계를 가지고 있으며, -1에 가까울수록 음의 상관관계를 가지고 있다.
현재 1에 가까운 변수들의 관계가 보이는데 조금 더 명확하게 확인하기 위해
cor함수의 결과를 시각화해주는 corrplot
패키지를 사용하였다.
library(corrplot)
png(height=1200, width=1500, pointsize=15, file="overlap.png") #png 파일로 저장
corrplot.mixed(cor(zoo2), upper="shade") #시각화
청색 사각형이 진한 것은 즉 해당 변수들 간의 양의 상관관계가 크다는 것이고,
적색 사각형이 진한 것은 해당 변수들 간의 음의 상관관계가 크다는 것이다.
상관관계가 양/음으로 큰 것이 많아 Data를 바로 머신러닝에 적용하는 것보다는
PCA를 진행한 후 나온 주성분으로 진행하는 것이 더 효과적일 것이라 판단되었다.
이를 확인하기 위해 기존 zoo 데이터로 회귀분석을 진행하였다. (Data Set이 작아 교차검증으로 훈련/시험 데이터를 분류하였다.)
library(caret)
set.seed(12345) #일정한 Random값을 준다
idx <- createFolds(zoo$type, k=4) #4개로 나누어 교차검증 실시
test<-data.frame(zoo[idx$Fold4, ]) #test data 생성
train<-data.frame(zoo[-idx$Fold4, ]) #train data 생성
fit<-lm(type ~ ., data=train) #다중회귀모델 생성
summary(fit) #모델 정보 보기
Call:
lm(formula = type ~ ., data = train)
Residuals:
Min 1Q Median 3Q Max
-0.78493 -0.09577 -0.00173 0.11715 0.83709
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6.62739 0.33977 19.505 < 2e-16 ***
hair -0.32976 0.21017 -1.569 0.1220
feathers -1.10228 0.47810 -2.306 0.0247 *
eggs 0.19355 0.29509 0.656 0.5144
milk -2.09309 0.39995 -5.233 2.32e-06 ***
airborne -0.27514 0.14017 -1.963 0.0544 .
aquatic 0.18385 0.13158 1.397 0.1676
predator -0.14823 0.08859 -1.673 0.0996 .
toothed 0.26025 0.44810 0.581 0.5636
backbone -2.92445 0.50361 -5.807 2.70e-07 ***
breathes -0.25324 0.16304 -1.553 0.1257
venomous 0.07897 0.18241 0.433 0.6666
fins 0.04010 0.18093 0.222 0.8254
legs 0.03620 0.02732 1.325 0.1902
tail -0.33615 0.14782 -2.274 0.0266 *
domestic -0.11452 0.12610 -0.908 0.3675
catsize -0.06468 0.09682 -0.668 0.5067
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.3069 on 59 degrees of freedom
Multiple R-squared: 0.9847, Adjusted R-squared: 0.9805
F-statistic: 237 on 16 and 59 DF, p-value: < 2.2e-16
결과를 보면, 밑에서 두번째 줄 Adjusted R-squared(조정된 결정계수)
는 0.9805이므로
회귀모델의 설명력은 98.05%라고 이야기할 수 있다.
또한, 회귀모델의 p-value
는 < 2.2e-16으로 유의수준 0.05보다 작으므로
회귀모델은 유의미하고 해석할 수 있다.
그러나 중간 부분인 Coefficients 부분 대부분의 변수의 Pr(>|t|),
즉 p-value
가 유의수준 0.05보다 크기 때문에 모든 변수가 유의미하다고는 해석할 수 없다.
생성된 모델을 테스트해보고 결과값을 비교해보자.
fit_pred <- predict(fit,newdata = test) #생성한 모델 테스트
fit_pred <- round(fit_pred) #결과값 소수점을 반올림으로 정리
result<-data.frame(fit_pred, test$type) #수치 확인
prop.table(table(ifelse(result$fit_pred==result$test.type, 'O', 'X'))) #정확도 확인
O X
0.84 0.16
84%가 나왔다. 이제 주성분분석을 통해서 위의 정확도를 높일 것이다.
주성분 분석 실행
주성분 분석을 실행하는 함수인 prcomp
는 R 기본 내장 함수로 패키지를 불러올 필요가 없다.
prcomp 함수 사용 방법은 “prcomp(데이터명, center(0이 가운데로 오게 하려면 T), scale(표준화하려면 T))”이다.
pca_zoo<-prcomp(zoo2, center=T, scale=T) #라벨 제외한 데이터 넣어주기, leg와 다른 변수의 차이로 표준화 진행
pca_zoo
Standard deviations (1, .., p=16):
[1] 2.1611512 1.8279126 1.5376982 1.1094762 0.9766976 0.8637323 0.7502086
[8] 0.7158401 0.6691730 0.6163235 0.5268610 0.4590507 0.3599192 0.3434271
[15] 0.1904509 0.1333544
Rotation (n x k) = (16 x 16):
PC1 PC2 PC3 PC4 PC5
hair -0.40781682 0.113787661 -0.10005203 0.05530359 -0.009809592
feathers 0.20156822 0.192502301 0.48301504 -0.17809415 -0.036434527
eggs 0.43158652 0.005130841 0.04178035 0.01426172 0.091265259
milk -0.44479630 -0.001635436 -0.01267313 -0.03047774 0.056347892
airborne 0.19541969 0.311645431 0.27830433 0.04158989 -0.074017532
aquatic 0.20486980 -0.373556142 -0.06308768 -0.06944122 0.060612264
predator 0.02901627 -0.252801176 -0.11773037 -0.57821523 -0.226856601
toothed -0.32298104 -0.320714639 -0.02356268 0.16552481 -0.094193168
backbone -0.20544385 -0.204605985 0.47642004 -0.01610225 -0.132586152
breathes -0.21041493 0.366020432 0.18971112 -0.16697296 -0.113468339
venomous 0.09561801 -0.002572422 -0.22627612 0.08610457 -0.899367272
fins 0.08175466 -0.454630774 0.04626720 0.21557957 0.129520397
legs -0.11455341 0.340245130 -0.31290123 -0.16874867 0.074115877
tail -0.12404631 -0.160614956 0.48311936 -0.04923232 -0.194076689
domestic -0.09681845 0.117442571 0.08098942 0.62769554 -0.079154927
catsize -0.28884911 -0.092983107 0.06893596 -0.29812608 0.109852410
PC6 PC7 PC8 PC9 PC10
hair 0.06161242 -0.07515992 0.334981626 -0.001301239 0.15512519
feathers -0.19625267 -0.02564308 0.022995325 -0.065117752 -0.05390175
eggs -0.05356323 -0.02890185 -0.138575999 0.031190293 -0.11994331
milk 0.01613469 0.01046026 0.199351722 -0.096391430 0.05439175
airborne 0.09999599 -0.10959835 0.669797120 -0.028090132 0.25288598
aquatic -0.19214372 -0.02543174 0.480033711 0.209284206 -0.54743189
predator -0.34599871 0.46764905 0.138975446 -0.215061046 0.31712410
toothed 0.19945655 0.19723504 0.030502760 -0.017126503 -0.17861926
backbone 0.01469534 0.15645504 0.003369248 -0.002809072 -0.35732051
breathes 0.09901229 0.03535602 0.028166893 -0.277439128 -0.40450808
venomous 0.01426752 -0.30043464 -0.003942459 0.023862483 -0.07413472
fins 0.04415996 -0.25279402 0.260343225 -0.038751534 0.21715242
legs -0.16148376 0.11487544 0.132149192 0.658732454 -0.14610223
tail 0.08427094 0.04507103 -0.160807230 0.615119601 0.30449191
domestic -0.70267677 0.23291114 -0.001917761 -0.045425876 0.03916579
catsize -0.45720535 -0.68783969 -0.130705985 -0.030737568 -0.00542077
PC11 PC12 PC13 PC14 PC15
hair -0.126364395 0.240440840 0.57497169 0.37241122 0.317488293
feathers -0.271401159 -0.010595538 -0.23097041 0.49356960 0.305939331
eggs 0.339430705 0.309095246 0.56718155 0.05341767 -0.238604529
milk -0.264907004 -0.192532452 0.02428247 0.01345932 -0.604889912
airborne 0.154556603 0.242072995 -0.15446276 -0.36345091 -0.078150678
aquatic -0.296648598 -0.184669662 0.16541568 -0.17969420 0.112444296
predator 0.163251706 0.006723729 0.06172096 -0.00769942 0.008438059
toothed 0.258974199 0.324786984 -0.23109588 -0.17512479 0.404762772
backbone 0.085608503 0.373509246 -0.07088645 0.22965938 -0.394495610
breathes 0.427508499 -0.492219367 0.20131286 -0.10041978 0.128970034
venomous -0.032641362 -0.008960971 -0.02060082 0.10963883 -0.092176109
fins 0.460929580 -0.355648714 -0.11606265 0.42906894 -0.047004611
legs 0.306509892 0.044660477 -0.24375442 0.24962280 -0.088447961
tail -0.008998563 -0.247623649 0.24957769 -0.21609532 0.078289499
domestic 0.060274550 -0.074228553 0.04464635 -0.08344367 0.014822352
catsize 0.134541662 0.184542762 -0.04684645 -0.21125773 0.054636237
PC16
hair 0.134120262
feathers -0.380512013
eggs -0.415846110
milk -0.521173008
airborne 0.009858174
aquatic 0.011355493
predator 0.020304189
toothed -0.472995861
backbone 0.398108510
breathes 0.016596916
venomous -0.068858540
fins 0.014957169
legs -0.041587882
tail -0.052231593
domestic 0.009209922
catsize -0.006001941
원래 zoo2의 변수가 16개였으므로, 주성분도 16개가 생성된다.
Rotation 부분을 보면 각 주성분에서 각각의 변수가 미치는 영향(계수)를 확인할 수 있는데,
일반적으로 plot을 그려 곡선의 기울기가 급격히 수평으로 눕는 주성분의 전단계까지 활용한다.
screeplot(pca_zoo, npcs=16, type='l')
4단계부터 급격히 기울기가 줄어들었으나, 그 이후 감소되는 부분이 적지 않다.
summary를 통해 주성분의 누적 기여율(Cumulative Proportion)이 85%가 넘는 부분을 확인, 사용하자.
summary(pca_zoo)
Importance of components:
PC1 PC2 PC3 PC4 PC5 PC6
Standard deviation 2.1612 1.8279 1.5377 1.10948 0.97670 0.86373
Proportion of Variance 0.2919 0.2088 0.1478 0.07693 0.05962 0.04663
Cumulative Proportion 0.2919 0.5007 0.6485 0.72546 0.78508 0.83170
PC7 PC8 PC9 PC10 PC11 PC12
Standard deviation 0.75021 0.71584 0.66917 0.61632 0.52686 0.45905
Proportion of Variance 0.03518 0.03203 0.02799 0.02374 0.01735 0.01317
Cumulative Proportion 0.86688 0.89891 0.92689 0.95063 0.96798 0.98115
PC13 PC14 PC15 PC16
Standard deviation 0.3599 0.34343 0.19045 0.13335
Proportion of Variance 0.0081 0.00737 0.00227 0.00111
Cumulative Proportion 0.9892 0.99662 0.99889 1.00000
결과대로 Cumulative Proportion이 85% 이상인 주성분7(PC7)까지 사용하기로 하자.
주성분 회귀분석 실행
항상 이론보다는 적용이 중요하다고 생각한다.
기존 라벨을 제외한 zoo2의 데이터를 행렬로 만들고,
주성분 분석을 거친 pca_zoo의 rotation을 행렬곱(%*%)
한 Data Set을 만들어보자.(회귀분석 사용을 위함)
zoo3<-as.matrix(zoo2) %*% pca_zoo$rotation[ , 1:7] # 행렬곱 실시,
zoo4<-cbind(zoo3, as.data.frame(zoo$type)) # 기존 라벨 더해주기
colnames(zoo4)[8]<-'type'
head(zoo4)
PC1 PC2 PC3 PC4 PC5 PC6
1 -2.30949940 0.9680483 -0.7705560 -1.5440605 -0.11425004 -1.0582278
2 -2.46256198 1.0602345 -0.1697063 -1.0150776 -0.08147013 -0.6279582
3 0.09475605 -1.7617928 0.8432062 -0.3176249 -0.36631469 -0.2491229
4 -2.30949940 0.9680483 -0.7705560 -1.5440605 -0.11425004 -1.0582278
5 -2.43354571 0.8074333 -0.2874366 -1.5932928 -0.30832673 -0.9739569
6 -2.46256198 1.0602345 -0.1697063 -1.0150776 -0.08147013 -0.6279582
PC7 type
1 0.5636576 1
2 0.1410796 1
3 0.5592826 4
4 0.5636576 1
5 0.6087286 1
6 0.1410796 1
자, 이제 두근대는 마음으로 다시 회귀분석을 해보자.
library(caret)
set.seed(12345) #이전과 동일하게 일정한 Random값을 준다(동등한 조건)
idx_pca <- createFolds(zoo4$type, k=4) #4개로 나누어 교차검증 실시
test_pca<-data.frame(zoo4[idx_pca$Fold4, ]) #test data 생성
train_pca<-data.frame(zoo4[-idx_pca$Fold4, ]) #train data 생성
fit_pca <- lm(type ~ ., data=train_pca) #회귀분석 실시
summary(fit_pca)
Call:
lm(formula = type ~ ., data = train_pca)
Residuals:
Min 1Q Median 3Q Max
-1.14877 -0.31274 -0.02064 0.28354 1.56288
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.73565 0.17476 32.819 < 2e-16 ***
PC1 1.64621 0.05910 27.853 < 2e-16 ***
PC2 -0.19344 0.06834 -2.831 0.006103 **
PC3 -1.98363 0.09319 -21.287 < 2e-16 ***
PC4 0.39482 0.13884 2.844 0.005884 **
PC5 -0.03323 0.19867 -0.167 0.867649
PC6 0.42837 0.17471 2.452 0.016782 *
PC7 -0.71923 0.18726 -3.841 0.000272 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.5305 on 68 degrees of freedom
Multiple R-squared: 0.9472, Adjusted R-squared: 0.9418
F-statistic: 174.4 on 7 and 68 DF, p-value: < 2.2e-16
결과를 보면, 밑에서 두번째 줄 Adjusted R-squared(조정된 결정계수)
는 0.9418로
회귀모델의 설명력은 98.05% → 94.18%로 감소했지만, 적은 수준은 아니다.
또한, 회귀모델의 p-value
는 < 2.2e-16으로 동일하며,
Coefficients 부분 대부분의 변수의 p-value는 유의수준 0.05보다 작아 다중공선성 문제를 해결한 듯 보인다.
이제 생성된 모델을 테스트해보고 결과값을 비교해보자.
fit_pca_pred <- predict(fit_pca, newdata = test_pca) #생성한 모델에 test data 넣기
fit_pca_pred <- round(fit_pca_pred) #결과값 소수점을 반올림으로 정리
result_pca<-data.frame(fit_pca_pred, test_pca$type) #수치 확인
prop.table(table(ifelse(result_pca$fit_pca_pred==result_pca$test_pca.type, 'O', 'X'))) #정확도 확인
O X
0.76 0.24
엥? 76%라는 정확도가 나왔다… (주성분 분석 전 정확도가 84%)
몇 시간동안 어떤 부분이 잘못되었는지 예전 공부했던 내용들과 자료를 살피고,
주성분의 갯수를 늘리는 등 몇 십가지의 모델을 생성했으나 예상값은 높은 정확도가 나오지 않았다.
결론
결과에 대한 본인의 결론은 아래와 같다.
각 Column(변수)의 값이 대부분 명목변수로, 0 or 1로 되어있는 데이터의 특성으로 주성분 분석 이후 정확도가 더 떨어짐
교차검증을 실시하였지만 Data Set Size가 작아 Test data가 25개 밖에 되지 않았음
legs 변수를 binary화해도 된다면 로지스틱 회귀분석이 더 정확도가 높을 것으로 예상
요약하면 주성분 분석은 대부분의 변수가 연속변수인 매우 많은 양의 데이터에서 매우 효과적인 것으로 예상된다.
→ 찾아본 주성분 분석 예제의 대부분의 자료는 이러하였음
개인적으로도 아쉬운 분석이었고, 만약 이 글을 읽으시는 분들도
주성분 분석에 대해 더 많은 정보를 얻고 싶어하실것이라 생각한다.
본인이 찾아본 글들 중 가장 이해하기 쉽게 잘 설명한 링크 몇 가지를 추천한다. 꼭 도움이 되길 바란다.
링크1 링크2 링크3 링크4