R에서 KNN 분류 모델에 대한 교차 검증 사용

Jesse John 2023년6월21일
  1. 다양한 교차 검증 접근 방식
  2. K-최근접 이웃 분류 모델에 대한 반복 K-폴드 교차 검증
R에서 KNN 분류 모델에 대한 교차 검증 사용

교차 검증을 통해 교육 데이터 세트만 있어도 새 데이터에 대한 모델의 성능을 평가할 수 있습니다. 회귀 및 분류 모델에 적용할 수 있는 일반적인 기법입니다.

이 기사에서는 KNN(K-Nearest Neighbor) 분류 모델에 대해 k-겹 반복 교차 검증을 수행하는 방법에 대해 설명합니다. 이를 위해 캐럿 패키지를 사용할 것입니다.

KNN의 K는 관측 이웃의 수를 나타냅니다. 반면 k-fold의 k는 훈련 데이터의 하위 집합 수입니다.

다양한 교차 검증 접근 방식

교차 검증에는 다양한 접근 방식이 있습니다.

가장 기본적인 버전은 학습 데이터의 하위 집합 하나를 사용하여 검증 집합 접근 방식이라고 하는 모델의 유효성을 검사합니다. 모델은 한 번만 적합하고 하위 집합에서 테스트됩니다.

다른 하나는 관측치 수만큼 모델을 피팅하고 평균 오류율을 취하는 것입니다. 각 모델에는 하나의 관찰이 생략되어 있습니다. 그런 다음 해당 모델을 해당 관찰에 대해 테스트합니다.

이를 LOOCV(Leave One Out Cross Validation)라고 합니다.

가장 유용한 접근 방식은 다음과 같습니다.

  1. 훈련 데이터 세트를 k 접기(그룹)로 분할,
  2. 모델 k번 피팅,
  3. 접힌 부분을 하나 남기고,
  4. 그것에 대한 모델 테스트.

이를 k-겹 교차 검증이라고 합니다. 일반적으로 5 또는 10의 k 값이 좋은 결과를 제공합니다.

k-겹 교차 검증의 개선 사항에는 다양한 접기 분할로 k-겹 교차 검증 모델을 여러 번 피팅하는 것이 포함됩니다. 이것을 우리가 사용할 반복 k-겹 교차 검증이라고 합니다.

K-최근접 이웃 분류 모델에 대한 반복 K-폴드 교차 검증

이제 반복되는 k-겹 교차 검증을 사용하여 KNN(K-Nearest Neighbor) 분류 모델을 맞추는 방법을 살펴보겠습니다. 우리는 캐럿 패키지를 사용할 것입니다.

캐럿 패키지는 매우 다양하며 여러 유형의 모델을 구축하는 데 사용할 수 있습니다. 자세한 내용은 CRAN 문서를 참조하십시오.

일반적으로 k-겹 교차 검증은 모델이 새 데이터에서 얼마나 정확할 것으로 예상되는지 알려줍니다.

예를 들어, 10 k-폴드를 사용하여 3번 반복되는 반복된 k-폴드 교차 검증을 사용하여 K = 5 KNN 모델을 적합한다고 가정합니다. 이 모델은 3개의 서로 다른 데이터 분할 각각에 대해 10번 적합할 것이며, K = 5 이웃이 있는 하나의 모델에 대해서만 성능 메트릭을 얻을 것입니다.

위의 내용 외에도 캐럿 패키지를 사용하면 다양한 K 값에 대해 KNN 모델을 맞출 수 있습니다. 그런 다음 함수는 최상의 모델을 생성하는 K 값을 보고하고 해당 모델을 생성합니다.

createDataPartition() 함수는 요인 벡터의 계층화된 무작위 분할을 생성합니다. 이를 사용하여 데이터를 교육 및 테스트 하위 집합으로 분리하여 모델의 정확성을 확인합니다.

train() 함수는 모델을 생성하는 main 함수입니다.

  1. x는 예측 변수가 있는 데이터 프레임입니다.
  2. y는 결과 데이터 프레임 또는 벡터입니다.
  3. method 인수는 구축하려는 모델의 유형을 취합니다. knn을 지정합니다.
  4. 전처리에 대해 스케일센터를 지정합니다.
  5. trControl 인수를 사용하면 교차 검증 절차의 세부 사항을 지정할 수 있습니다.
  6. tuneGrid 인수는 여러 모델을 만들고 비교하는 데 도움이 됩니다. 조정할 매개변수 이름이 있는 데이터 프레임이 필요합니다.

우리는 KNN 모델을 구축하고 있기 때문에 tuneGrid에 대한 튜닝 매개변수로 소문자로 k를 제공합니다. 우리는 1에서 12까지의 K 값의 벡터를 제공할 것이며, 함수가 모델을 생성하고 테스트하기를 원합니다.

교차 유효성 검사의 세부 사항은 trainControl() 함수를 사용하여 trControl 인수로 전달됩니다.

  1. method 인수의 경우 반복 교차 검증을 원하기 때문에 repeatedcv를 지정합니다.
  2. methodcv 또는 repeatedcv인 경우 number 인수는 폴드 k를 지정합니다. 우리는 10을 사용할 것입니다.
  3. repeats 인수는 k-폴드 분할이 반복되어야 하는 횟수를 지정합니다.

예제 코드:

# Create the data vectors for the demonstration.
# We will create two numeric vectors as predictors.
# Each vector will have two distinct groups to suit our model.
# We will create a factor with two levels.
# The factor levels correspond to the groups in the predictor vectors.

