Introduction
Ce laboratoire montre comment imputer les données manquantes dans un ensemble de données à l'aide de différentes techniques dans scikit-learn. Les ensembles de données utilisés ici sont l'ensemble de données sur le diabète avec 10 caractéristiques et l'ensemble de données sur le logement en Californie avec 8 caractéristiques. Les valeurs manquantes peuvent être remplacées par la moyenne, la médiane ou la valeur la plus fréquente à l'aide de SimpleImputer. Ce laboratoire étudiera différentes techniques d'imputation telles que l'imputation par une valeur constante, l'imputation par la moyenne de chaque caractéristique combinée avec une variable auxiliaire indicateur d'absence de données, l'imputation par les k plus proches voisins et l'imputation itérative.
Conseils sur la machine virtuelle
Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Notebook pour accéder à Jupyter Notebook pour la pratique.
Parfois, vous devrez peut-être attendre quelques secondes pour que Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations de Jupyter Notebook.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez des commentaires après la session, et nous résoudrons rapidement le problème pour vous.
Télécharger les données et créer des ensembles de données avec des valeurs manquantes
Tout d'abord, les deux ensembles de données sont téléchargés. Nous n'utiliserons que les 400 premières entrées pour l'ensemble de données sur le logement en Californie afin d'accélérer les calculs. Ensuite, nous supprimerons certaines valeurs pour créer de nouvelles versions avec des données manquantes artificielles.
import numpy as np
from sklearn.datasets import fetch_california_housing, load_diabetes
rng = np.random.RandomState(42)
X_diabetes, y_diabetes = load_diabetes(return_X_y=True)
X_california, y_california = fetch_california_housing(return_X_y=True)
X_california = X_california[:400]
y_california = y_california[:400]
X_diabetes = X_diabetes[:400]
y_diabetes = y_diabetes[:400]
def add_missing_values(X_full, y_full):
n_samples, n_features = X_full.shape
## Ajouter des valeurs manquantes dans 75% des lignes
missing_rate = 0.75
n_missing_samples = int(n_samples * missing_rate)
missing_samples = np.zeros(n_samples, dtype=bool)
missing_samples[:n_missing_samples] = True
rng.shuffle(missing_samples)
missing_features = rng.randint(0, n_features, n_missing_samples)
X_missing = X_full.copy()
X_missing[missing_samples, missing_features] = np.nan
y_missing = y_full.copy()
return X_missing, y_missing
X_miss_california, y_miss_california = add_missing_values(X_california, y_california)
X_miss_diabetes, y_miss_diabetes = add_missing_values(X_diabetes, y_diabetes)
Imputer les données manquantes et évaluer les résultats
Maintenant, nous allons écrire une fonction qui évaluera les résultats sur les données imputées différemment. Regardons chaque imputateur séparément :
from sklearn.ensemble import RandomForestRegressor
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import SimpleImputer, KNNImputer, IterativeImputer
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline
N_SPLITS = 4
regressor = RandomForestRegressor(random_state=0)
def get_scores_for_imputer(imputer, X_missing, y_missing):
estimator = make_pipeline(imputer, regressor)
impute_scores = cross_val_score(
estimator, X_missing, y_missing, scoring="neg_mean_squared_error", cv=N_SPLITS
)
return impute_scores
x_labels = []
mses_california = np.zeros(5)
stds_california = np.zeros(5)
mses_diabetes = np.zeros(5)
stds_diabetes = np.zeros(5)
Estimer le score
Tout d'abord, nous voulons estimer le score sur les données originales :
def get_full_score(X_full, y_full):
full_scores = cross_val_score(
regressor, X_full, y_full, scoring="neg_mean_squared_error", cv=N_SPLITS
)
return full_scores.mean(), full_scores.std()
mses_california[0], stds_california[0] = get_full_score(X_california, y_california)
mses_diabetes[0], stds_diabetes[0] = get_full_score(X_diabetes, y_diabetes)
x_labels.append("Full data")
Remplacer les valeurs manquantes par 0
Maintenant, nous allons estimer le score sur les données où les valeurs manquantes sont remplacées par 0 :
def get_impute_zero_score(X_missing, y_missing):
imputer = SimpleImputer(
missing_values=np.nan, add_indicator=True, strategy="constant", fill_value=0
)
zero_impute_scores = get_scores_for_imputer(imputer, X_missing, y_missing)
return zero_impute_scores.mean(), zero_impute_scores.std()
mses_california[1], stds_california[1] = get_impute_zero_score(
X_miss_california, y_miss_california
)
mses_diabetes[1], stds_diabetes[1] = get_impute_zero_score(
X_miss_diabetes, y_miss_diabetes
)
x_labels.append("Zero imputation")
Imputation des valeurs manquantes par KNN
KNNImputer impute les valeurs manquantes en utilisant la moyenne pondérée ou non pondérée du nombre souhaité de plus proches voisins.
def get_impute_knn_score(X_missing, y_missing):
imputer = KNNImputer(missing_values=np.nan, add_indicator=True)
knn_impute_scores = get_scores_for_imputer(imputer, X_missing, y_missing)
return knn_impute_scores.mean(), knn_impute_scores.std()
mses_california[2], stds_california[2] = get_impute_knn_score(
X_miss_california, y_miss_california
)
mses_diabetes[2], stds_diabetes[2] = get_impute_knn_score(
X_miss_diabetes, y_miss_diabetes
)
x_labels.append("KNN Imputation")
Imputer les valeurs manquantes avec la moyenne
def get_impute_mean(X_missing, y_missing):
imputer = SimpleImputer(missing_values=np.nan, strategy="mean", add_indicator=True)
mean_impute_scores = get_scores_for_imputer(imputer, X_missing, y_missing)
return mean_impute_scores.mean(), mean_impute_scores.std()
mses_california[3], stds_california[3] = get_impute_mean(
X_miss_california, y_miss_california
)
mses_diabetes[3], stds_diabetes[3] = get_impute_mean(X_miss_diabetes, y_miss_diabetes)
x_labels.append("Mean Imputation")
Imputation itérative des valeurs manquantes
Une autre option est l'IterativeImputer. Cela utilise une régression linéaire en boucle, en modélisant chaque caractéristique avec des valeurs manquantes en fonction des autres caractéristiques, tour à tour. La version implémentée suppose des variables gaussiennes (de sortie). Si vos caractéristiques ne sont pas manifestement normales, envisagez de les transformer pour les rendre plus normales afin de potentiellement améliorer les performances.
def get_impute_iterative(X_missing, y_missing):
imputer = IterativeImputer(
missing_values=np.nan,
add_indicator=True,
random_state=0,
n_nearest_features=3,
max_iter=1,
sample_posterior=True,
)
iterative_impute_scores = get_scores_for_imputer(imputer, X_missing, y_missing)
return iterative_impute_scores.mean(), iterative_impute_scores.std()
mses_california[4], stds_california[4] = get_impute_iterative(
X_miss_california, y_miss_california
)
mses_diabetes[4], stds_diabetes[4] = get_impute_iterative(
X_miss_diabetes, y_miss_diabetes
)
x_labels.append("Iterative Imputation")
mses_diabetes = mses_diabetes * -1
mses_california = mses_california * -1
Tracer les résultats
Enfin, nous allons visualiser le score :
n_bars = len(mses_diabetes)
xval = np.arange(n_bars)
colors = ["r", "g", "b", "orange", "black"]
## plot diabetes results
plt.figure(figsize=(12, 6))
ax1 = plt.subplot(121)
for j in xval:
ax1.barh(
j,
mses_diabetes[j],
xerr=stds_diabetes[j],
color=colors[j],
alpha=0.6,
align="center",
)
ax1.set_title("Imputation Techniques with Diabetes Data")
ax1.set_xlim(left=np.min(mses_diabetes) * 0.9, right=np.max(mses_diabetes) * 1.1)
ax1.set_yticks(xval)
ax1.set_xlabel("MSE")
ax1.invert_yaxis()
ax1.set_yticklabels(x_labels)
## plot california dataset results
ax2 = plt.subplot(122)
for j in xval:
ax2.barh(
j,
mses_california[j],
xerr=stds_california[j],
color=colors[j],
alpha=0.6,
align="center",
)
ax2.set_title("Imputation Techniques with California Data")
ax2.set_yticks(xval)
ax2.set_xlabel("MSE")
ax2.invert_yaxis()
ax2.set_yticklabels([""] * n_bars)
plt.show()
Sommaire
Ce laboratoire montre comment imputer les données manquantes dans un ensemble de données à l'aide de différentes techniques dans scikit-learn. Nous avons utilisé l'ensemble de données sur le logement en Californie et l'ensemble de données sur le diabète pour implémenter différentes techniques telles que l'imputation par une valeur constante, l'imputation par la valeur moyenne de chaque caractéristique combinée avec une variable auxiliaire indicateur d'absence de données, l'imputation par les k plus proches voisins et l'imputation itérative. Nous avons également visualisé les scores à l'aide de graphiques en barres.