Breast Cancer Wisconsin Diagnostic
K-NN알고리즘으로 유방암 여부 진단
radius (mean of distances from center to points on the perimeter)
texture (standard deviation of gray-scale values)
smoothness (local variation in radius lengths)
compactness (perimeter^2 / area - 1.0)
concavity (severity of concave portions of the contour)
concave points (number of concave portions of the contour)
symmetry
fractal dimension ("coastline approximation" - 1)
Diagnosis (M = malignant, B = benign)
1. 데이터 준비 및 정규화
> wbcd = read.csv("C:/R/wisc_bc_data.csv", header=TRUE)
> wbcd = wbcd[-1] # id 열 삭제
> #str(wbcd)
> attach(wbcd)
> table(diagnosis)
diagnosis
B M
357 212
>
> # factor로 변환
> diagnosis = factor(diagnosis, levels=c("B", "M"),
+ labels=c("Benign", "Malignant"))
>
> # 비율 확인
> round(prop.table(table(diagnosis))*100, digits=1)
diagnosis
Benign Malignant
62.7 37.3
> summary(wbcd[c("radius_mean", "area_mean", "smoothness_mean")])
radius_mean area_mean smoothness_mean
Min. : 6.981 Min. : 143.5 Min. :0.05263
1st Qu.:11.700 1st Qu.: 420.3 1st Qu.:0.08637
Median :13.370 Median : 551.1 Median :0.09587
Mean :14.127 Mean : 654.9 Mean :0.09636
3rd Qu.:15.780 3rd Qu.: 782.7 3rd Qu.:0.10530
Max. :28.110 Max. :2501.0 Max. :0.16340
- diagnosis 변수를 가변수로 만들어주었다.
- Benign과 Malignant의 비율은 62.6%, 37.3%이다.
K-NN의 거리 계산은 측정 범위에 크게 의존한다.
'radius_mean', 'area_mean', 'smoothness_mean'의 범위를 봤을 때 큰 차이가 나기 때문에 정규화를 해주어야 한다.
데이터 정규화 함수 normalize를 생성하여 적용해주었다.
> # 데이터 정규화
> normalize = function(x) {return ((x-min(x))/(max(x)-min(x)))}
> wbcd_n = as.data.frame(lapply(wbcd[2:31], normalize))
>
> summary(wbcd_n$radius_mean)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.2233 0.3024 0.3382 0.4164 1.0000
> summary(wbcd_n$area_mean)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.1174 0.1729 0.2169 0.2711 1.0000
> summary(wbcd_n$smoothness_mean)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.3046 0.3904 0.3948 0.4755 1.0000
- 위의 summary와 비교하면 0~1 사이로 잘 변환된 것을 알 수 있다.
다음으로, 훈련 데이터와 테스트 데이터를 9:1의 비율로 생성하였다.
> # 훈련, 테스트 데이터 생성
> 569*0.9 #512
> wbcd_train = wbcd_n[1:512,]
> wbcd_test = wbcd_n[513:569,]
> wbcd_train_labels = wbcd[1:512, 1] # 팩터
> wbcd_test_labels = wbcd[513:569, 1]
2. 모델 훈련
class 패키지의 knn() 함수를 사용하여 모델을 훈련한 후 성능을 평가했다.
> # 모델 훈련
> # install.packages("class")
> library(class)
> wbcd_test_pred = knn(train=wbcd_train, test=wbcd_test,
+ cl=wbcd_train_labels, k=23)
>
>
> # 모델 성능 평가
> # install.packages("gmodels")
> library(gmodels)
> CrossTable(x=wbcd_test_labels, wbcd_test_pred,
+ prop.chisq=F, prop.c=F, prop.r=F,
+ dnn = c('actual default', 'predicted default'))
(43+13)/57*100 # 98.24561
- k의 개수는 약 sqrt(512)인 23으로 지정하였다.
- 모델의 정확도는 약 98%로 높은 성능을 보인다.
3. 모델 성능 높이기
① k에 다른 값을 적용하여 분류해보기
# k=1
wbcd_test_pred = knn(train=wbcd_train, test=wbcd_test,
cl=wbcd_train_labels, k=1)
CrossTable(x=wbcd_test_labels, wbcd_test_pred,
prop.chisq=F, prop.c=F, prop.r=F,
dnn = c('actual default', 'predicted default'))
(40+13)/57*100 # 정확도 92.98%
# k=5
wbcd_test_pred = knn(train=wbcd_train, test=wbcd_test,
cl=wbcd_train_labels, k=5)
CrossTable(x=wbcd_test_labels, wbcd_test_pred,
prop.chisq=F, prop.c=F, prop.r=F,
dnn = c('actual default', 'predicted default'))
(42+13)/57*100 # 정확도 96.5%
# k=10
wbcd_test_pred = knn(train=wbcd_train, test=wbcd_test,
cl=wbcd_train_labels, k=10)
CrossTable(x=wbcd_test_labels, wbcd_test_pred,
prop.chisq=F, prop.c=F, prop.r=F,
dnn = c('actual default', 'predicted default'))
(41+14)/57*100 # 정확도 96.5%
# k=30
wbcd_test_pred = knn(train=wbcd_train, test=wbcd_test,
cl=wbcd_train_labels, k=30)
CrossTable(x=wbcd_test_labels, wbcd_test_pred,
prop.chisq=F, prop.c=F, prop.r=F,
dnn = c('actual default', 'predicted default'))
(43+13)/57*100 # 정확도 98.25%
② 정규화 대신 z-점수 표준화 사용
# z-점수 표준화
> wbcd_z = as.data.frame(scale(wbcd[-1]))
> summary(wbcd_z$radius_mean)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.0279 -0.6888 -0.2149 0.0000 0.4690 3.9678
> summary(wbcd_z$area_mean)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-1.4532 -0.6666 -0.2949 0.0000 0.3632 5.2459
> summary(wbcd_z$smoothness_mean)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-3.10935 -0.71034 -0.03486 0.00000 0.63564 4.76672
> wbcd_train = wbcd_z[1:512, ]
> wbcd_test = wbcd_z[513:569, ]
> wbcd_train_labels = wbcd[1:512, 1]
> wbcd_test_labels = wbcd[513:569, 1]
>
> wbcd_test_pred = knn(train = wbcd_train, test = wbcd_test,
+ cl = wbcd_train_labels, k=23)
> CrossTable(x = wbcd_test_labels, y = wbcd_test_pred,
+ prop.chisq=F, prop.c=F, prop.r=F,
+ dnn = c('actual default', 'predicted default'))
(43+13)/57*100 # 정확도 98.25%
기존 모델의 정확도가 높았기 때문에 이 두 가지의 방법으로 모델의 성능이 개선되진 않았지만,
다른 케이스에 적용해보면 모델의 성능이 개선되는 것을 확인할 수 있을 것 같다!
'R > ML & DL 공부' 카테고리의 다른 글
[R] 와인 등급 예측 - 회귀트리, 모델트리 (0) | 2022.04.22 |
---|---|
[R] 의료비 예측 - 선형 회귀 (0) | 2022.04.22 |
[R] 휴대폰 스팸 분류 - Naive bayes (0) | 2022.04.20 |
[R] 독버섯 분류 - 분류 규칙 (OneR, Ripper) (0) | 2022.04.19 |
[R] 은행 대출 채무 여부 분류 - 의사결정트리 (0) | 2022.04.15 |