Auteur: Leihua Ye, UC Santa Barbara
Traduction: Chen Chao
Relecture: Feng Yu
Cet article est à propos de 2300 mots , Il est recommandé de lire 10 minutes
Cet article présente une méthode d'implémentation de l'algorithme K-plus proche en langage R pour les débutants.
Cet article présente un moyen de créer un modèle KNN en langage R, qui contient une variété d'indicateurs de mesure.
Photo de Mathyas Kurmann, d'Unsplash
«Si vous avez 5 minutes pour quitter la vie de Bill Gates, je parie que vous êtes riche.
Contexte
Dans le monde de l'apprentissage automatique, j'ai trouvé que le classificateur de l'algorithme de voisinage K (KNN) est le plus intuitif et le plus facile à utiliser, même sans introduire de symboles mathématiques.
Afin de déterminer le label de l'échantillon observé, nous observons ses échantillons voisins et étiquetons les échantillons voisins à l'échantillon observé d'intérêt. Bien entendu, l'observation d'un échantillon voisin peut entraîner des écarts et des erreurs. La méthode KNN a formulé une série de règles et de procédures pour déterminer le nombre optimal d'échantillons voisins, par exemple le test k > Échantillons adjacents de 1 et adoptez la règle de la majorité pour déterminer la classification.
"Afin de déterminer le libellé du nouvel échantillon d'observation, nous examinons l'échantillon du voisin le plus proche."
Mesure de distance
Afin de sélectionner l'échantillon le plus proche, nous devons définir la taille de la distance. Pour les données de catégorie, il y a la distance de Hamming et la distance d'édition. Voir les détails
https://en.m.wikipedia.org/wiki/Knearest_neighbors_algorithm
, Cet article ne traitera pas trop des problèmes mathématiques.
Qu'est-ce que la validation croisée K-fold?
Dans l'apprentissage automatique, la validation croisée (CV) joue un rôle clé dans la sélection de modèles et a une série d'applications. En fait, CV a un concept de design plus intuitif et est également très intuitif.
La brève introduction est la suivante:
1. Divisez les données en K blocs / couches uniformément répartis
2. Choisissez un ensemble de blocs / couches comme ensemble de test et les blocs / couches K-1 restants comme ensemble d'apprentissage.
3. Créez un modèle ML basé sur l'ensemble de formation
4. Ne comparez que la valeur prédite et la valeur vraie dans l'ensemble de test
5. Appliquez le modèle ML à l'ensemble de test et répétez le test K fois avec chaque bloc
6. Additionnez les scores métriques du modèle et trouvez la moyenne des K couches
Comment choisir K?
Comme vous l'avez remarqué, le point de la comparaison de validation croisée est de savoir comment définir une valeur pour K. Nous désignons la taille totale de l'échantillon par n. Techniquement, K peut être réglé sur n'importe quelle valeur de 1 à n.
Si k = n, nous prenons 1 observation comme ensemble d'apprentissage et les n-1 valeurs restantes comme ensemble de test. Répétez ensuite ce processus dans l'ensemble de l'ensemble de données. C'est ce qu'on appelle "laisser une validation croisée" (LOOCV).
La méthode de validation croisée laisser un seul retrait nécessite plus de puissance de calcul et si votre ensemble de données est trop volumineux, la méthode ne peut pas être interrompue.
En prenant du recul, même s'il n'y a pas de valeur k optimale, on ne peut pas dire qu'une valeur k plus grande est meilleure.
Afin de choisir la valeur de k la plus appropriée, nous devons peser le biais et la variance. Si k est petit, nous obtiendrons un écart plus important mais la variance sera plus petite lors de l'estimation de l'erreur de test; si la valeur k est relativement grande, notre biais sera plus petit et la variance sera plus grande.
Photo de Jon Tyson, d'Unsplash
"Bonjour voisin! Entrez."
Implémentation du langage R
1. Préparation du logiciel
# install.packages («ISLR»)
# install.packages («ggplot2») # install.packages («plyr»)
# install.packages («dplyr») # install.packages («class») # Charger les bibliothèques
bibliothèque (ISLR)
bibliothèque (ggplot2)
bibliothèque (reshape2)
bibliothèque (plyr)
bibliothèque (dplyr)
library (class) # charger des données et nettoyer l'ensemble de données
banking = read.csv ("bank-additional-full.csv", sep = ";", header = T) ## vérifier les données manquantes et s'assurer qu'aucune donnée ne manque
bancaire # recodage des variables qualitatives (factorielles) en
banking $ job = recode (banking $ job, " admin. = 1; blue-cols = 2; entrepreneur = 3;
femme de ménage »= 4;« direction »= 5;« retraité »= 6;« travailleur indépendant »= 7;« services »= 8;
Étudiant = 9; technicien = 10; chômeur = 11; inconnu = 12 ) # recoder à nouveau la variable
banking $ marital = recode (banking $ marital, "" divorcé "= 1;" marié "= 2;" célibataire "= 3;" inconnu "= 4")
banking $ education = recode (banking $ education, "'basic.4y' = 1; 'basic.6y' = 2; 'basic.9y' = 3; 'high.school' = 4; 'analphabète' = 5; ' professional.course '= 6;' university.degree '= 7;' unknown '= 8 )
banking $ default = recode (banking $ default, "" no "= 1;" yes "= 2;" unknown "= 3")
banque $ logement = recode (banque $ logement, «« non »= 1;« oui »= 2;« inconnu »= 3»)
bancaire $ prêt = recode (bancaire $ prêt, "'non' = 1; 'oui' = 2; 'inconnu' = 3") bancaire $ contact = recode (bancaire $ prêt, "'cellulaire' = 1; 'téléphone' = 2; ")
banking $ month = recode (banking $ month, "'mar' = 1; 'apr' = 2; 'may' = 3; 'jun' = 4; 'jul' = 5; 'aug' = 6; 'sep' = 7; 'oct' = 8; 'nov' = 9; 'dec' = 10 )
banking $ day_of_week = recode (banking $ day_of_week, "'mon' = 1; 'tue' = 2; 'wed' = 3; 'thu' = 4; 'fri' = 5;»)
banking $ poutcome = recode (banking $ poutcome, " échec = 1; inexistant = 2; succès = 3;») # supprimer la variable «pdays», b / c elle na pas de variation
banking $ pdays = NULL #remove variable «duration», b / c elle est colinéaire avec le DV
banque $ duration = NULL
Après avoir chargé et effacé l'ensemble de données initial, la pratique habituelle consiste à visualiser la distribution des variables, à vérifier la saisonnalité, les modèles, les valeurs aberrantes, etc.
#EDA du DV
plot (banking $ y, main = "Plot 1: Distribution of Dependent Variable")
Comme le montre la figure, la variable de résultat (abonnement au service bancaire) ne satisfait pas une distribution uniforme, et "Non" est bien plus que "Oui".
Lorsque nous essayons de classer correctement les étiquettes, l'apprentissage supervisé n'est pas très pratique. Comme prévu, si un grand nombre de cas minoritaires sont classés comme l'étiquette majoritaire, le taux de faux positifs sera plus élevé.
En fait, une distribution inégale peut préférer les classificateurs ML non paramétriques, dans mon autre article (Utilisation de 5 classificateurs pour classer des événements rares, https://medium.com/m/global-identity?
redirectUrl = https% 3A% 2F% 2Ftowardsdatascience.com% 2Fc classifying-rare-events-using-five-machine-learning-techniques-fab464573233) a introduit KNN pour être plus performant après comparaison avec d'autres méthodes ML. Cela peut être causé par des hypothèses mathématiques et statistiques sous-jacentes dans les modèles paramétriques et non paramétriques.
2. Regroupement des données
Comme mentionné ci-dessus, nous devons regrouper l'ensemble de données en ensemble d'apprentissage et ensemble de test, et adopter la validation croisée de la couche k pour sélectionner le meilleur modèle ML. Selon la règle empirique, nous utilisons généralement le ratio «80-20»: nous formons ML avec 80% des données et testons avec les 20% restants. Les données de la série chronologique sont légèrement différentes, nous avons changé le ratio de 90% à 10%.
# diviser l'ensemble de données en ensembles d'entraînement et de test de manière aléatoire, mais nous devons définir des semences de manière à générer la même valeur à chaque fois que nous exécutons le jeu de codes.seed (1) #create un index pour diviser les données: 80% d'entraînement et 20% tester
index = round (nrow (banking) * 0.2, digits = 0) #sample aléatoirement dans l'ensemble de données et garder le nombre total égal à la valeur de l'index
test.indices = sample (1: nrow (banking), index) # Ensemble d'entraînement à 80%
banking.train = ensemble de test bancaire # 20%
banking.test = banking #Sélectionnez l'ensemble de formation sauf le DV
YTrain = banking.train $ y
XTrain = banking.train% > % select (-y) # Sélectionnez l'ensemble de test sauf le DV
YTest = banking.test $ y
XTest = banking.test% > % select (-y)
Jusqu'à présent, nous avons terminé la préparation des données et commencé la sélection du modèle.
3. Formation du modèle
Écrivons une nouvelle fonction ("calc_error_rate") pour enregistrer le taux de classification des erreurs. Cette fonction calcule le rapport de non-concordance entre l'étiquette prédite obtenue lors de l'utilisation de l'ensemble d'apprentissage et l'étiquette de résultat réel. Il mesure l'exactitude de la classification.
#define une fonction de taux d'erreur et l'applique pour obtenir des erreurs de test / entraînementcalc_error_rate < -fonction (valeur.prédite, valeur.vrai) {
return (mean (true.value! = preded.value))
}
Ensuite, nous avons besoin d'une autre fonction "do.chunk ()" pour effectuer la validation croisée de la couche k. Cette fonction renvoie un bloc de données des valeurs possibles du calque. L'objectif principal de cette étape est de sélectionner la meilleure valeur K pour KNN.
nfold = 10
set.seed (1) # cut () divise la plage en plusieurs intervalles
folds = seq.int (nrow (banking.train))% > %
cut (breaks = nfold, labels = FALSE)% > %
sampledo.chunk < -fonction (chunkid, folddef, Xdat, Ydat, k) {
train = (folddef! = chunkid) # training indexXtr = Xdat # training set by the indexYtr = Ydat # true label in training setXvl = Xdat # test setYvl = Ydat # true label in test setpredYtr = knn (train = Xtr, test = Xtr , cl = Ytr, k = k) # prédire les étiquettes de formation predYvl = knn (train = Xtr, test = Xvl, cl = Ytr, k = k) # prédire les étiquettes de testdata.frame (fold = chunkid, # k replis
train.error = calc_error_rate (predYtr, Ytr), # erreur d'entraînement par pli
val.error = calc_error_rate (predYvl, Yvl)) # erreur de test par pli
} # set error.folds pour enregistrer les erreurs de validation
error.folds = NULL # crée une séquence de données avec un intervalle de 10
kvec = c (1, seq (10, 50, length.out = 5)) set.seed (1) for (j en kvec) {
tmp = ldply (1: nfold, do.chunk, # applique do.function à chaque pli
folddef = replis, Xdat = XTrain, Ydat = YTrain, k = j) # arguments requis
tmp $ voisins = j # suivre chaque valeur des voisins
error.folds = rbind (error.folds, tmp) # combine les résultats
} #melt () dans le package reshape2 fusionne les données grand format en données long format
errors = melt (error.folds, id.vars = c ("fold", "voisins"), value.name = "error")
L'étape suivante consiste à trouver la valeur de k qui minimise l'erreur de vérification.
val.error.means = erreurs% > %
#select toutes les lignes d'erreurs de validation
filter (variable == "val.error")% > %
# regrouper les données sélectionnées par voisins
group_by (voisins, variable)% > %
#cacluate erreur CV pour chaque k
summary_each (funs (moyenne), erreur)% > %
#remove groupe existant
dissocier ()% > %
filter (error == min (error)) # le meilleur nombre de voisins
numnequart = max (val.error.means $ voisins)
numnequart ##
Après avoir utilisé la validation croisée à 10 niveaux, le nombre optimal de voisins est de 20.
Nick Youngson
4. Quelques indicateurs de modèle
# erreur de formation
set.seed (20)
pred.YTtrain = knn (train = XTrain, test = XTrain, cl = YTrain, k = 20)
knn_traing_error < -calc_error_rate (preded.value = pred.YTtrain, true.value = YTrain)
knn_traing_error
0,101214
L'erreur d'apprentissage est de 0,1.
#test error
set.seed (20)
pred.YTest = knn (train = XTrain, test = XTest, cl = YTrain, k = 20)
knn_test_error < -calc_error_rate (preded.value = pred.YTest, true.value = YTest)
knn_test_error
0,1100995
L'erreur de test est de 0,11.
#confusion matrixconf.matrix = table (prédite = pred.YTest, true = YTest)
Sur la base de la matrice de confusion ci-dessus, nous pouvons calculer les valeurs suivantes et nous préparer à dessiner la courbe ROC.
Précision = (TP + TN) / (TP + FP + FN + TN)
TPR / Rappel / Sensibilité = TP / (TP + FN)
Précision = TP / (TP + FP)
Spécificité = TN / (TN + FP)
FPR = 1 - Spécificité = FP / (TN + FP)
Score F1 = 2 * TP / (2 * TP + FP + FN) = Précision * Rappel / (Précision + Rappel)
# Taux de précision du testum (diag (conf.matrix) / sum (conf.matrix)) 0.8899005 # Test error rate1-sum (glisser (conf.matrix) / sum (conf.matrix)) 0.1100995
Vous remarquerez peut-être que le taux de test correct + le taux d'erreur de test = 1, je propose également plusieurs méthodes pour calculer chaque valeur.
# ROC et AUC
knn_model = knn (train = XTrain, test = XTrain, cl = YTrain, k = 20, prob = TRUE) prob < -attr (knn_model, "prob") prob < -2 * ifelse (knn_model == -1, prob, 1-prob) - 1pred_knn < -prédiction (prob, YTrain) performance_knn < -performance (pred_knn, "tpr", "fpr") # AUCauc_knn < -performance(pred_knn,"auc")@y.valuesauc_knn 0.8470583plot (performance_knn, col = 2, lwd = 2, main = "Courbes ROC pour KNN")
En résumé, nous avons appris ce qu'est KNN et avons construit un modèle KNN en langage R. Plus important encore, nous avons appris le mécanisme derrière la validation croisée de la couche K et comment implémenter la validation croisée en langage R.
A propos de l'auteur:
Lei Hua Ye (@leihua_ye) est doctorante à l'Université de Californie à Santa Barbara. Il a plus de 5 ans de recherche et d'expérience professionnelle dans la recherche quantitative sur l'expérience utilisateur, les expériences et le raisonnement causal, l'apprentissage automatique et la science des données.
Titre original:
Guide du débutant des K-Nearest Neighbours dans R: de zéro à héros
Lien d'origine:
https://www.kdnuggets.com/2020/01/beginners-guide-nearest-neighbors-r.html
Editeur: Yu Tengkai
Relecture: Tan Jiayao
Profil de traducteur
Chen Chao , Master de psychologie appliquée à l'Université de Pékin. Le premier étudiant était autrefois en informatique, puis il a continué à explorer la voie de la psychologie. De plus en plus constatent que l'analyse de données et la programmation sont devenues deux compétences de survie obligatoires, alors je fais tous les efforts dans ma vie quotidienne pour mieux accéder et comprendre les connaissances pertinentes, mais le chemin à parcourir est long et je suis toujours sur la route.
-Terminer-
Suivez la plate-forme publique officielle WeChat de l'Institut Tsinghua-Qingdao pour la science des données " Tarte aux données THU "Et le numéro de soeur" Tarte aux données JEU "Obtenez plus d'avantages de cours et un contenu de qualité.