Häufig haben Menschen, die in das Gebiet Data Science eintreten, eine unrealistische Vorstellung davon, was sie erwartet. Viele denken, dass sie jetzt großartige neuronale Netze schreiben, einen Sprachassistenten aus Iron Man erstellen oder alle an den Finanzmärkten besiegen werden.
Aber die Arbeit Daten als Scientist basiert auf Daten, und einer der wichtigsten und zeitaufwendigsten Punkte ist die Datenaufbereitung, bevor sie in ein neuronales Netz eingegeben oder auf bestimmte Weise analysiert werden.
In diesem Artikel wird unser Team beschreiben, wie man Daten einfach und schnell mit einer schrittweisen Anleitung und Code verarbeiten kann. Wir haben versucht, den Code so flexibel zu gestalten, dass er für verschiedene Datensätze verwendet werden kann.
Viele Fachleute werden vielleicht nichts Außergewöhnliches in diesem Artikel finden, aber Anfänger können etwas Neues lernen, und auch jeder, der schon lange davon träumt, ein eigenes Notebook für eine schnelle und strukturierte Datenverarbeitung zu erstellen, kann den Code kopieren und anpassen oder
Wir haben den Datensatz erhalten. Was sollen wir als Nächstes tun?
Also, der Standard: Wir müssen verstehen, womit wir es zu tun haben, das Gesamtbild. Dafür verwenden wir pandas, um einfach verschiedene Datentypen zu bestimmen.
import pandas as pd #wir importieren pandas
import numpy as np #wir importieren numpy
df = pd.read_csv("AB_NYC_2019.csv") #wir lesen den Datensatz und speichern ihn in der Variable df
df.head(3) #wir sehen uns die ersten 3 Zeilen an, um zu verstehen, wie die Werte aussehen 
df.info() #wir zeigen Informationen über die Spalten an 
Wir schauen uns die Werte der Spalten an:
- Entspricht die Anzahl der Zeilen jeder Spalte der Gesamtzahl der Zeilen?
- Was ist der Inhalt der Daten in jeder Spalte?
- Welche Spalte möchten wir als Zielspalte festlegen, um Vorhersagen dafür zu treffen?
Die Antworten auf diese Fragen ermöglichen es, den Datensatz zu analysieren und einen Plan für die nächsten Schritte zu skizzieren.
Außerdem können wir zur näheren Betrachtung der Werte in jeder Spalte die pandas-Funktion describe() verwenden. Der Nachteil dieser Funktion ist jedoch, dass sie keine Informationen über Spalten mit String-Werten gibt. Damit werden wir uns später befassen.
df.describe() 
Magische Visualisierung
Schauen wir uns an, wo uns überhaupt Werte fehlen:
import seaborn as sns
sns.heatmap(df.isnull(),yticklabels=False,cbar=False,cmap='viridis') 
Das war ein kleiner Überblick, jetzt kommen wir zu interessanteren Dingen.
Wir versuchen, Spalten zu finden und gegebenenfalls zu entfernen, in denen in allen Zeilen nur ein einziges Wert vorkommt (diese werden das Ergebnis nicht beeinflussen):
df = df[[c for c
in list(df)
if len(df[c].unique()) > 1]] #Wir schreiben den Datensatz neu und lassen nur die Spalten, in denen mehr als ein einzigartiger Wert vorhanden ist.Jetzt schützen wir uns und den Erfolg unseres Projekts vor Duplikatzeilen (Zeilen, die dieselben Informationen in derselben Reihenfolge wie eine bereits bestehende Zeile enthalten):
df.drop_duplicates(inplace=True) #Wir tun dies, wenn wir es für notwendig halten.
#In einigen Projekten sollte man solche Daten von Anfang an nicht entfernen.Wir teilen den Datensatz in zwei: einen mit qualitativen Werten und einen anderen mit quantitativen Werten.
Hier sollte eine kleine Klarstellung vorgenommen werden: Wenn die Zeilen mit fehlenden Daten in qualitativen und quantitativen Daten stark nicht miteinander in Verbindung stehen, müssen wir entscheiden, womit wir opfern — mit allen Zeilen mit fehlenden Daten, nur einem Teil davon oder bestimmten Spalten. Wenn die Zeilen jedoch in Beziehung stehen, haben wir das volle Recht, den Datensatz in zwei Teile aufzuteilen. Andernfalls müssen wir zuerst die Zeilen klären, in denen die fehlenden Daten in qualitativen und quantitativen Daten nicht übereinstimmen, und erst danach den Datensatz aufteilen.
df_numerical = df.select_dtypes(include = [np.number])
df_categorical = df.select_dtypes(exclude = [np.number])Wir tun dies, um die Bearbeitung dieser beiden unterschiedlichen Datentypen zu erleichtern — später werden wir verstehen, wie sehr das unser Leben vereinfacht.
Wir arbeiten mit quantitativen Daten.
Das erste, was wir tun sollten, ist zu bestimmen, ob es "Spion-Spalten" in den quantitativen Daten gibt. Wir nennen diese Spalten so, weil sie sich als quantitative Daten ausgeben, während sie eigentlich qualitative Daten darstellen.
Wie können wir sie identifizieren? Nun, es hängt alles von der Natur der Daten ab, die Sie analysieren, aber im Allgemeinen können solche Spalten wenige einzigartige Daten haben (im Bereich von 3-10 einzigartigen Werten).
print(df_numerical.nunique())Nachdem wir die Spion-Spalten identifiziert haben, werden wir sie aus den quantitativen Daten in die qualitativen verschieben:
spy_columns = df_numerical[['Spalte1', 'Spalte2', 'Spalte3']]#wir wählen die Spalten aus und speichern sie in einem separaten DataFrame
df_numerical.drop(labels=['Spalte1', 'Spalte2', 'Spalte3'], axis=1, inplace=True)#wir schneiden diese Spalten aus den quantitativen Daten aus
df_categorical.insert(1, 'Spalte1', spy_columns['Spalte1']) #wir fügen die erste Spalte in die qualitativen Daten ein
df_categorical.insert(1, 'Spalte2', spy_columns['Spalte2']) #wir fügen die zweite Spalte in die qualitativen Daten ein
df_categorical.insert(1, 'Spalte3', spy_columns['Spalte3']) #wir fügen die dritte Spalte in die qualitativen Daten einEndlich haben wir die quantitativen Daten vollständig von den qualitativen Daten getrennt, und jetzt können wir richtig damit arbeiten. Zuerst müssen wir verstehen, wo wir leere Werte haben (NaN, und in einigen Fällen wird auch 0 als leer betrachtet).
for i in df_numerical.columns:
print(i, df[i][df[i]==0].count())In diesem Stadium ist es wichtig, zu verstehen, in welchen Spalten Nullen fehlende Werte bedeuten könnten: hängt das mit der Art und Weise zusammen, wie die Daten gesammelt wurden? Oder könnte es mit den Werten der Daten zu tun haben? Diese Fragen müssen im Einzelfall beantwortet werden.
Wenn wir also entschieden haben, dass Daten dort fehlen können, wo es Nullen gibt, sollten wir die Nullen durch NaN ersetzen, um später leichter mit diesen fehlenden Daten arbeiten zu können:
df_numerical[["Spalte 1", "Spalte 2"]] = df_numerical[["Spalte 1", "Spalte 2"]].replace(0, nan)Jetzt schauen wir, wo bei uns Daten fehlen:
sns.heatmap(df_numerical.isnull(),yticklabels=False,cbar=False,cmap='viridis') # Man kann auch df_numerical.info() verwenden 
Hier sollten die Werte innerhalb der Spalten, die fehlen, gelb markiert sein. Und jetzt beginnt das Interessanteste – wie gehen wir mit diesen Werten um? Sollen wir die Zeilen mit diesen Werten oder die Spalten entfernen? Oder sollten wir diese leeren Werte mit irgendetwas anderem füllen?
Hier ist ein grober Plan, der Ihnen helfen kann, zu entscheiden, was man prinzipiell mit fehlenden Werten machen kann:

