Ga naar hoofdinhoud

K-Nearest Neighbors (KNN) Classificatie met R Tutorial

Duik in K-Nearest Neighbors (KNN)-classificatie met R. Leer hoe je de R-pakketten 'class' en 'caret' gebruikt, hyperparameters afstemt en modelprestaties evalueert.
· 11 min lezen

Verken met AI

image2.png

R is een krachtig hulpmiddel voor het implementeren van KNN-classificatie en wordt veel gebruikt door data scientists en statistici voor uiteenlopende machinelearning-toepassingen.

In deze tutorial leer je wat K-Nearest Neighbors is, hoe het werkt en bekijken we enkele voor- en nadelen. Verder gebruiken we de R-pakketten 'class' en 'caret' om het KNN-classificatiemodel eenvoudig te implementeren.

Wat is K-Nearest Neighbors?

K-Nearest Neighbors (KNN) is een supervised machinelearningmodel dat kan worden gebruikt voor zowel regressie- als classificatietaken. Het algoritme is niet-parametrisch, wat betekent dat het geen aannames doet over de onderliggende verdeling van de data.

Het KNN-algoritme voorspelt de labels van de testdataset door te kijken naar de labels van de dichtstbijzijnde buren in de feature-ruimte van de trainingsdataset. De “K” is de belangrijkste hyperparameter die je kunt afstemmen om de prestaties van het model te optimaliseren.

KNN is een eenvoudig en intuïtief algoritme dat goede resultaten kan leveren voor een breed scala aan classificatieproblemen. Het is makkelijk te implementeren en te begrijpen, en is toepasbaar op zowel kleine als grote datasets. Er zijn echter ook nadelen: de belangrijkste is dat het computationeel duur kan zijn voor grote datasets of hoge-dimensionale feature-ruimtes.

Het KNN-algoritme wordt gebruikt in aanbevelingssystemen voor e-commerce, beeldherkenning, fraudedetectie, tekstclassificatie, anomaliedetectie en nog veel meer. In deze tutorial gebruiken we het KNN-algoritme voor een systeem voor leninggoedkeuring.

Weet je niet goed hoe je met je data science-reis moet beginnen? Volg de carrièreroute Data Scientist Professional with R en bereid je voor op een succesvolle carrière in data science. Deze skill track helpt je R-programmeren, data-inname, datacleaning, datamanipulatie, datavisualisatie, machine learning, hypothesetests, experimentele designs, SQL en Git onder de knie te krijgen.

Hoe werkt K-Nearest Neighbors Classificatie?

Het KNN-classificatie-algoritme werkt door K buren (dichtstbijzijnde datapunten) in de trainingsdataset te zoeken voor een nieuw datapunt. Vervolgens kent het de label van de meerderheidsklasse onder die buren toe aan het nieuwe datapunt.

Laten we het algoritme in meerdere stappen opdelen.

Eerst berekent het de afstand tussen de nieuwe datapunten en alle andere datapunten in de trainingsset en selecteert het de K dichtstbijzijnde punten. De afstandsmaatstaf kan variëren afhankelijk van het probleem. De meest gebruikte maat is de Euclidische afstand.

Na het identificeren van de K dichtstbijzijnde buren, kent het algoritme de label van de meerderheidsklasse onder die buren toe aan het nieuwe datapunt. Als er bijvoorbeeld twee labels “blauw” zijn en één label “rood”, dan kent het algoritme het label “blauw” toe aan het nieuwe datapunt.

Gif from eunsukim.me

Gif van eunsukim.me

Samenvatting:

  1. We kiezen de waarde van K, het aantal dichtstbijzijnde buren dat wordt gebruikt voor de voorspelling.
  2. Bereken de afstand tussen dat punt en alle punten in de trainingsset.
  3. Selecteer de K dichtstbijzijnde buren op basis van de berekende afstanden.
  4. Koppel de label van de meerderheidsklasse aan het nieuwe datapunt.
  5. Herhaal stappen 2 t/m 4 voor alle datapunten in de testset.
  6. Evalueer de nauwkeurigheid van het algoritme.

De waarde van “K” wordt door de gebruiker opgegeven en kan worden gebruikt om de prestaties van het algoritme te optimaliseren. Kleinere K-waarden kunnen leiden tot overfitting en grotere waarden tot underfitting. Het is dus cruciaal om optimale waarden te vinden die stabiliteit en de beste fit bieden.

Implementatie van KNN in R

In deze sectie gebruiken we de Loan Data en trainen we KNN-classificatie met behulp van het class-pakket. De dataset bestaat uit 10.000 leningen en we gaan voorspellen of een lening wordt terugbetaald op basis van de gegevens van de klant.

Data laden

We importeren de tidyverse-bibliotheek om toegang te krijgen tot essentiële R-pakketten voor het laden, manipuleren en visualiseren van data. Met suppressPackageStartupMessages onderdruk je de waarschuwingen en krijg je een schone output.

Daarna gebruiken we read_csv om de dataset te laden, verwijderen we de kolom “purpose” uit de dataframe met de functie subset en tonen we de bovenste 3 rijen.

suppressPackageStartupMessages(library(tidyverse))

data <- read_csv('data/loans.csv.gz', show_col_types = FALSE)
data <- subset(data, select = -c(purpose))
head(data,3)

image4.png

Train-test-split

We kunnen de dataset handmatig splitsen, maar met de caTools-bibliotheek is het veel netter.

  • Zet een seed voor reproduceerbaarheid.
  • Gebruik sample.split om een index te maken voor train- en testdatasets met een verhouding van 75:25.
  • Gebruik subset om een train- en testdataset te maken, zoals hieronder getoond.
library(caTools)
set.seed(255)

split = sample.split(data$not_fully_paid, 
                     SplitRatio = 0.75)
train = subset(data, 
                      split == TRUE)
test = subset(data, 
                  split == FALSE)

Feature scaling

We schalen nu zowel de trainings- als de testset. Onder de motorkap gebruikt de functie (x - mean(x)) / sd(x). We schalen alleen features en verwijderen de doellabels uit zowel de test- als de trainingsset.

train_scaled = scale(train[-13])
test_scaled = scale(test[-13])

KNN-classifier trainen en voorspellen

De class-bibliotheek is behoorlijk populair voor het trainen van KNN-classificatie. Het is eenvoudig en snel. We geven een geschaalde train- en testset, de doeldkolom en de “k”-hyperparameter op.

library(class)
test_pred <- knn(
                 train = train_scaled, 
                 test = test_scaled,
                 cl = train$not_fully_paid, 
                 k=10
                 )

Model-evaluatie

Om de modelresultaten te evalueren, tonen we een confusion matrix met de functie table. We hebben de echte (testdoel) en voorspelde labels aan de functie table doorgegeven en zoals je ziet hebben we best goede resultaten voor de meerderheidsklasse.

Het KNN-algoritme is niet goed in het omgaan met ongebalanceerde data, en daarom zien we een slechte prestatie bij de minderheidsklasse.

actual <- test$not_fully_paid

cm <- table(actual,test_pred)
cm
     test_pred
actual    0    1
     0 1988   23
     1  373   10

We kunnen de accuracy berekenen door de true positives van de confusion matrix op te tellen en te delen door de totale lengte van de doeldkolom.

Zoals we zien, hebben we een goede accuracy met een standaardmodel. We kunnen deze accuracy verbeteren door de “K”-hyperparameter af te stemmen en de dataset in balans te brengen.

accuracy <- sum(diag(cm))/length(actual)
sprintf("Accuracy: %.2f%%", accuracy*100)
'Accuracy: 83.46%'

KNN-classificatie in R met caret

In deze sectie gebruiken we caret voor alles. caret is een R-pakket voor het bouwen en evalueren van machinelearningmodellen. Het biedt een interface voor de belangrijkste machinelearning-algoritmen.

We gebruiken het om de dataset te splitsen en voor te bewerken, hyperparameter-tuning uit te voeren en modellen te trainen en te evalueren.

Train-test-split

We importeren het caret-pakket en zetten de seed voor reproduceerbaarheid. Daarna converteren we de doelvariabele van integer naar factor. Tot slot gebruiken we createDataPartition om de dataset in train- en testdatasets te splitsen met een verhouding van 80:20.

suppressPackageStartupMessages(library(caret))
set.seed(255)

data$not_fully_paid <- factor(data$not_fully_paid, levels = c(0, 1))

trainIndex <- createDataPartition(data$not_fully_paid, 
								  times=1, 
								  p = .8, 
								  list = FALSE)
train <- data[trainIndex, ]
test <- data[-trainIndex, ]

Datavoorbewerking

Vervolgens schalen we zowel de trainings- als de testset met de functie preProcess.

preProcValues <- preProcess(train, method = c("center", "scale"))
trainTransformed <- predict(preProcValues, train)
testTransformed <- predict(preProcValues, test)

Modelafstemming

Voordat we ons KNN-model trainen, moeten we de optimale waarde van “K” vinden met de train-functie. De train-functie vereist een formule, geschaalde trainingsdataset, modelnaam, train control-methode (cross-validatie) en een lijst met hyperparameters. We gaan de modelprestaties controleren waarbij “K” gelijk is aan 3, 5 en 7.

knnModel <- train(
		     not_fully_paid ~ ., 
		     data = trainTransformed, 
	            method = "knn", 
		     trControl = trainControl(method = "cv"), 
		     tuneGrid = data.frame(k = c(3,5,7))
		    )

Best presterend model trainen

Nadat we de beste waarde van “K” hebben gevonden, trainen we het KNN-classificatiemodel met de geschaalde trainingsdataset.

best_model<- knn3(
                  not_fully_paid ~ .,
                  data = trainTransformed,
                  k = knnModel$bestTune$k
                 )

Model-evaluatie

caret biedt een eenvoudige en krachtige functie voor modelevaluatie. Om de modelprestaties te tonen, voorspellen we eerst de labels voor de onzichtbare testdataset. Daarna gebruiken we voorspelde en echte waarden om de modelprestaties te evalueren met de functie confusionMatrix.

predictions <- predict(best_model, testTransformed,type = "class")
# Calculate confusion matrix
cm <- confusionMatrix(predictions, testTransformed$not_fully_paid)
cm

Als resultaat krijgen we de confusion matrix, modelaccuracy, p-waarde, modelsensitiviteit en andere belangrijke statistieken die helpen de stabiliteit en prestaties van het model te bepalen.

Zoals we zien, presteert het model vrij slecht op “Neg Pred Value”, wat een minderheidsklasse is, en onze gebalanceerde accuracy is 51%. Dat is vergelijkbaar met kop of munt.

We kunnen het resultaat verbeteren door de klassen in balans te brengen met oversampling- en undersamplingmethoden. We kunnen ook feature engineering toepassen: nieuwe features creëren en sterk gecorreleerde features verwijderen.

Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 1570  288
         1   39   18
                                          
               Accuracy : 0.8292          
                 95% CI : (0.8116, 0.8458)
    No Information Rate : 0.8402          
    P-Value [Acc > NIR] : 0.9091          
                                          
                  Kappa : 0.0516          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.97576         
            Specificity : 0.05882         
         Pos Pred Value : 0.84499         
         Neg Pred Value : 0.31579         
             Prevalence : 0.84021         
         Detection Rate : 0.81984         
   Detection Prevalence : 0.97023         
      Balanced Accuracy : 0.51729         
                                          
       'Positive' Class : 0

We kunnen ons resultaat ook vereenvoudigen door het als een data frame weer te geven.

data.frame(Accuracy = cm$overall["Accuracy"],
           Sensitivity = cm$byClass["Sensitivity"],
           Specificity = cm$byClass["Specificity"])

image3.png

