Fehlende Daten einschätzen

Machine LearningMachine LearningBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab wird gezeigt, wie man fehlende Daten in einem Datensatz mit verschiedenen Techniken in scikit-learn einträgt. Als Datensätze werden hier der Diabetes-Datensatz mit 10 Merkmalen und der Kalifornien-Wohnungs-Datensatz mit 8 Merkmalen verwendet. Die fehlenden Werte können mithilfe von SimpleImputer durch den Mittelwert, die Median oder den häufigsten Wert ersetzt werden. In diesem Lab werden verschiedene Imputations-Techniken untersucht, wie die Imputation mit einem konstanten Wert, die Imputation mit dem Mittelwert jedes Merkmals in Kombination mit einer Hilfsvariable für die Fehlendheitsanzeige, die k-nearest-neighbor-Imputation und die iterative Imputation.

Tipps für die VM

Nachdem der Start der VM abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.

Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund von Einschränkungen in Jupyter Notebook nicht automatisiert werden.

Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.

Daten herunterladen und Mengen mit fehlenden Werten erstellen

Zunächst werden die beiden Datensätze heruntergeladen. Wir werden nur die ersten 400 Einträge für den Kalifornien-Wohnungs-Datensatz verwenden, um die Berechnungen zu beschleunigen. Anschließend werden einige Werte entfernt, um neue Versionen mit künstlich fehlenden Daten zu erstellen.

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

    ## Füge fehlende Werte in 75% der Zeilen hinzu
    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)

Fehlende Daten eintragen und bewerten

Jetzt werden wir eine Funktion schreiben, die die Ergebnisse auf den unterschiedlich eintragenen Daten bewertet. Schauen wir uns jedes Imputer einzeln an:

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)

Die Bewertung abschätzen

Zunächst möchten wir die Bewertung auf den ursprünglichen Daten abschätzen:

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")

Fehlende Werte durch 0 ersetzen

Jetzt werden wir die Bewertung auf den Daten abschätzen, bei denen die fehlenden Werte durch 0 ersetzt werden:

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")

KNN-Einschätzung der fehlenden Werte

KNNImputer schätzt fehlende Werte mithilfe des gewichteten oder ungewichteten Mittelwerts der gewünschten Anzahl der nächsten Nachbarn.

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")

Fehlende Werte mit Mittelwert eintragen

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")

Iterative Einschätzung der fehlenden Werte

Eine weitere Option ist der IterativeImputer. Dieser verwendet eine Rund-Robin-Linear-Regression, um jeweils jede Feature mit fehlenden Werten als Funktion der anderen Feature zu modellieren. Die implementierte Version nimmt an, dass die Variablen (Output) gaussian verteilt sind. Wenn Ihre Feature offensichtlich nicht normal verteilt sind, sollten Sie sie möglicherweise transformieren, um sie normaler zu gestalten und so eventuell die Leistung zu verbessern.

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

Die Ergebnisse visualisieren

Schließlich werden wir die Bewertung visualisieren:

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()

Zusammenfassung

In diesem Lab wird gezeigt, wie man fehlende Daten in einem Datensatz mit verschiedenen Techniken in scikit-learn einschätzen kann. Wir haben den California Housing Datensatz und den Diabetes Datensatz verwendet, um verschiedene Techniken wie die Einschätzung durch einen konstanten Wert, die Einschätzung durch den Mittelwert jedes Features in Kombination mit einer Hilfsvariable für die Fehlendheit, die k-nearest-neighbor-Einschätzung und die iterative Einschätzung umzusetzen. Wir haben auch die Bewertungen mithilfe von Balkendiagrammen visualisiert.