set.seed(564)
vX1a = round(rnorm(100, 2,2))+4
set.seed(574)
vX2a = round(rnorm(100, 15,4))

set.seed(584)
vX1b = round(rnorm(100, 10,3))+5
set.seed(594)
vX2b = round(rnorm(100, 5,4))

vYa = rep("Blue", 100)
vYb = rep("Red", 100)

vX1 = c(vX1a, vX1b)
vX2 = c(vX2a, vX2b)
vY = c(vYa, vYb)

# Dummy column for ordering rows.
set.seed(528)
R = sample(1:200,200)

# Temporary data frame.
temp_df = data.frame(X1 = vX1, X2 = vX2, Y = as.factor(vY), R)

# Packages that we will use.
library(ggplot2)
library(dplyr)

# See the sample data.
temp_df %>% ggplot(aes(x=X1, y = X2, colour = Y)) + geom_point()

# Re-order the rows, just to see that the KNN model works with the rows jumbled up.
# Final data frame.
# Notice that the outputs are a factor vector.
fin_df = temp_df %>% arrange(R) %>% select(X1, X2, Y)
head(fin_df)
str(fin_df)

# Install the caret package if it is not already installed.
# To install, uncomment the next line and run it.
# install.packages("caret")

# Load the caret package.
library(caret)

# Split the data frame into a training set and test set.
# Create a list of row numbers in the training set.
# This function creates a stratified random sample of all the outcome classes.
set.seed(365)
training_row_index = createDataPartition(fin_df[,3], p=0.75, list=FALSE)

# Create training sets of the predictors and the corresponding outcomes.
trg_data = fin_df[training_row_index,1:2]
trg_class = fin_df[training_row_index,3]

# Create the test set of predictors and the outcomes that we will later use.
tst_data = fin_df[-training_row_index,1:2]
tst_class = fin_df[-training_row_index,3]

# Let us check if the sample is stratified:
table(tst_class)
# Obviously, the training sample will complement these numbers of the totals.

# We will build a K-Nearest neighbors model using repeated k-fold cross-validation.
# The arguments are described in the article.
mod_knn = train(x = trg_data,
                y = trg_class,
                method = "knn",
                preProcess = c("center", "scale"),
                tuneGrid = data.frame(k = c(1:12)),
                trControl = trainControl(method = "repeatedcv",
                                         number = 10,
                                         repeats = 3)
                )

# View the fitted model.
mod_knn

출력:

> head(fin_df)
  X1 X2    Y
1 15  6  Red
2 15  2  Red
3 14  3  Red
4  4 22 Blue
5 20 -3  Red
6  4 22 Blue

> str(fin_df)
'data.frame':	200 obs. of  3 variables:
 $ X1: num  15 15 14 4 20 4 15 2 20 13 ...
 $ X2: num  6 2 3 22 -3 22 7 16 9 -6 ...
 $ Y : Factor w/ 2 levels "Blue","Red": 2 2 2 1 2 1 2 1 2 2 ...

> # Let us check if the sample is really stratified:
> table(tst_class)
tst_class
Blue  Red
  25   25

> # View the fitted model.
> mod_knn
k-Nearest Neighbors

150 samples
  2 predictor
  2 classes: 'Blue', 'Red'

Pre-processing: centered (2), scaled (2)
Resampling: Cross-Validated (10 fold, repeated 3 times)
Summary of sample sizes: 135, 136, 135, 135, 135, 134, ...
Resampling results across tuning parameters:

  k   Accuracy   Kappa
   1  0.9710317  0.9420024
   2  0.9736905  0.9473602
   3  0.9753373  0.9505141
   4  0.9842460  0.9683719
   5  0.9864683  0.9728764
   6  0.9843849  0.9687098
   7  0.9843849  0.9687098
   8  0.9800794  0.9600386
   9  0.9800794  0.9600386
  10  0.9800794  0.9600386
  11  0.9800794  0.9600386
  12  0.9800794  0.9600386

Accuracy was used to select the optimal model using the largest value.
The final value used for the model was k = 5.

최상의 모델은 K = 5를 사용한다는 것을 알 수 있습니다.

이제 기본 R predict() 함수와 table() 함수를 사용하여 생성된 혼동 행렬을 사용하여 테스트 데이터에서 모델의 정확도를 확인합니다.

예제 코드:

# Use model to predict classes for the test set.
pred_cls = predict(mod_knn, tst_data)

# Check the accuracy of the predictions by computing the confusion matrix.
table(Actl = tst_class, Pred = pred_cls)

출력:

> table(Actl = tst_class, Pred = pred_cls)
      Pred
Actl   Blue Red
  Blue   25   0
  Red     0  25

우리는 모델이 완전한 정확도로 테스트 데이터 클래스를 예측했음을 발견했습니다. 이는 샘플 데이터 프레임에 데이터가 잘 분리되어 있기 때문에 가능했습니다.

실제로는 정확도가 더 낮을 것입니다. 그러나 각 모델에 대해 반복되는 k-겹 교차 검증 절차는 교육 데이터와 유사한 새 데이터에서 기대할 수 있는 정확도에 대한 좋은 아이디어를 제공합니다.

작가: Jesse John
Jesse John avatar Jesse John avatar

Jesse is passionate about data analysis and visualization. He uses the R statistical programming language for all aspects of his work.