Ben je een Python-fan en wil je leren hoe je KNN-classificatie uitvoert? Lees dan onze tutorial K-Nearest Neighbors (KNN) Classificatie met scikit-learn om KNN-concepten en -workflow met voorbeelden te begrijpen.

Voordelen en nadelen van KNN

Voordelen

  1. Het is een eenvoudig algoritme om te begrijpen en te implementeren.
  2. Het is veelzijdig en kan worden gebruikt voor zowel regressie- als classificatietaken.
  3. Het levert interpreteerbare resultaten op die je kunt visualiseren en begrijpen, omdat de voorspelde klasse is gebaseerd op de labels van de dichtstbijzijnde buren in de trainingsdata.
  4. KNN doet geen aannames over de beslissingsgrens tussen klassen, wat het mogelijk maakt niet-lineaire relaties tussen features vast te leggen.
  5. Het algoritme doet geen aannames over de verdeling van de data, waardoor het geschikt is voor een breed scala aan problemen.
  6. KNN bouwt geen model. Het slaat de trainingsdata op en gebruikt die voor voorspellingen.

Nadelen

  1. Het is computationeel en qua geheugen duur voor grote en complexe datasets.
  2. De prestaties van KNN dalen bij ongebalanceerde data. Het vertoont een bias richting de meerderheidsklasse, wat kan resulteren in slechte prestaties voor minderheidsklassen.
  3. Het is niet geschikt voor ruisgevoelige data. De dichtstbijzijnde buren van een datapunt hoeven niet representatief te zijn voor het echte klasselabel.
  4. Het is niet geschikt voor hoog-dimensionale data, omdat bij hoge dimensionaliteit de afstanden tussen alle datapunten op elkaar kunnen gaan lijken.
  5. Het vinden van het optimale aantal K-buren kan tijdrovend zijn.
  6. KNN is gevoelig voor uitschieters, omdat het buren kiest op basis van een afstandsmaat.
  7. Het gaat niet goed om met ontbrekende waarden in de trainingsdataset.

Conclusie

In deze tutorial hebben we geleerd hoe je K-Nearest Neighbors (KNN)-classificatie met R gebruikt. We hebben het basisconcept van KNN en de werking ervan behandeld. Daarnaast hebben we kennisgemaakt met twee libraries, class en caret, voor het trainen en evalueren van KNN-classificatiemodellen op een echte dataset.

Volg de cursus Supervised Learning in R: Classification om andere supervised machinelearning-algoritmen met R te leren. Je leert over Naive Bayes, Logistische Regressie en Classification Trees met voorbeelden en code-oefeningen.

De R-tutorials omvatten stappen voor het manipuleren, splitsen en verwerken van de dataset, het afstemmen van hyperparameters, het trainen van de modellen en het evalueren van de resultaten. Door een ongebalanceerde dataset presteerden we het slechtst op de minderheidsklasse.

Het is belangrijk te begrijpen dat het KNN-algoritme niet perfect is; het heeft ook nadelen, en we moeten veel factoren meenemen voordat we het als primair model kiezen.

Abid Ali Awan

Auteur

Abid Ali Awan

Als gecertificeerd data scientist haal ik met passie het maximale uit de nieuwste technologie om innovatieve machinelearning-toepassingen te bouwen. Met een sterke achtergrond in spraakherkenning, data-analyse en -rapportage, MLOps, conversationele AI en NLP heb ik mijn vaardigheden aangescherpt in het ontwikkelen van intelligente systemen die echt impact maken. Naast mijn technische expertise ben ik ook een sterke communicator met een talent om complexe concepten terug te brengen tot heldere, beknopte taal. Daardoor ben ik uitgegroeid tot een veelgelezen blogger over data science, waar ik mijn inzichten en ervaringen deel met een groeiende community van data-professionals. Op dit moment richt ik me op contentcreatie en redactie, waarbij ik met large language models werk aan krachtige en aansprekende content die zowel bedrijven als individuen helpt het beste uit hun data te halen.

Onderwerpen

Gerelateerd