0. Entfernen unnötiger Spalten
df_numerical.drop(labels=["Spalte1","Spalte2"], axis=1, inplace=True)1. Ist die Anzahl der leeren Werte in dieser Spalte größer als 50%?
print(df_numerical.isnull().sum() / df_numerical.shape[0] * 100)df_numerical.drop(labels=["Spalte1","Spalte2"], axis=1, inplace=True)#Wir entfernen, wenn eine Spalte mehr als 50 leere Werte hat2. Wir entfernen Zeilen mit leeren Werten
df_numerical.dropna(inplace=True)#Entfernen Sie Zeilen mit leeren Werten, wenn genügend Daten zum Trainieren übrig bleiben3.1. Fügen Sie einen zufälligen Wert ein
import random #importiere random
df_numerical["spalte"].fillna(lambda x: random.choice(df[df[column] != np.nan]["spalte"]), inplace=True) #füge zufällige Werte in leere Zellen der Tabelle ein3.2. Fügen Sie einen konstanten Wert ein
from sklearn.impute import SimpleImputer #importiere SimpleImputer, der hilft, Werte einzufügen
imputer = SimpleImputer(strategy='constant', fill_value="") #füge einen bestimmten Wert mit SimpleImputer ein
df_numerical[["neue_spalte1",'neue_spalte2','neue_spalte3']] = imputer.fit_transform(df_numerical[['spalte1', 'spalte2', 'spalte3']]) #Wende dies auf unsere Tabelle an
df_numerical.drop(labels = ["spalte1","spalte2","spalte3"], axis = 1, inplace = True) #Entferne Spalten mit alten Werten3.3. Fügen Sie den Durchschnitt oder den am häufigsten vorkommenden Wert ein
from sklearn.impute import SimpleImputer #importiere SimpleImputer, der hilft, Werte einzufügen
imputer = SimpleImputer(strategy='mean', missing_values = np.nan) #anstatt mean kann auch most_frequent verwendet werden
df_numerical[["neue_spalte1",'neue_spalte2','neue_spalte3']] = imputer.fit_transform(df_numerical[['spalte1', 'spalte2', 'spalte3']]) #Wende dies auf unsere Tabelle an
df_numerical.drop(labels = ["spalte1","spalte2","spalte3"], axis = 1, inplace = True) #Entferne Spalten mit alten Werten3.4. Fügen Sie einen Wert ein, der von einem anderen Modell berechnet wurde
Manchmal können Werte mit Regressionsmodellen berechnet werden, indem man Modelle aus der scikit-learn-Bibliothek oder anderen ähnlichen Bibliotheken verwendet. Unser Team wird einen separaten Artikel widmen, wie dies in naher Zukunft gemacht werden kann.
So wird die Erzählung über quantitative Daten vorerst unterbrochen, da es viele andere Nuancen darüber gibt, wie man die Datenvorbereitung und -vorverarbeitung für verschiedene Aufgaben besser durchführen kann. Die grundlegenden Aspekte für quantitative Daten wurden in diesem Artikel berücksichtigt, und jetzt ist es an der Zeit, zu den qualitativen Daten zurückzukehren, die wir vor einigen Schritten von den quantitativen getrennt haben. Sie können dieses Notebook nach Belieben anpassen, um es für verschiedene Aufgaben zu optimieren, damit die Datenvorverarbeitung sehr schnell verläuft!
Qualitative Daten
Im Allgemeinen wird für qualitative Daten die Methode One-Hot-Encoding verwendet, um sie von string (oder object) in Zahlen zu formatieren. Bevor wir zu diesem Punkt übergehen, lassen Sie uns das Schema und die Codes oben verwenden, um mit fehlenden Werten umzugehen.
df_categorical.nunique()sns.heatmap(df_categorical.isnull(), yticklabels=False, cbar=False, cmap='viridis') 
0. Entfernen unnötiger Spalten
df_categorical.drop(labels=["kolonne1", "kolonne2"], axis=1, inplace=True)1. Ist die Anzahl der leeren Werte in dieser Spalte größer als 50%?
print(df_categorical.isnull().sum() / df_numerical.shape[0] * 100)df_categorical.drop(labels=["kolonne1", "kolonne2"], axis=1, inplace=True) # Entfernen, wenn eine der Spalten
# mehr als 50 % fehlende Werte hat.2. Wir entfernen Zeilen mit leeren Werten
df_categorical.dropna(inplace=True) # Entfernen Sie die Zeilen mit fehlenden Werten,
# wenn danach genügend Daten für das Training übrig bleiben.3.1. Fügen Sie einen zufälligen Wert ein
import random
df_categorical["kolonne"].fillna(lambda x: random.choice(df[df[column] != np.nan]["kolonne"]), inplace=True)3.2. Fügen Sie einen konstanten Wert ein
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='constant', fill_value="")
df_categorical[["neue_kolonne1", 'neue_kolonne2', 'neue_kolonne3']] = imputer.fit_transform(df_categorical[['kolonne1', 'kolonne2', 'kolonne3']])
df_categorical.drop(labels=["kolonne1", "kolonne2", "kolonne3"], axis=1, inplace=True)So, endlich haben wir die fehlenden Werte in den qualitativen Daten behandelt. Jetzt ist es Zeit, One-Hot-Encoding für die Werte durchzuführen, die in Ihrer Datenbank vorhanden sind. Diese Methode wird häufig verwendet, damit Ihr Algorithmus mit qualitativ hochwertigen Daten lernen kann.
def encode_and_bind(original_dataframe, feature_to_encode):
dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
res = pd.concat([original_dataframe, dummies], axis=1)
res = res.drop([feature_to_encode], axis=1)
return(res)features_to_encode = ["kolonne1", "kolonne2", "kolonne3"]
for feature in features_to_encode:
df_categorical = encode_and_bind(df_categorical, feature)So, endlich haben wir die qualitativen und quantitativen Daten separat bearbeitet – es ist Zeit, sie wieder zusammenzuführen.
new_df = pd.concat([df_numerical, df_categorical], axis=1)Nachdem wir die Datensätze in einen einzigen zusammengeführt haben, können wir die Daten mit dem MinMaxScaler aus dem sklearn-Paket transformieren. Das wird unsere Werte im Bereich von 0 bis 1 bringen, was beim zukünftigen Modelltraining hilft.
from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler()
new_df = min_max_scaler.fit_transform(new_df)Diese Daten sind jetzt bereit für alles – für neuronale Netze, Standard-ML-Algorithmen usw.!
In diesem Artikel haben wir die Verarbeitung von zeitbezogenen Daten nicht berücksichtigt, da für solche Daten etwas andere Techniken zur Verarbeitung verwendet werden sollten, abhängig von Ihrer Aufgabe. In Zukunft wird unser Team diesem Thema einen eigenen Artikel widmen, und wir hoffen, dass er Ihr Leben mit etwas Interessantem, Neuem und Nützlichem bereichern kann, so wie dieser.
Quelle: habr.com
