Pour prédire un cas nouveau, on cherche les k cas passés les plus ressemblants et on reprend leur réponse : vote pour une classe, moyenne pour un chiffre. Aucun modèle à entraîner, seulement une distance à bien définir. C'est la méthode des comparables, rendue automatique.
Un agent immobilier estime un appartement en regardant les ventes récentes de biens similaires dans le quartier.
Sans cela, une surface en m² (des centaines) écraserait un nombre de concurrents (quelques unités) dans le calcul de distance.
Pour le nouveau cas, on calcule sa distance à tous les cas connus, en général la distance euclidienne, et on garde les k plus petits.
En régression, la moyenne de leurs valeurs ; en classification, la classe majoritaire. On peut pondérer par la distance pour donner plus de poids aux plus proches.
Surface, budget publicitaire, nombre de concurrents, zone (centre-ville, périphérie, rural) et chiffre d'affaires annuel. Plus les caractéristiques d'un projet d'ouverture.
Le modèle propose un chiffre d'affaires et la liste des magasins qui ont servi à l'estimer. Le comité d'investissement peut discuter chaque comparable, ce qu'aucune formule ne permet.
On mesure l'écart moyen entre CA estimé et CA réel sur des magasins mis de côté. Sur le jeu d'exemple, k = 1 donne l'erreur la plus forte ; k = 10 fait mieux que k = 5 et que k = 20.
Noms donnés pour R (FNN) et Python (scikit-learn).
Nombre de voisins consultés. Trop petit, la prédiction suit le bruit d'un seul cas ; trop grand, elle se rapproche de la moyenne générale. Se choisit par validation croisée.
Centrer et réduire chaque variable avant tout calcul de distance, avec les paramètres calculés sur l'entraînement seulement.
Pondération des voisins. "uniform" donne le même poids à tous, "distance" favorise les plus proches. FNN ne propose que la moyenne simple ; le package kknn permet la pondération.
# CA d'un projet de magasin : k plus proches voisins en R
library(FNN)
magasins <- read.csv("magasins.csv")
X <- model.matrix(~ surface_m2 + budget_pub_k + nb_concurrents + zone, data = magasins)[, -1]
set.seed(42)
idx <- sample(nrow(magasins), 300)
# Mise à l'échelle avec les paramètres de l'entraînement
X_train <- scale(X[idx, ])
X_test <- scale(X[-idx, ], center = attr(X_train, "scaled:center"), scale = attr(X_train, "scaled:scale"))
y_train <- magasins$ca_k[idx]
y_test <- magasins$ca_k[-idx]
for (k in c(1, 5, 10, 20)) {
pred <- knn.reg(train = X_train, test = X_test, y = y_train, k = k)$pred
cat("k =", k, "| erreur moyenne (k€) :", round(mean(abs(pred - y_test)), 1), "\n")
}
# Les 10 magasins comparables du premier projet du jeu de test
voisins <- get.knnx(X_train, X_test[1, , drop = FALSE], k = 10)$nn.index
print(magasins[idx[voisins[1, ]], c("surface_m2", "budget_pub_k", "zone", "ca_k")])
# CA d'un projet de magasin : k plus proches voisins en Python
import pandas as pd
from sklearn.neighbors import KNeighborsRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error
magasins = pd.read_csv("magasins.csv")
X = pd.get_dummies(magasins[["surface_m2", "budget_pub_k", "nb_concurrents", "zone"]], dtype=float)
y = magasins["ca_k"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
# Mise à l'échelle obligatoire : sinon la surface (en m²) écrase les autres variables
for k in [1, 5, 10, 20]:
modele = make_pipeline(StandardScaler(), KNeighborsRegressor(n_neighbors=k)).fit(X_train, y_train)
print("k =", k, "| erreur moyenne (k€) :", round(mean_absolute_error(y_test, modele.predict(X_test)), 1))
# Les 10 magasins comparables du premier projet du jeu de test
modele = make_pipeline(StandardScaler(), KNeighborsRegressor(n_neighbors=10)).fit(X_train, y_train)
projet = X_test.iloc[[0]]
_, voisins = modele[-1].kneighbors(modele[0].transform(projet))
print(magasins.loc[X_train.index[voisins[0]], ["surface_m2", "budget_pub_k", "zone", "ca_k"]])
print("CA estimé (k€) :", round(modele.predict(projet)[0], 1), "| CA réel (k€) :", y_test.iloc[0])
Par validation croisée : on teste plusieurs valeurs et on garde celle qui minimise l'erreur sur des données non vues. Un k petit colle aux cas individuels, un k grand lisse vers la moyenne. En classification binaire, un k impair évite les égalités de vote.
Oui, toujours. La distance additionne les écarts de toutes les variables : une variable exprimée en milliers domine celles exprimées en unités. On centre et on réduit chaque variable, avec les paramètres de l'entraînement.
Il ne construit aucun modèle : il garde les données telles quelles et fait tout le calcul au moment de la prédiction. L'entraînement est instantané, mais chaque prédiction doit comparer le nouveau cas à toute la base, ce qui devient lent sur de gros volumes.
Une formule au lieu de comparables. Meilleure quand la relation est régulière, et elle extrapole.
Voir la fiche → plus robusteChoisit seule les variables utiles et n'a pas besoin de mise à l'échelle.
Voir la fiche → le même principe, en recommandationTrouver les clients aux goûts proches pour recommander ce qu'ils ont aimé.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus