Scikit-learn impute wird verwendet, um fehlende Daten als Vorprozess für maschinelles Lernen auszufüllen. Ich habe versucht, das Verhalten mit einfachen Daten zu überprüfen.
data = {
'A': [a for a in range(10)],
'B': [a * 2 for a in range(10)],
'C': [a * 3 for a in range(10)],
'D': [a * 4 for a in range(10)],
}
import pandas as pd
data = pd.DataFrame(data)
data
A | B | C | D | |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
1 | 1 | 2 | 3 | 4 |
2 | 2 | 4 | 6 | 8 |
3 | 3 | 6 | 9 | 12 |
4 | 4 | 8 | 12 | 16 |
5 | 5 | 10 | 15 | 20 |
6 | 6 | 12 | 18 | 24 |
7 | 7 | 14 | 21 | 28 |
8 | 8 | 16 | 24 | 32 |
9 | 9 | 18 | 27 | 36 |
import numpy as nan
data2 = pd.DataFrame(data)
#data2['B'][3] = np.nan
data2.loc.__setitem__(((2), ("B")), np.nan)
data2.loc.__setitem__(((3), ("C")), np.nan)
data2.loc.__setitem__(((5), ("C")), np.nan)
data2.loc.__setitem__(((6), ("D")), np.nan)
data2.loc.__setitem__(((7), ("D")), np.nan)
data2
A | B | C | D | |
---|---|---|---|---|
0 | 0 | 0.0 | 0.0 | 0.0 |
1 | 1 | 2.0 | 3.0 | 4.0 |
2 | 2 | NaN | 6.0 | 8.0 |
3 | 3 | 6.0 | NaN | 12.0 |
4 | 4 | 8.0 | 12.0 | 16.0 |
5 | 5 | 10.0 | NaN | 20.0 |
6 | 6 | 12.0 | 18.0 | NaN |
7 | 7 | 14.0 | 21.0 | NaN |
8 | 8 | 16.0 | 24.0 | 32.0 |
9 | 9 | 18.0 | 27.0 | 36.0 |
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(data2)
Wie oben beschrieben, haben wir Spalte B mit einem fehlenden Wert, Spalte C mit zwei und Spalte D mit aufeinanderfolgenden fehlenden Werten erstellt.
SimpleImputer
Die SimpleImputer-Klasse bietet eine grundlegende Berechnungsmethode für die Eingabe fehlender Werte. Fehlende Werte können anhand der angegebenen konstanten Werte oder anhand der Statistiken (Mittelwert, Median oder am häufigsten auftretende Werte) jeder Spalte berechnet werden, in der die fehlenden Werte vorhanden sind.
default(mean)
Der Standardwert wird mit dem Durchschnittswert gefüllt.
from sklearn.impute import SimpleImputer
imp = SimpleImputer() #missing_values=np.nan, strategy='mean')
data3 = pd.DataFrame(imp.fit_transform(data2))
data3
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 0.0 | 0.000000 | 0.000 | 0.0 |
1 | 1.0 | 2.000000 | 3.000 | 4.0 |
2 | 2.0 | 9.555556 | 6.000 | 8.0 |
3 | 3.0 | 6.000000 | 13.875 | 12.0 |
4 | 4.0 | 8.000000 | 12.000 | 16.0 |
5 | 5.0 | 10.000000 | 13.875 | 20.0 |
6 | 6.0 | 12.000000 | 18.000 | 16.0 |
7 | 7.0 | 14.000000 | 21.000 | 16.0 |
8 | 8.0 | 16.000000 | 24.000 | 32.0 |
9 | 9.0 | 18.000000 | 27.000 | 36.0 |
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(data3)
Wie oben erwähnt, kann es je nach Art der Daten unnatürlich sein, den Durchschnittswert einzugeben.
median
Sie können die fehlenden Werte auch mit Medianwerten füllen.
from sklearn.impute import SimpleImputer
imp = SimpleImputer(missing_values=np.nan, strategy='median')
data4 = pd.DataFrame(imp.fit_transform(data2))
data4
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 0.0 | 0.0 | 0.0 | 0.0 |
1 | 1.0 | 2.0 | 3.0 | 4.0 |
2 | 2.0 | 10.0 | 6.0 | 8.0 |
3 | 3.0 | 6.0 | 15.0 | 12.0 |
4 | 4.0 | 8.0 | 12.0 | 16.0 |
5 | 5.0 | 10.0 | 15.0 | 20.0 |
6 | 6.0 | 12.0 | 18.0 | 14.0 |
7 | 7.0 | 14.0 | 21.0 | 14.0 |
8 | 8.0 | 16.0 | 24.0 | 32.0 |
9 | 9.0 | 18.0 | 27.0 | 36.0 |
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(data4)
Wie der Durchschnittswert kann es beim Füllen mit dem Medianwert je nach Inhalt der Daten zu einem unnatürlichen Fülltyp werden.
most_frequent
Sie können auch die häufigsten Werte eingeben.
from sklearn.impute import SimpleImputer
imp = SimpleImputer(missing_values=np.nan, strategy='most_frequent')
data5 = pd.DataFrame(imp.fit_transform(data2))
data5
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 0.0 | 0.0 | 0.0 | 0.0 |
1 | 1.0 | 2.0 | 3.0 | 4.0 |
2 | 2.0 | 0.0 | 6.0 | 8.0 |
3 | 3.0 | 6.0 | 0.0 | 12.0 |
4 | 4.0 | 8.0 | 12.0 | 16.0 |
5 | 5.0 | 10.0 | 0.0 | 20.0 |
6 | 6.0 | 12.0 | 18.0 | 0.0 |
7 | 7.0 | 14.0 | 21.0 | 0.0 |
8 | 8.0 | 16.0 | 24.0 | 32.0 |
9 | 9.0 | 18.0 | 27.0 | 36.0 |
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(data5)
Wenn es keinen häufigsten Wert gibt, scheint er mit dem ersten Wert gefüllt zu sein.
constant
Sie können auch eine vorgegebene Zahl festlegen und damit füllen.
from sklearn.impute import SimpleImputer
imp = SimpleImputer(missing_values=np.nan, strategy='constant', fill_value=99)
data6 = pd.DataFrame(imp.fit_transform(data2))
data6
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 0.0 | 0.0 | 0.0 | 0.0 |
1 | 1.0 | 2.0 | 3.0 | 4.0 |
2 | 2.0 | 99.0 | 6.0 | 8.0 |
3 | 3.0 | 6.0 | 99.0 | 12.0 |
4 | 4.0 | 8.0 | 12.0 | 16.0 |
5 | 5.0 | 10.0 | 99.0 | 20.0 |
6 | 6.0 | 12.0 | 18.0 | 99.0 |
7 | 7.0 | 14.0 | 21.0 | 99.0 |
8 | 8.0 | 16.0 | 24.0 | 32.0 |
9 | 9.0 | 18.0 | 27.0 | 36.0 |
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(data6)
Nun, wie unnatürlich es ist!
KNNImputer
Die KNNImputer-Klasse füllt fehlende Werte mithilfe des k-Nearest Neighbors-Ansatzes aus. Standardmäßig wird die euklidische Distanzmetrik nan_euclidean_distances verwendet, die fehlende Werte unterstützt, um die nächsten Nachbarn zu finden. Die Eigenschaften der Nachbarn werden entweder gleichmäßig gemittelt oder durch die Entfernung zu jedem Nachbarn gewichtet. Wenn einem Beispiel ein oder mehrere Merkmale fehlen, können sich seine Nachbarn je nach den eingegebenen Merkmalen unterscheiden. Wenn die Anzahl der verfügbaren Nachbarn kleiner als n_Nachbarn ist und kein definierter Abstand zum Trainingssatz besteht, wird der Durchschnitt des Trainingssatzes für diese Funktion während der Eingabe verwendet. Wenn es mindestens einen Nachbarn mit der definierten Entfernung gibt, wird der gewichtete oder ungewichtete Durchschnitt der verbleibenden Nachbarn bei der Einreise verwendet.
n_neighbors=2
Setzen wir die Anzahl der zu berücksichtigenden Nachbarn explizit auf n_neighbors = 2.
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=2)
data7 = pd.DataFrame(imputer.fit_transform(data2))
data7
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 0.0 | 0.0 | 0.0 | 0.0 |
1 | 1.0 | 2.0 | 3.0 | 4.0 |
2 | 2.0 | 4.0 | 6.0 | 8.0 |
3 | 3.0 | 6.0 | 9.0 | 12.0 |
4 | 4.0 | 8.0 | 12.0 | 16.0 |
5 | 5.0 | 10.0 | 15.0 | 20.0 |
6 | 6.0 | 12.0 | 18.0 | 18.0 |
7 | 7.0 | 14.0 | 21.0 | 26.0 |
8 | 8.0 | 16.0 | 24.0 | 32.0 |
9 | 9.0 | 18.0 | 27.0 | 36.0 |
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(data7)
Es scheint, dass es nicht gut gefüllt werden kann, wenn es zwei Mal hintereinander fehlt.
default(n_neighbors=5)
Standardmäßig werden bis zu 5 Nachbarn berücksichtigt.
from sklearn.impute import KNNImputer
imputer = KNNImputer()
data8 = pd.DataFrame(imputer.fit_transform(data2))
data8
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 0.0 | 0.0 | 0.0 | 0.0 |
1 | 1.0 | 2.0 | 3.0 | 4.0 |
2 | 2.0 | 5.2 | 6.0 | 8.0 |
3 | 3.0 | 6.0 | 12.0 | 12.0 |
4 | 4.0 | 8.0 | 12.0 | 16.0 |
5 | 5.0 | 10.0 | 16.2 | 20.0 |
6 | 6.0 | 12.0 | 18.0 | 23.2 |
7 | 7.0 | 14.0 | 21.0 | 23.2 |
8 | 8.0 | 16.0 | 24.0 | 32.0 |
9 | 9.0 | 18.0 | 27.0 | 36.0 |
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(data8)
Die Art und Weise, Spalte D zu füllen, ist relativ besser, hat sich jedoch geringfügig negativ auf die Füllung der Spalten B und C ausgewirkt.
Es gibt wahrscheinlich keine perfekte Möglichkeit, fehlende Werte einzugeben. Berücksichtigen Sie daher die Eigenschaften Ihrer Daten und wählen Sie die suboptimale Methode!
Recommended Posts