본 글에서는 저번 글에 이어서 유방암 환자 데이터 (Breast Cancer Wisconsin) 데이터를 바탕으로 진행되는 주성분분석 (PCA)의 과정을 살펴볼 것입니다. 저번 글에서는 PCA를 진행하기에 앞서 주성분의 개수를 선택하는 과정을 진행하였고, 여러 방법들을 고려했을 때 유방암 환자 데이터에 대해서는 6개의 주성분으로 차원 축소하는 것이 적절하다고 결정하였습니다. 선택 과정은 해당 글에서 살펴볼 수 있습니다.
전체적인 분석 과정을 다시 요약하면, (1) 원본 데이터, (2) PCA를 적용한 데이터, 각각에 비지도 학습 중 하나인 K-means 군집 분석을 적용하고, K-means를 통해 분류된 양성 여부와 실제 양성 여부 간의 정확도를 측정하여 PCA의 적용이 유의미한지 판단하는 것입니다.
1) K-menas 군집 분석 (원본 데이터)
타겟 변수인 유방암 양성 여부는 1) 양성 (Benign), 2) 악성 (Malignant), 두 개의 값을 가지기 때문에, k를 2로 설정하고 K-means 군집 분석을 진행하였습니다. 분석 코드는 다음과 같이 K-means 군집 분석을 수행하고, 결과를 새로운 변수에 할당하는 것입니다.
> set.seed(1234)
> kmeans_model <- kmeans(bcw_raw[, 3:32], 2, iter.max = 10, nstart = 1)
> bcw_raw$kmeans_raw2 <- kmeans_model$cluster
다음은 K-means 군집 분석을 통해서 분류된 유방암 양성 여부를 시각화한 결과입니다. B는 양성, M은 악성을 의미하며, 시각화 결과 비교의 편의를 위해 원본 데이터도 주성분 1, 2를 바탕으로 시각화를 진행하였습니다. 두 군집으로 잘 나뉜 것을 확인할 수 있습니다.
> par(mar = c(5, 5, 5, 0))
>
> plot.new()
> plot.window(xlim = c(-20, 10), ylim = c(-15, 10))
> abline(h = seq(-15, 10, 5), v = seq(-20, 10, 5), col = "grey", lty = 3)
>
> points(bcw_raw[bcw_raw$kmeans_raw2 == 2, "pc1"],
> bcw_raw[bcw_raw$kmeans_raw2 == 2, "pc2"], pch = 16, col = "#FC766AFF",
> cex = 0.75)
> points(bcw_raw[bcw_raw$kmeans_raw2 == 1, "pc1"],
> bcw_raw[bcw_raw$kmeans_raw2 == 1, "pc2"], pch = 16, col = "#5B84B1FF",
> cex = 0.75)
>
> axis(side = 1, at = seq(-20, 10, 5), cex.axis = 1)
> axis(side = 2, at = seq(-15, 10, 5), las = 2, cex.axis = 1)
>
> mtext("PC1", 1, line = 3, cex = 1)
> mtext("PC2", 2, line = 3, cex = 1)
>
> legend(-20, 10, pch = 16, col = c("#5B84B1FF", "#FC766AFF"),
> legend = c("B", "M"))
2) K-means 군집 분석 (PCA 적용 데이터)
원본 데이터에 적용한 것과 같이 PCA를 적용한 데이터에도 똑같은 과정을 진행하였습니다. 이 역시 두 그룹으로 잘 나뉜 것을 확인할 수 있습니다.
> par(mar = c(5, 5, 5, 0))
>
> plot.new()
> plot.window(xlim = c(-20, 10), ylim = c(-15, 10))
> abline(h = seq(-15, 10, 5), v = seq(-20, 10, 5), col = "grey", lty = 3)
>
> points(bcw_raw[bcw_raw$kmeans_pca2 == 2, "pc1"],
> bcw_raw[bcw_raw$kmeans_pca2 == 2, "pc2"], pch = 16, col = "#FC766AFF",
> cex = 0.75)
> points(bcw_raw[bcw_raw$kmeans_pca2 == 1, "pc1"],
> bcw_raw[bcw_raw$kmeans_pca2 == 1, "pc2"], pch = 16, col = "#5B84B1FF",
> cex = 0.75)
>
> axis(side = 1, at = seq(-20, 10, 5), cex.axis = 1)
> axis(side = 2, at = seq(-15, 10, 5), las = 2, cex.axis = 1)
>
> mtext("PC1", 1, line = 3, cex = 1)
> mtext("PC2", 2, line = 3, cex = 1)
>
> legend(-20, 10, pch = 16, col = c("#5B84B1FF", "#FC766AFF"),
> legend = c("B", "M"))
3) 결과 비교
앞선 두 결과와 실제값을 비교한 그림은 다음과 같습니다. 원본 데이터를 바탕으로 군집 분석을 수행한 것(1)과 비교하여, PCA를 적용한 데이터의 군집 분석 결과(2)가 실제값(3)과 더 유사한 것을 확인할 수 있습니다.
하지만 시각적으로 확인하는 것은 주관적인 판단이 개입될 수 있기 때문에, 혼동행렬 (Confusion Matrix)을 통해 객관적인 정확도를 검증하였습니다.
> bcw_raw$diagnosis_n <- ifelse(bcw_raw$diagnosis == "M", 1, 2)
> confusionMatrix(factor(bcw_raw$kmeans_raw2), factor(bcw_raw$diagnosis_n))
Confusion Matrix and Statistics
Reference
Prediction 1 2
1 130 1
2 82 356
Accuracy : 0.8541
95% CI : (0.8224, 0.8821)
No Information Rate : 0.6274
P-Value [Acc > NIR] : < 2.2e-16
...
> confusionMatrix(factor(bcw_raw$kmeans_pca2), factor(bcw_raw$diagnosis_n))
Confusion Matrix and Statistics
Reference
Prediction 1 2
1 176 18
2 36 339
Accuracy : 0.9051
95% CI : (0.878, 0.9279)
No Information Rate : 0.6274
P-Value [Acc > NIR] : <2e-16
...
1) 원본 데이터를 바탕으로 진행된 군집 분석의 정확도는 약 85.4%이고, 2) PCA 적용 데이터를 바탕으로 진행된 군집 분석의 정확도는 약 90.5%로, PCA를 적용했을 때의 데이터가 더 높은 정확도를 보여주는 것을 확인할 수 있었습니다. 이러한 분석 결과를 통해 변수가 많고 변수 간 상관관계 높은 데이터에 대해서는 PCA와 같은 차원 축소 기법을 적용하는 것이 더 적합하다는 것을 확인할 수 있었습니다.
ML/DL 분야에서는 Auto-encoder와 같이 최신 기법들이 차원 축소에 활용되고 있는 추세이기는 하지만, PCA는 여전히 일반적인 통계 분석에서 많이 활용되고 있을 뿐 아니라, 통계 분석의 기본적인 방법이었기 때문에 과거의 과제를 바탕으로 전반적인 분석 과정을 살펴봤습니다. 분석 과정에서 틀린 부분이나 개선될 부분이 있다면, 댓글로 알려주시길 바랍니다.
<참고>
https://dslyh01.tistory.com/17
[Dimensionality Reduction] 주성분 분석 (PCA, Principal Components Analysis) - 1
본 글에서는 차원 축소 (Dimensionality Reduction) 기법 중, 가장 널리 사용되었던 주성분 분석 (PCA)에 대해 살펴보고자 합니다. PCA의 개념 및 이론에 대해 자세히 살펴보지는 않고, 예제 데이터를 바탕
dslyh01.tistory.com
'Data Analysis > Dimensionality Reduction' 카테고리의 다른 글
[Dimensionality Reduction] 주성분 분석 (PCA, Principal Components Analysis) - 1 (2) | 2022.10.27 |
---|
댓글