K-NN이란?
K-NN은 분류에 사용되는 알고리즘의 종류 중 하나입니다. K-NN은 유사도를 기준으로 하여 '가장 가까운 K개의 레코드'를 찾는 방식으로 분류를 수행합니다.
예시로 다음과 같은 데이터가 있다고 해보겠습니다.
데이터 | X축 | Y축 |
A | 1 | 4 |
B | 3 | 5 |
C | 2 | 3 |
D | 5 | 1 |
E | 6 | 2 |
F | 5 | 4 |
? | 4 | 4 |
?의 클래스를 판별하기 위해서 거리를 측정하도록 하겠습니다. 최근접 이웃을 찾기 위해서는 거리 함수 또는 두 인스턴스 간의 유사도를 측정해야 합니다. 일반적으로 K-NN 알고리즘에서는 유클리드 거리를 사용합니다.
▷ 유클리드 거리의 공식은 예를들어 p와 q의 거리를 비교한다고 했을때
다음과 같이 계산이 됩니다. 그럼 위의 데이터를 거리를 측정해 보도록 하겠습니다.
데이터 | X축 | Y축 | 거리 계산 |
A | 1 | 4 | 3 |
B | 3 | 5 | √2 |
C | 2 | 3 | √3 |
D | 5 | 1 | √10 |
E | 6 | 2 | √8 |
F | 5 | 4 | √1 |
? | 4 | 4 |
거리 계산을 하면 다음과 같습니다. 계산 결과 ?는 F와 가장 가까운것으로 나타났습니다.
위의 표를 그래프로 표현하면 다음과 같습니다. 예를들어 여기서 K=1 이라고 한다면 ?는 가장 첫번째로 가까운 거리인 F의 모양이 세모이므로 세모로 분류를 하게 되는 것입니다.
만약 K=3이라고 한다면 네모(B,C), 세모(F)로 다수결에 의해서 ?는 네모로 분류하게 됩니다.
적절한 K
K값을 적절하게 선택하는 것이 모델의 성능을 좌우하게 됩니다.
K값을 너무 작게 설정하면 모델이 과적합될 가능성이 크게 됩니다.
K값을 너무 크게 설정하면 데이터의 구조를 파악하기 어려워 집니다. (편향될 가능성이 크다요.)
K값은 보통 데이터의 제곱근을 취한 값으로 시작을 한다고 합니다. 예를 들어 학습 데이터가 15개라고 한다면? 제곱근은 약 3.87로 여기서 K=4로 시작을 하는 것입니다.
K-NN 장 단점
장점
- 단순하며 효율적이다.
- 기저 데이터 분포에 대한 가정을 하지 않습니다.
- 훈련 단계가 빠릅니다.
단점
- 적절한 K의 선택이 필요합니다.
- 분류 단계가 느립니다.
- 모델을 생성하지 않아서 특징과 클래스 간의 관계를 이해하는 능력이 필요합니다.
K-NN 실습
1. 데이터 준비및 전처리
데이터는 UCI에서 제공하는 유방암 관련 데이터를 사용하겠습니다. 먼저 데이터를 로딩해보겠습니다.
wbcd<-read.csv("C:\\Users\\User\\Desktop\\머신러닝\\wisc_bc_data.csv")
head(wbcd)
id diagnosis radius_mean texture_mean perimeter_mean area_mean smoothness_mean compactness_mean concavity_mean
1 87139402 B 12.32 12.39 78.85 464.1 0.10280 0.06981 0.03987
2 8910251 B 10.60 18.95 69.28 346.4 0.09688 0.11470 0.06387
3 905520 B 11.04 16.83 70.92 373.2 0.10770 0.07804 0.03046
4 868871 B 11.28 13.39 73.00 384.8 0.11640 0.11360 0.04635
5 9012568 B 15.19 13.21 97.65 711.8 0.07963 0.06934 0.03393
6 906539 B 11.57 19.04 74.20 409.7 0.08546 0.07722 0.05485
points_mean symmetry_mean dimension_mean radius_se texture_se perimeter_se area_se smoothness_se compactness_se
1 0.03700 0.1959 0.05955 0.2360 0.6656 1.670 17.43 0.008045 0.011800
2 0.02642 0.1922 0.06491 0.4505 1.1970 3.430 27.10 0.007470 0.035810
3 0.02480 0.1714 0.06340 0.1967 1.3870 1.342 13.54 0.005158 0.009355
4 0.04796 0.1771 0.06072 0.3384 1.3430 1.851 26.33 0.011270 0.034980
5 0.02657 0.1721 0.05544 0.1783 0.4125 1.338 17.72 0.005012 0.014850
6 0.01428 0.2031 0.06267 0.2864 1.4400 2.206 20.30 0.007278 0.020470
concavity_se points_se symmetry_se dimension_se radius_worst texture_worst perimeter_worst area_worst smoothness_worst
1 0.01683 0.012410 0.01924 0.002248 13.50 15.64 86.97 549.1 0.1385
2 0.03354 0.013650 0.03504 0.003318 11.88 22.94 78.28 424.8 0.1213
3 0.01056 0.007483 0.01718 0.002198 12.41 26.44 79.93 471.4 0.1369
4 0.02187 0.019650 0.01580 0.003442 11.92 15.77 76.53 434.0 0.1367
5 0.01551 0.009155 0.01647 0.001767 16.20 15.73 104.50 819.1 0.1126
6 0.04447 0.008799 0.01868 0.003339 13.07 26.98 86.43 520.5 0.1249
compactness_worst concavity_worst points_worst symmetry_worst dimension_worst
1 0.1266 0.12420 0.09391 0.2827 0.06771
2 0.2515 0.19160 0.07926 0.2940 0.07587
3 0.1482 0.10670 0.07431 0.2998 0.07881
4 0.1822 0.08669 0.08611 0.2102 0.06784
5 0.1737 0.13620 0.08178 0.2487 0.06766
6 0.1937 0.25600 0.06664 0.3035 0.08284
str(wbcd)
'data.frame': 569 obs. of 32 variables:
$ id : int 87139402 8910251 905520 868871 9012568 906539 925291 87880 862989 89827 ...
$ diagnosis : Factor w/ 2 levels "B","M": 1 1 1 1 1 1 1 2 1 1 ...
$ radius_mean : num 12.3 10.6 11 11.3 15.2 ...
$ texture_mean : num 12.4 18.9 16.8 13.4 13.2 ...
$ perimeter_mean : num 78.8 69.3 70.9 73 97.7 ...
$ area_mean : num 464 346 373 385 712 ...
$ smoothness_mean : num 0.1028 0.0969 0.1077 0.1164 0.0796 ...
$ compactness_mean : num 0.0698 0.1147 0.078 0.1136 0.0693 ...
$ concavity_mean : num 0.0399 0.0639 0.0305 0.0464 0.0339 ...
$ points_mean : num 0.037 0.0264 0.0248 0.048 0.0266 ...
$ symmetry_mean : num 0.196 0.192 0.171 0.177 0.172 ...
$ dimension_mean : num 0.0595 0.0649 0.0634 0.0607 0.0554 ...
$ radius_se : num 0.236 0.451 0.197 0.338 0.178 ...
$ texture_se : num 0.666 1.197 1.387 1.343 0.412 ...
$ perimeter_se : num 1.67 3.43 1.34 1.85 1.34 ...
$ area_se : num 17.4 27.1 13.5 26.3 17.7 ...
$ smoothness_se : num 0.00805 0.00747 0.00516 0.01127 0.00501 ...
$ compactness_se : num 0.0118 0.03581 0.00936 0.03498 0.01485 ...
$ concavity_se : num 0.0168 0.0335 0.0106 0.0219 0.0155 ...
$ points_se : num 0.01241 0.01365 0.00748 0.01965 0.00915 ...
$ symmetry_se : num 0.0192 0.035 0.0172 0.0158 0.0165 ...
$ dimension_se : num 0.00225 0.00332 0.0022 0.00344 0.00177 ...
$ radius_worst : num 13.5 11.9 12.4 11.9 16.2 ...
$ texture_worst : num 15.6 22.9 26.4 15.8 15.7 ...
$ perimeter_worst : num 87 78.3 79.9 76.5 104.5 ...
$ area_worst : num 549 425 471 434 819 ...
$ smoothness_worst : num 0.139 0.121 0.137 0.137 0.113 ...
$ compactness_worst: num 0.127 0.252 0.148 0.182 0.174 ...
$ concavity_worst : num 0.1242 0.1916 0.1067 0.0867 0.1362 ...
$ points_worst : num 0.0939 0.0793 0.0743 0.0861 0.0818 ...
$ symmetry_worst : num 0.283 0.294 0.3 0.21 0.249 ...
$ dimension_worst : num 0.0677 0.0759 0.0788 0.0678 0.0677 ...
데이터를 살펴봤을때 총 569명의 환자의 데이터가 있고 다양한 변수들이 존재합니다.
wbcd<-wbcd[-1]
id는 환자를 식별하기 위한 데이터로 예측을 할때는 필요하지 않기 때문에 따로 제거하도록 하겠습니다.
table(wbcd$diagnosis)
B M
357 212
예측을 할 결과변수는 diagnosis변수로 B(양성)는 357개, M(음성)은 212개로 나타났습니다. 좀 더 알아보기 쉽게 표현하기 위하여 이름을 살짝 변경해보도록 하겠습니다.
wbcd$diagnosis <- factor(wbcd$diagnosis, levels = c("B", "M"),
labels = c("Benign", "Malignant"))
table(wbcd$diagnosis)
Benign Malignant
357 212
다음은 양성과 음성을 비율로 표현해보도록 하겠습니다. 이때 쓰이는 함수는 prop.table 입니다.
round(prop.table(table(wbcd$diagnosis)) * 100, digits = 1)
Benign Malignant
62.7 37.3
결과값을 보면 각각 62.7%와 3.7.3%로 나왔습니다.
이제 피처들에 대해서 자세히 알아보도록 할텐데("radius_mean", "area_mean", "smoothness_mean") 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
여기서 보면 area_mean과 smoothness_mean를 비교 해봤을때 단위의 차이가 심한것을 알 수 있습니다. 이 상태로 예측을 진행하게 되면 거리 계산을 할때 한쪽으로 취우치는 현상이 발생합니다. 여기서 바로 데이터들을 정규화 해주는 작업이 필요합니다.
normalize <- function(x) {
return ((x - min(x)) / (max(x) - min(x)))
}
정규화 식은 다음과 같습니다.
다음으로 데이터는 모두 동일한 길이의 백터들의 리스트로 lapply()를 사용해야 하는데 여기서 결과값이 리스트로 반환이 되기 때문에 as.darta.frame()을 사용해서 데이터프레임으로 변환을 해주어야 합니다.
wbcd_n <- as.data.frame(lapply(wbcd[2:31], normalize))
summary(wbcd_n)
radius_mean texture_mean perimeter_mean area_mean smoothness_mean compactness_mean concavity_mean
Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.00000
1st Qu.:0.2233 1st Qu.:0.2185 1st Qu.:0.2168 1st Qu.:0.1174 1st Qu.:0.3046 1st Qu.:0.1397 1st Qu.:0.06926
Median :0.3024 Median :0.3088 Median :0.2933 Median :0.1729 Median :0.3904 Median :0.2247 Median :0.14419
Mean :0.3382 Mean :0.3240 Mean :0.3329 Mean :0.2169 Mean :0.3948 Mean :0.2606 Mean :0.20806
3rd Qu.:0.4164 3rd Qu.:0.4089 3rd Qu.:0.4168 3rd Qu.:0.2711 3rd Qu.:0.4755 3rd Qu.:0.3405 3rd Qu.:0.30623
Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.00000
points_mean symmetry_mean dimension_mean radius_se texture_se perimeter_se area_se
Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000 Min. :0.00000 Min. :0.00000
1st Qu.:0.1009 1st Qu.:0.2823 1st Qu.:0.1630 1st Qu.:0.04378 1st Qu.:0.1047 1st Qu.:0.04000 1st Qu.:0.02064
Median :0.1665 Median :0.3697 Median :0.2439 Median :0.07702 Median :0.1653 Median :0.07209 Median :0.03311
Mean :0.2431 Mean :0.3796 Mean :0.2704 Mean :0.10635 Mean :0.1893 Mean :0.09938 Mean :0.06264
3rd Qu.:0.3678 3rd Qu.:0.4530 3rd Qu.:0.3404 3rd Qu.:0.13304 3rd Qu.:0.2462 3rd Qu.:0.12251 3rd Qu.:0.07170
Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000 Max. :1.00000 Max. :1.00000
smoothness_se compactness_se concavity_se points_se symmetry_se dimension_se radius_worst
Min. :0.0000 Min. :0.00000 Min. :0.00000 Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000
1st Qu.:0.1175 1st Qu.:0.08132 1st Qu.:0.03811 1st Qu.:0.1447 1st Qu.:0.1024 1st Qu.:0.04675 1st Qu.:0.1807
Median :0.1586 Median :0.13667 Median :0.06538 Median :0.2070 Median :0.1526 Median :0.07919 Median :0.2504
Mean :0.1811 Mean :0.17444 Mean :0.08054 Mean :0.2235 Mean :0.1781 Mean :0.10019 Mean :0.2967
3rd Qu.:0.2187 3rd Qu.:0.22680 3rd Qu.:0.10619 3rd Qu.:0.2787 3rd Qu.:0.2195 3rd Qu.:0.12656 3rd Qu.:0.3863
Max. :1.0000 Max. :1.00000 Max. :1.00000 Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000
texture_worst perimeter_worst area_worst smoothness_worst compactness_worst concavity_worst points_worst
Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000
1st Qu.:0.2415 1st Qu.:0.1678 1st Qu.:0.08113 1st Qu.:0.3000 1st Qu.:0.1163 1st Qu.:0.09145 1st Qu.:0.2231
Median :0.3569 Median :0.2353 Median :0.12321 Median :0.3971 Median :0.1791 Median :0.18107 Median :0.3434
Mean :0.3640 Mean :0.2831 Mean :0.17091 Mean :0.4041 Mean :0.2202 Mean :0.21740 Mean :0.3938
3rd Qu.:0.4717 3rd Qu.:0.3735 3rd Qu.:0.22090 3rd Qu.:0.4942 3rd Qu.:0.3025 3rd Qu.:0.30583 3rd Qu.:0.5546
Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000
symmetry_worst dimension_worst
Min. :0.0000 Min. :0.0000
1st Qu.:0.1851 1st Qu.:0.1077
Median :0.2478 Median :0.1640
Mean :0.2633 Mean :0.1896
3rd Qu.:0.3182 3rd Qu.:0.2429
Max. :1.0000 Max. :1.0000
출력된 결과를 보면 모두 0~1사이로 정규화가 적용이 된것을 확인하였습니다.
2. 학습&테스트 데이터 생성
이제 모델을 적용하기 전에 데이터를 학습 데이터와 테스트 데이터로 분류를 해야합니다. 여기서는 학습 데이터를 469개, 그리고 테스트 데이터를 100개 사용하도록 하겠습니다.
wbcd_train <- wbcd_n[1:469, ]
wbcd_test <- wbcd_n[470:569, ]
다음으로 레이블을 따로 저장해주도록 하겠습니다.
wbcd_train_labels <- wbcd[1:469, 1]
wbcd_test_labels <- wbcd[470:569, 1]
3. 모델 학습 시키기
이제 모델을 학습시키기 위한 준비가 완료되었습니다. R에서는 class 패키지를 사용해서 K-NN을 구현할 수 있습니다.
install.packages("class")
library(class)
knn() 함수의 사용
p <- knn(train, test, class, k)
train: 훈련 데이터
test: 테스트 데이터
class: 훈련 데이터의 각 행에 대해 클래스를 갖는 팩터 백터
k: 최근접 이웃의 개수를 지정
여기서는 469개의 대략 제곱근인 K=21로 설정을 해주겠다. 이번 예제처럼 데이터의 분류가 바이너리한 경우 동적 표로 끝날 경우를 대비하여 홀수로 설정하는것이 좋습니다.
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
cl = wbcd_train_labels, k = 21)
4. 모델 성능 평가
위 과정을 통해서 모델을 학습시키고 최종적으로 wbcd_test_pred라는 값을 얻게 되었습니다. 이젠 이 예측된 클래스가 얼마나 예측이 잘 되었는지 평가를 해야 합니다. 이때 사용되는 gmodels 패키지의 CrossTable() 함수입니다.
CrossTable(x = wbcd_test_pred, y = wbcd_test_labels,
prop.chisq = FALSE, dnn = c('predicted', 'actual'))
Cell Contents
|-------------------------|
| N |
| N / Row Total |
| N / Col Total |
| N / Table Total |
|-------------------------|
Total Observations in Table: 100
| actual
predicted | Benign | Malignant | Row Total |
-------------|-----------|-----------|-----------|
Benign | 61 | 2 | 63 |
| 0.968 | 0.032 | 0.630 |
| 1.000 | 0.051 | |
| 0.610 | 0.020 | |
-------------|-----------|-----------|-----------|
Malignant | 0 | 37 | 37 |
| 0.000 | 1.000 | 0.370 |
| 0.000 | 0.949 | |
| 0.000 | 0.370 | |
-------------|-----------|-----------|-----------|
Column Total | 61 | 39 | 100 |
| 0.610 | 0.390 | |
-------------|-----------|-----------|-----------|
결과를 해석하기 전에 왼쪽 위에서보다 오른쪽 시계 방향으로 TP(True Positive), FP(False Positive), TN(True Negative), FN(False Negative) 라고 부른다. 표를 해석하면 최종적으로 100개의 클래스 중에서 2개가 잘못 분류되었다.
5. 모델 성능 높이기
KNN 알고리즘에서는 보통 정규화가 많이 사용이 되지만 항상 최적의 방법이 되는 것은 아닙니다. 왜냐하면 데이터를 0~1사이로 정하기 때문에 최솟값과 최댓값이 정해져 극단값이 중심으로 향하기 때문입니다. 이를 대안하기 위해서는 z-점수 표준화 방법이 있습니다. R에서는 scale() 함수를 써서 표준화를 시킬수 있습니다.
wbcd_z <- as.data.frame(scale(wbcd[-1]))
summary(wbcd_z)
radius_mean texture_mean perimeter_mean area_mean smoothness_mean compactness_mean
Min. :-2.0279 Min. :-2.2273 Min. :-1.9828 Min. :-1.4532 Min. :-3.10935 Min. :-1.6087
1st Qu.:-0.6888 1st Qu.:-0.7253 1st Qu.:-0.6913 1st Qu.:-0.6666 1st Qu.:-0.71034 1st Qu.:-0.7464
Median :-0.2149 Median :-0.1045 Median :-0.2358 Median :-0.2949 Median :-0.03486 Median :-0.2217
Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.00000 Mean : 0.0000
3rd Qu.: 0.4690 3rd Qu.: 0.5837 3rd Qu.: 0.4992 3rd Qu.: 0.3632 3rd Qu.: 0.63564 3rd Qu.: 0.4934
Max. : 3.9678 Max. : 4.6478 Max. : 3.9726 Max. : 5.2459 Max. : 4.76672 Max. : 4.5644
concavity_mean points_mean symmetry_mean dimension_mean radius_se texture_se
Min. :-1.1139 Min. :-1.2607 Min. :-2.74171 Min. :-1.8183 Min. :-1.0590 Min. :-1.5529
1st Qu.:-0.7431 1st Qu.:-0.7373 1st Qu.:-0.70262 1st Qu.:-0.7220 1st Qu.:-0.6230 1st Qu.:-0.6942
Median :-0.3419 Median :-0.3974 Median :-0.07156 Median :-0.1781 Median :-0.2920 Median :-0.1973
Mean : 0.0000 Mean : 0.0000 Mean : 0.00000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
3rd Qu.: 0.5256 3rd Qu.: 0.6464 3rd Qu.: 0.53031 3rd Qu.: 0.4706 3rd Qu.: 0.2659 3rd Qu.: 0.4661
Max. : 4.2399 Max. : 3.9245 Max. : 4.48081 Max. : 4.9066 Max. : 8.8991 Max. : 6.6494
perimeter_se area_se smoothness_se compactness_se concavity_se points_se
Min. :-1.0431 Min. :-0.7372 Min. :-1.7745 Min. :-1.2970 Min. :-1.0566 Min. :-1.9118
1st Qu.:-0.6232 1st Qu.:-0.4943 1st Qu.:-0.6235 1st Qu.:-0.6923 1st Qu.:-0.5567 1st Qu.:-0.6739
Median :-0.2864 Median :-0.3475 Median :-0.2201 Median :-0.2808 Median :-0.1989 Median :-0.1404
Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
3rd Qu.: 0.2428 3rd Qu.: 0.1067 3rd Qu.: 0.3680 3rd Qu.: 0.3893 3rd Qu.: 0.3365 3rd Qu.: 0.4722
Max. : 9.4537 Max. :11.0321 Max. : 8.0229 Max. : 6.1381 Max. :12.0621 Max. : 6.6438
symmetry_se dimension_se radius_worst texture_worst perimeter_worst area_worst
Min. :-1.5315 Min. :-1.0960 Min. :-1.7254 Min. :-2.22204 Min. :-1.6919 Min. :-1.2213
1st Qu.:-0.6511 1st Qu.:-0.5846 1st Qu.:-0.6743 1st Qu.:-0.74797 1st Qu.:-0.6890 1st Qu.:-0.6416
Median :-0.2192 Median :-0.2297 Median :-0.2688 Median :-0.04348 Median :-0.2857 Median :-0.3409
Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.00000 Mean : 0.0000 Mean : 0.0000
3rd Qu.: 0.3554 3rd Qu.: 0.2884 3rd Qu.: 0.5216 3rd Qu.: 0.65776 3rd Qu.: 0.5398 3rd Qu.: 0.3573
Max. : 7.0657 Max. : 9.8429 Max. : 4.0906 Max. : 3.88249 Max. : 4.2836 Max. : 5.9250
smoothness_worst compactness_worst concavity_worst points_worst symmetry_worst dimension_worst
Min. :-2.6803 Min. :-1.4426 Min. :-1.3047 Min. :-1.7435 Min. :-2.1591 Min. :-1.6004
1st Qu.:-0.6906 1st Qu.:-0.6805 1st Qu.:-0.7558 1st Qu.:-0.7557 1st Qu.:-0.6413 1st Qu.:-0.6913
Median :-0.0468 Median :-0.2693 Median :-0.2180 Median :-0.2233 Median :-0.1273 Median :-0.2163
Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
3rd Qu.: 0.5970 3rd Qu.: 0.5392 3rd Qu.: 0.5307 3rd Qu.: 0.7119 3rd Qu.: 0.4497 3rd Qu.: 0.4504
Max. : 3.9519 Max. : 5.1084 Max. : 4.6965 Max. : 2.6835 Max. : 6.0407 Max. : 6.8408
z-점수 표준화는 결과값처럼 평균을 항상 0으로 되게하고 범위는 상당히 작게 변환시켜 줍니다.
이제 위에서 했던 예제를 반복해서 학습을 시키고 평가도 해보겠습니다.
wbcd_train <- wbcd_z[1:469, ]
wbcd_test <- wbcd_z[470:569, ]
wbcd_train_labels <- wbcd[1:469, 1]
wbcd_test_labels <- wbcd[470:569, 1]
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
cl = wbcd_train_labels, k = 21)
CrossTable(x = wbcd_test_pred, y = wbcd_test_labels,
prop.chisq = FALSE, dnn = c('predicted', 'actual'))
Cell Contents
|-------------------------|
| N |
| N / Row Total |
| N / Col Total |
| N / Table Total |
|-------------------------|
Total Observations in Table: 100
| actual
predicted | Benign | Malignant | Row Total |
-------------|-----------|-----------|-----------|
Benign | 61 | 5 | 66 |
| 0.924 | 0.076 | 0.660 |
| 1.000 | 0.128 | |
| 0.610 | 0.050 | |
-------------|-----------|-----------|-----------|
Malignant | 0 | 34 | 34 |
| 0.000 | 1.000 | 0.340 |
| 0.000 | 0.872 | |
| 0.000 | 0.340 | |
-------------|-----------|-----------|-----------|
Column Total | 61 | 39 | 100 |
| 0.610 | 0.390 | |
-------------|-----------|-----------|-----------|
결과를 봤을때 앞의 예제보다 더 낮은 성능이 나왔습니다.
이번에는 K값을 조정하면서 성능을 비교해보도록 하겠습니다.
# k = 1
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
cl = wbcd_train_labels, k = 1)
| actual
predicted | Benign | Malignant | Row Total |
-------------|-----------|-----------|-----------|
Benign | 59 | 3 | 62 |
| 0.952 | 0.048 | 0.620 |
| 0.967 | 0.077 | |
| 0.590 | 0.030 | |
-------------|-----------|-----------|-----------|
Malignant | 2 | 36 | 38 |
| 0.053 | 0.947 | 0.380 |
| 0.033 | 0.923 | |
| 0.020 | 0.360 | |
-------------|-----------|-----------|-----------|
Column Total | 61 | 39 | 100 |
| 0.610 | 0.390 | |
-------------|-----------|-----------|-----------|
# k = 5
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
cl = wbcd_train_labels, k = 5)
| actual
predicted | Benign | Malignant | Row Total |
-------------|-----------|-----------|-----------|
Benign | 60 | 2 | 62 |
| 0.968 | 0.032 | 0.620 |
| 0.984 | 0.051 | |
| 0.600 | 0.020 | |
-------------|-----------|-----------|-----------|
Malignant | 1 | 37 | 38 |
| 0.026 | 0.974 | 0.380 |
| 0.016 | 0.949 | |
| 0.010 | 0.370 | |
-------------|-----------|-----------|-----------|
Column Total | 61 | 39 | 100 |
| 0.610 | 0.390 | |
-------------|-----------|-----------|-----------|
# k = 11
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
cl = wbcd_train_labels, k = 11)
| actual
predicted | Benign | Malignant | Row Total |
-------------|-----------|-----------|-----------|
Benign | 60 | 3 | 63 |
| 0.952 | 0.048 | 0.630 |
| 0.984 | 0.077 | |
| 0.600 | 0.030 | |
-------------|-----------|-----------|-----------|
Malignant | 1 | 36 | 37 |
| 0.027 | 0.973 | 0.370 |
| 0.016 | 0.923 | |
| 0.010 | 0.360 | |
-------------|-----------|-----------|-----------|
Column Total | 61 | 39 | 100 |
| 0.610 | 0.390 | |
-------------|-----------|-----------|-----------|
# k = 15
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
cl = wbcd_train_labels, k = 15)
# k = 21
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
cl = wbcd_train_labels, k = 21)
| actual
predicted | Benign | Malignant | Row Total |
-------------|-----------|-----------|-----------|
Benign | 61 | 3 | 64 |
| 0.953 | 0.047 | 0.640 |
| 1.000 | 0.077 | |
| 0.610 | 0.030 | |
-------------|-----------|-----------|-----------|
Malignant | 0 | 36 | 36 |
| 0.000 | 1.000 | 0.360 |
| 0.000 | 0.923 | |
| 0.000 | 0.360 | |
-------------|-----------|-----------|-----------|
Column Total | 61 | 39 | 100 |
| 0.610 | 0.390 | |
-------------|-----------|-----------|-----------|
# k = 27
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
cl = wbcd_train_labels, k = 27)
| actual
predicted | Benign | Malignant | Row Total |
-------------|-----------|-----------|-----------|
Benign | 61 | 5 | 66 |
| 0.924 | 0.076 | 0.660 |
| 1.000 | 0.128 | |
| 0.610 | 0.050 | |
-------------|-----------|-----------|-----------|
Malignant | 0 | 34 | 34 |
| 0.000 | 1.000 | 0.340 |
| 0.000 | 0.872 | |
| 0.000 | 0.340 | |
-------------|-----------|-----------|-----------|
Column Total | 61 | 39 | 100 |
| 0.610 | 0.390 | |
-------------|-----------|-----------|-----------|
k값에 따라서 거짓 부정, 거짓 긍정등이 달라지게 되는것을 알 수 있습니다.
'Machine Learning' 카테고리의 다른 글
ML 평가 지표 (0) | 2020.05.09 |
---|---|
의사결정 나무 실습 (0) | 2020.05.07 |
분류 실습(신용카드 사기 데이터) (0) | 2020.05.03 |
LightGBM (3) | 2020.04.28 |
XGBoost 실습 - 사이킷런 래퍼 - (0) | 2020.04.27 |