
Dieses Jupyter Notebook stammt aus einem Vortrag von Michael Hefenbrock am “1. Smart Data und KI Tag”. Ziel ist es, Einblicke in den Analyseprozess (mit Python) zu geben.
Außerdem: Kann ich meine Daten einfach aus der Datenbank in ein Analysesystem “kippen” und bekomme sinnvolle Ergebnisse?
Einblicke in einen Datenanalyseprozess (mit Python)¶
Insbesondere: Kann ich meine Daten einfach aus der Datenbank in ein Analysesystem "kippen" und bekomme sinnvolle Ergebnisse ?¶
Usecase: Vorhersage von Preisen für Eigentumswohnungen¶
- CRIME - Kriminalitätsrate pro Block
- INDUSTRY - Anteil der Gewerbeflächen pro Block
- RIVERSIDE - Ist ein Fluss in der Nähe
- NOX - Stickoxidkonzentration (parts per 10 million)
- ROOMS - durchschnittliche Anzahl der Zimmer pro Wohnung
- AGE - Anteil der vor 1940 gebauten selbstgenutzten Einheiten
- DISTANCE - Gewichtete Entfernungen zu fünf Bostoner Arbeitsämtern
- AUTOBAHN - Index der Zugänglichkeit zu radialen Autobahnen
- TAX - Vollwertiger Grundsteuersatz pro 10.000 €
- EDUCATION - Schüler-Lehrer-Verhältnis nach Block
- LOW_STATUS - niedrigerer Status der Bevölkerung
- **PREIS** - Medianwert der Eigentumswohnungen in €
In [1]:
from utilities import *
import seaborn as sb
In [2]:
data = pd.read_csv('daten.csv', sep=';', encoding='utf-8', decimal=',')
Hier wurde die Vorgabe der Codierung von UTF-8 nicht beachtet !¶
In diesen Fällen müssen wir das richtige Encoding "raten", was zu Verzögerungen bei der Analyse führt. Außerdem ist eine automatische Verarbeitung der Daten in diesen Fällen nicht ohne manuelle intervention möglich.¶
In diesem Fall wurde das Encoding "Windows-1252" verwendet¶
In [3]:
data = pd.read_csv('daten.csv', sep=';', encoding='cp1252', decimal=',')
data.head()
Out[3]:
Nachdem die Daten geladen wurden, können wir beispielsweise den durchschnittlichen Preis und die durchschnittliche Steuer (TAX) berechnen:¶
In [4]:
data['PREIS'].mean()
Out[4]:
In [5]:
data['TAX'].mean()
In [6]:
# Entfernung des €-Zeichens und anschließende Formatierung der Werte als Zahlen (float).
data['TAX'] = data.TAX.map(lambda z : z[:-2].replace(',','.')).astype(float)
Nun kann die durchschnittliche Steuer (TAX) berechnet werden:¶
In [7]:
data['TAX'].mean()
Out[7]:
Bevor eine weitere Analyse durchgeführt wird, untersuchen wir zunächst die Daten auf Vollständigkeit der Einträge:¶
In [8]:
data.info()
Im Unterschied zu den restlichen Spalten, enhält "CRIME" nur 521 (von 527) nicht-leere Einträge.¶
In [9]:
data[data.CRIME.isnull()]
Out[9]:
Um die Daten in folgenden Verarbeiten zu können, werden die entsprechenden Reihen mit leeren Einträgen entfernt.¶
In [10]:
data = data.dropna()
data.info()
Nun sind nur noch die vollständigen Einträge (521) enthalten.¶
In [11]:
data[['PREIS', 'TAX']].hist(figsize=(20,6));
Es fällt auf, dass die Verteilung der Preise negative Einträge enthält !¶
In [12]:
data[data.PREIS < 0].head()
Out[12]:
Solche unplausiblen Einträge sind nicht untypisch und erfordern normalerweise eine Rücksprache mit dem Kunden und eine genaue Untersuchung der Ursachen.¶
Oft sind hierfür entweder Fehler bei der Datenerfassung oder eine interne Codierung (z.B. "-1" oder "9999" für fehlende Werte oder Fehlerfälle o.ä.) verantwortlich.¶
Bleiben solche Fehler unentdeckt, kann dies zu einer erheblichen Verzerrung der weiteren Berechnungen führen (siehe Durchschnittswert). Im folgenden werden wir die entsprechenden Einträge aus der Analyse ausschließen.¶
In [13]:
data = data[data.PREIS > 0]
Nun können wir noch weitere Visualisierungen der Daten erstellen (hier durch bereits vorbereitete Funktionen).¶
In [14]:
Verteilung_der_Merkmale(data)
In [15]:
# Die Korrelation der Merkmale untereinander
Korrelation(data)
In [16]:
# Zusammenhang der anderen Merkmale mit dem Preis
Merkmale_Ziel_Korrelation(data)
Modelbildung und Evaluation¶
Im Folgenden erstellen wir ein Regressionsmodell zur Vorhersage der Wohnungspreise.¶
Hierfür wird der Datensatz zur späteren Validierung der Modelle zunächst in Trainings-und Testdaten (70/30) unterteilt. Weiterhin werden die Daten standardisiert (dies ist für manche Modelle notwendig).¶
In [17]:
# Test train split
xtrain, xtest, ytrain, ytest = train_test_split(data.drop(['PREIS', 'RIVERSIDE'], axis=1),
data.PREIS, test_size=.3, random_state=1)
# Standartisierung der Daten
mean, std = xtrain.mean() , xtrain.std()
xtrain = (xtrain - mean)/std
xtest = (xtest - mean)/std
print('Größte des Trainingsets : ', xtrain.shape[0])
print('Größte des Testsets : ', xtest.shape[0])
In [18]:
# Lineares Regressionsmodell
Lineare_Regression = Regressor('LR').fit_evaluate(xtrain, xtest, ytrain, ytest, True)
In [19]:
# Gradient boosting
Gradient_Boosting = Regressor('GB').fit_evaluate(xtrain, xtest, ytrain, ytest, True)
Manche Modelle (hier: lineare Regression) ermöglichen es uns den Einfluss der Merkmale auf die Zielvariable zu beurteilen¶
In [20]:
feature_importance(Lineare_Regression, xtrain.columns)
In [21]:
feature_importance(Gradient_Boosting, xtrain.columns)
Der Status der Bevölkerung in der Wohngegend (LOW_STATUS) wird von beiden Modellen als wichtigstes Merkmal zur Vorhersage des Wohnungspreises verwendet.¶
Fazit:¶
- Standards beim Datenaustausch und der Datenverarbeitung sind notwendig !
- Datenfelder sollten einheitlich codiert werden.
- Rohdaten sind meistens nicht direkt zur Analyse und Modellbildung geeignet und müssen vorverarbeitet werden.
- Daten in ein System "kippen" und automatisch analysieren lassen funktioniert meistens nicht.
- Einer Datenanalyse und Modellbildung geht oft ein erheblicher Aufwand an Bereinigung der Daten voraus.
Anmerkungen:¶
Dieses Jupyter Notebook stammt aus einem Vortrag von Michael Hefenbrock am “1. Smart Data und KI Tag”.