TensorFlow lineare Regression mit Facetten- und Interaktionsterm
In diesem Tutorial erfahren Sie, wie Sie die Daten überprüfen und vorbereiten, um eine einfache lineare Regressionsaufgabe zu erstellen.
Dieses Tutorial ist in zwei Teile gegliedert:
- Suchen Sie nach Interaktion
- Testen Sie das Modell
Im vorheriges TutorialSie haben den Boston-Datensatz verwendet, um den mittleren Preis eines Hauses zu schätzen. Der Boston-Datensatz ist mit nur 506 Beobachtungen klein. Dieser Datensatz wird als Benchmark zum Ausprobieren neuer linearer Regressionsalgorithmen betrachtet.
Der Datensatz besteht aus:
Variable | Beschreibung |
---|---|
zn | Der Anteil an Wohngrundstücken, die für Grundstücke über 25,000 Quadratfuß in Zonen ausgewiesen sind. |
Indus | Der Anteil der Nicht-Einzelhandelsflächen pro Stadt. |
Nox | Stickoxidkonzentration |
rm | durchschnittliche Zimmeranzahl pro Wohnung |
Alter | der Anteil der Eigentumswohnungen, die vor 1940 gebaut wurden |
dis | gewichtete Entfernungen zu fünf Bostoner Arbeitsvermittlungszentren |
Steuer | Vollwert-Grundsteuersatz pro 10,000 Dollar |
ptratio | das Schüler-Lehrer-Verhältnis einer Stadt |
mit V | Der mittlere Wert von Eigenheimen in Tausend Dollar |
kriminell | Pro-Kopf-Kriminalitätsrate nach Stadt |
chas | Charles River, Dummy-Variable (1, wenn der Fluss begrenzt ist, andernfalls 0) |
B | der Anteil der Schwarzen in der Stadt |
In diesem Tutorial schätzen wir den Medianpreis mithilfe eines linearen Regressors, der Schwerpunkt liegt jedoch auf einem bestimmten Prozess Maschinelles Lernen: "Datenaufbereitung."
Ein Modell verallgemeinert das Muster in den Daten. Um ein solches Muster zu erfassen, müssen Sie es zunächst finden. Eine gute Vorgehensweise besteht darin, eine Datenanalyse durchzuführen, bevor ein Algorithmus für maschinelles Lernen ausgeführt wird.
Die Auswahl der richtigen Funktionen macht den Erfolg Ihres Modells entscheidend. Stellen Sie sich vor, Sie versuchen, den Lohn eines Volkes zu schätzen. Wenn Sie das Geschlecht nicht als Kovariate einbeziehen, erhalten Sie eine schlechte Schätzung.
Eine weitere Möglichkeit, das Modell zu verbessern, besteht darin, die Korrelation zwischen den unabhängigen Variablen zu untersuchen. Zurück zum Beispiel: Sie können sich Bildung als einen hervorragenden Kandidaten vorstellen, um das Gehalt, aber auch den Beruf vorherzusagen. Man kann mit Fug und Recht sagen, dass der Beruf vom Bildungsniveau abhängt, nämlich dass eine höhere Bildung oft zu einem besseren Beruf führt. Wenn wir diese Idee verallgemeinern, können wir sagen, dass die Korrelation zwischen der abhängigen Variablen und einer erklärenden Variablen durch eine weitere erklärende Variable vergrößert werden kann.
Um den begrenzten Effekt der Bildung auf den Beruf zu erfassen, können wir einen Interaktionsbegriff verwenden.
Wenn man sich die Lohngleichung anschaut, sieht sie so aus:
If positiv ist, bedeutet dies, dass ein zusätzliches Bildungsniveau zu einer stärkeren Steigerung des Medianwerts eines Hauses bei einem hohen Beschäftigungsgrad führt. Mit anderen Worten: Es gibt einen Interaktionseffekt zwischen Bildung und Beruf.
In diesem Tutorial werden wir versuchen herauszufinden, welche Variablen gute Kandidaten für Interaktionsterme sein können. Wir werden testen, ob das Hinzufügen dieser Art von Informationen zu einer besseren Preisvorhersage führt.
Zusammengefasste Statistiken
Es gibt einige Schritte, die Sie befolgen können, bevor Sie mit dem Modell fortfahren. Wie bereits erwähnt, handelt es sich bei dem Modell um eine Verallgemeinerung der Daten. Die beste Vorgehensweise besteht darin, die Daten zu verstehen und eine Vorhersage zu treffen. Wenn Sie Ihre Daten nicht kennen, sind die Chancen, Ihr Modell zu verbessern, gering.
Laden Sie im ersten Schritt die Daten als Pandas-Datenrahmen und erstellen Sie einen Trainingssatz und einen Testsatz.
Tipps: Für dieses Tutorial müssen Sie Matplotlit und Seaborn installiert haben in Python. Sie können installieren Python Paket im Handumdrehen mit Jupyter. Sie Sollte nicht mach das
!conda install -- yes matplotlib
aber
import sys !{sys.executable} -m pip install matplotlib # Already installed !{sys.executable} -m pip install seaborn
Beachten Sie, dass dieser Schritt nicht erforderlich ist, wenn Sie Matplotlib und Seaborn installiert haben.
Matplotlib ist die Bibliothek zum Erstellen eines Diagramms Python. Seaborn ist eine statistische Visualisierungsbibliothek, die auf Matplotlib basiert. Es bietet attraktive und schöne Grundstücke.
Der folgende Code importiert die erforderlichen Bibliotheken.
import pandas as pd from sklearn import datasets import tensorflow as tf from sklearn.datasets import load_boston import numpy as np
Die Bibliothek sklearn enthält den Boston-Datensatz. Sie können die API aufrufen, um die Daten zu importieren.
boston = load_boston() df = pd.DataFrame(boston.data)
Der Name des Features wird im Objekt feature_names in einem Array gespeichert.
boston.feature_names
Ausgang
array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')
Sie können die Spalten umbenennen.
df.columns = boston.feature_names df['PRICE'] = boston.target df.head(2)
Sie konvertieren die Variable CHAS als String-Variable und kennzeichnen sie mit Ja, wenn CHAS = 1 und Nein, wenn CHAS = 0
df['CHAS'] = df['CHAS'].map({1:'yes', 0:'no'}) df['CHAS'].head(5) 0 no 1 no 2 no 3 no 4 no Name: CHAS, dtype: object
Bei Pandas ist es einfach, den Datensatz aufzuteilen. Sie teilen den Datensatz zufällig in 80 Prozent Trainingssatz und 20 Prozent Testsatz auf. Pandas verfügen über eine integrierte Kostenfunktion zum Aufteilen einer Datenrahmenstichprobe.
Der erste Parameter frac ist ein Wert zwischen 0 und 1. Sie legen ihn auf 0.8 fest, um zufällig 80 Prozent des Datenrahmens auszuwählen.
Mit Random_state kann für alle derselbe Datenrahmen zurückgegeben werden.
### Create train/test set df_train=df.sample(frac=0.8,random_state=200) df_test=df.drop(df_train.index)
Sie können die Form der Daten ermitteln. Es sollte sein:
- Zugset: 506*0.8 = 405
- Testsatz: 506*0.2 = 101
print(df_train.shape, df_test.shape)
Ausgang
(405, 14) (101, 14)
df_test.head(5)
Ausgang
KRIMINALITÄT | ZN | INDUS | CHAS | NOX | RM | Alter | DIS | RAD | Steuer | PTRATIO | B | LSTAT | PREIS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.00632 | 18.0 | 2.31 | nicht | 0.538 | 6.575 | 65.2 | 4.0900 | 1.0 | 296.0 | 15.3 | 396.90 | 4.98 | 24.0 |
1 | 0.02731 | 0.0 | 7.07 | nicht | 0.469 | 6.421 | 78.9 | 4.9671 | 2.0 | 242.0 | 17.8 | 396.90 | 9.14 | 21.6 |
3 | 0.03237 | 0.0 | 2.18 | nicht | 0.458 | 6.998 | 45.8 | 6.0622 | 3.0 | 222.0 | 18.7 | 394.63 | 2.94 | 33.4 |
6 | 0.08829 | 12.5 | 7.87 | nicht | 0.524 | 6.012 | 66.6 | 5.5605 | 5.0 | 311.0 | 15.2 | 395.60 | 12.43 | 22.9 |
7 | 0.14455 | 12.5 | 7.87 | nicht | 0.524 | 6.172 | 96.1 | 5.9505 | 5.0 | 311.0 | 15.2 | 396.90 | 19.15 | 27.1 |
Daten sind chaotisch; Es ist oft unausgewogen und voller Ausreißerwerte, die die Analyse und das Training für maschinelles Lernen beeinträchtigen.
Der erste Schritt zur Bereinigung des Datensatzes besteht darin, zu verstehen, wo er bereinigt werden muss. Das Bereinigen eines Datensatzes kann schwierig sein, insbesondere auf verallgemeinerbare Weise
Das Google-Forschungsteam hat für diese Aufgabe ein Tool namens entwickelt Facetten die dabei helfen, die Daten zu visualisieren und auf verschiedene Arten aufzuteilen. Dies ist ein guter Ausgangspunkt, um zu verstehen, wie der Datensatz aufgebaut ist.
Mit Facetten können Sie feststellen, wo die Daten nicht ganz Ihren Vorstellungen entsprechen.
Abgesehen von der Web-App erleichtert Google die Einbettung des Toolkits in eine Jupyter Notebook.
Facetten bestehen aus zwei Teilen:
- Facettenübersicht
- Facetten Deep Dive
Facettenübersicht
Facettenübersicht gibt einen Überblick über den Datensatz. Facettenübersicht teilt die Datenspalten in Zeilen mit wichtigen Informationen auf und zeigt
- der Prozentsatz der fehlenden Beobachtung
- Min.- und Max.-Werte
- Statistiken wie Mittelwert, Median und Standardabweichung.
- Außerdem wird eine Spalte hinzugefügt, die den Prozentsatz der Werte anzeigt, die Nullen sind. Dies ist hilfreich, wenn die meisten Werte Nullen sind.
- Es ist möglich, diese Verteilungen sowohl im Testdatensatz als auch im Trainingsdatensatz für jedes Merkmal anzuzeigen. So können Sie doppelt überprüfen, ob der Test eine ähnliche Verteilung wie die Trainingsdaten aufweist.
Dies ist zumindest das Minimum, das vor jeder maschinellen Lernaufgabe erledigt werden muss. Mit diesem Tool verpassen Sie diesen entscheidenden Schritt nicht und es macht einige Auffälligkeiten deutlich.
Facetten Deep Dive
Facets Deep Dive ist ein cooles Tool. Es verschafft Ihnen Klarheit über Ihren Datensatz und ermöglicht es Ihnen, ganz hineinzuzoomen, um einzelne Datenelemente anzuzeigen. Das bedeutet, dass Sie die Daten zeilen- und spaltenweise über alle Merkmale des Datensatzes hinweg facettieren können.
Wir werden diese beiden Tools mit dem Boston-Datensatz verwenden.
Note: Sie können Facets Overview und Facets Deep Dive nicht gleichzeitig verwenden. Sie müssen zuerst das Notizbuch leeren, um das Werkzeug zu wechseln.
Facette installieren
Für die meisten Analysen können Sie die Facet-Web-App verwenden. In diesem Tutorial erfahren Sie, wie Sie es innerhalb eines verwenden Jupyter Notizbuch.
Zuerst müssen Sie nbextensions installieren. Dies geschieht mit diesem Code. Sie kopieren und fügen den folgenden Code in das Terminal Ihres Computers ein.
pip install jupyter_contrib_nbextensions
Gleich danach müssen Sie die Repositorys auf Ihrem Computer klonen. Sie haben zwei Möglichkeiten:
Option 1) Kopieren Sie diesen Code und fügen Sie ihn in das Terminal ein (Empfohlen)
Wenn Sie Git nicht auf Ihrem Computer installiert haben, rufen Sie bitte diese URL auf https://git-scm.com/download/win und befolgen Sie die Anweisungen. Sobald Sie fertig sind, können Sie den Befehl git im Terminal für Mac-Benutzer oder die Anaconda-Eingabeaufforderung verwenden Windows Benutzer
git clone https://github.com/PAIR-code/facets
Option 2) Gehen Sie zu https://github.com/PAIR-code/facets und laden Sie die Repositorys herunter.
Wenn Sie die erste Option wählen, landet die Datei in Ihrer Download-Datei. Sie können die Datei entweder herunterladen lassen oder sie auf einen anderen Pfad ziehen.
Sie können mit dieser Befehlszeile überprüfen, wo Facets gespeichert sind:
echo `pwd`/`ls facets`
Nachdem Sie Facets gefunden haben, müssen Sie es installieren Jupyter Notizbuch. Sie müssen das Arbeitsverzeichnis auf den Pfad festlegen, in dem sich Facets befindet.
Ihr aktuelles Arbeitsverzeichnis und der Speicherort der Facets-Zip-Datei sollten identisch sein.
Sie müssen das Arbeitsverzeichnis auf Facet verweisen:
cd facets
So installieren Sie Facetten in Jupyter, Sie haben zwei Möglichkeiten. Wenn Sie installiert haben Jupyter Kopieren Sie mit Conda für alle Benutzer diesen Code:
kann jupyter nbextension install facets-dist/ verwenden
jupyter nbextension install facets-dist/
Andernfalls verwenden Sie:
jupyter nbextension install facets-dist/ --user
Alles klar, Sie sind bereit. Öffnen wir die Facettenübersicht.
Übersicht
Übersicht verwendet eine Python Skript zur Berechnung der Statistiken. Sie müssen das Skript namens generic_feature_statistics_generator importieren, um Jupyter. Mach dir keine Sorge; Das Skript befindet sich in den Facets-Dateien.
Sie müssen seinen Pfad finden. Es ist leicht zu machen. Sie öffnen Facetten, öffnen die Datei facets_overview und dann Python. Kopieren Sie den Pfad
Gehen Sie danach zurück zu Jupyter, und schreiben Sie den folgenden Code. Ändern Sie den Pfad „/Users/Thomas/facets/facets_overview/python“ in Ihren Pfad.
# Add the facets overview python code to the python path# Add t import sys sys.path.append('/Users/Thomas/facets/facets_overview/python')
Sie können das Skript mit dem folgenden Code importieren.
from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator
In Windows wird derselbe Code
import sys sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python") from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator
Um die Feature-Statistiken zu berechnen, müssen Sie die Funktion GenericFeatureStatistics verwendenGenerator(), und Sie verwenden das Objekt ProtoFromDataFrames. Sie können den Datenrahmen in einem Wörterbuch übergeben. Wenn wir beispielsweise eine zusammenfassende Statistik für den Zugsatz erstellen möchten, können wir die Informationen in einem Wörterbuch speichern und im Objekt „ProtoFromDataFrames“ verwenden.
-
'name': 'train', 'table': df_train
Name ist der Name der angezeigten Tabelle, und Sie verwenden den Namen der Tabelle, für die Sie die Zusammenfassung berechnen möchten. In Ihrem Beispiel ist die Tabelle mit den Daten df_train
# Calculate the feature statistics proto from the datasets and stringify it for use in facets overview import base64 gfsg = GenericFeatureStatisticsGenerator() proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train}, {'name': 'test', 'table': df_test}]) #proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train}]) protostr = base64.b64encode(proto.SerializeToString()).decode("utf-8")
Zum Schluss kopieren Sie einfach den folgenden Code und fügen ihn ein. Der Code kommt direkt von GitHub. Sie sollten Folgendes sehen können:
# Display the facets overview visualization for this data# Displ from IPython.core.display import display, HTML HTML_TEMPLATE = """<link rel="import" href="/de/nbextensions/facets-dist/facets-jupyter.html" > <facets-overview id="elem"></facets-overview> <script> document.querySelector("#elem").protoInput = "{protostr}"; </script>""" html = HTML_TEMPLATE.format(protostr=protostr) display(HTML(html))
Graph
Nachdem Sie die Daten und ihre Verteilung überprüft haben, können Sie eine Korrelationsmatrix zeichnen. Die Korrelationsmatrix berechnet den Pearson-Koeffizienten. Dieser Koeffizient liegt zwischen -1 und 1, wobei ein positiver Wert eine positive Korrelation und ein negativer Wert eine negative Korrelation anzeigt.
Sie möchten wissen, welche Variablen gute Kandidaten für Interaktionsterme sein können.
## Choose important feature and further check with Dive %matplotlib inline import matplotlib.pyplot as plt import seaborn as sns sns.set(style="ticks") # Compute the correlation matrix corr = df.corr('pearson') # Generate a mask for the upper triangle mask = np.zeros_like(corr, dtype=np.bool) mask[np.triu_indices_from(mask)] = True # Set up the matplotlib figure f, ax = plt.subplots(figsize=(11, 9)) # Generate a custom diverging colormap cmap = sns.diverging_palette(220, 10, as_cmap=True) # Draw the heatmap with the mask and correct aspect ratio sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,annot=True, square=True, linewidths=.5, cbar_kws={"shrink": .5})
Ausgang
<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518>
png
Aus der Matrix können Sie Folgendes erkennen:
- LSTAT
- RM
Sind stark mit dem PREIS korreliert. Ein weiteres spannendes Merkmal ist die starke positive Korrelation zwischen NOX und INDUS, was bedeutet, dass sich diese beiden Variablen in die gleiche Richtung bewegen. Außerdem sind sie auch mit dem PREIS korreliert. DIS ist auch stark mit IND und NOX korreliert.
Sie haben einen ersten Hinweis darauf, dass IND und NOX gute Kandidaten für den Intercept-Term sein können und dass es auch interessant sein könnte, sich auf DIS zu konzentrieren.
Sie können etwas tiefer gehen, indem Sie ein Paargitter zeichnen. Es wird die Korrelationskarte, die Sie zuvor erstellt haben, detaillierter veranschaulichen.
Das Paargitter setzt sich wie folgt zusammen:
- Oberer Teil: Streudiagramm mit angepasster Linie
- Diagonale: Diagramm der Kerndichte
- Unterer Teil: Multivariates Kerndichtediagramm
Sie wählen den Fokus auf vier unabhängige Variablen. Die Auswahl entspricht den Variablen mit starker Korrelation mit PREIS
- INDUS
- NOX
- RM
- LSTAT
außerdem der PREIS.
Note dass der Standardfehler standardmäßig zum Streudiagramm hinzugefügt wird.
attributes = ["PRICE", "INDUS", "NOX", "RM", "LSTAT"] g = sns.PairGrid(df[attributes]) g = g.map_upper(sns.regplot, color="g") g = g.map_lower(sns.kdeplot,cmap="Reds", shade=True, shade_lowest=False) g = g.map_diag(sns.kdeplot)
Ausgang
Beginnen wir mit dem oberen Teil:
- Der Preis korreliert negativ mit INDUS, NOX und LSTAT; positiv mit RM korreliert.
- Bei LSTAT und PRICE besteht eine leichte Nichtlinearität
- Wenn der Preis 50 beträgt, sieht es wie eine gerade Linie aus. In der Beschreibung des Datensatzes wurde PRICE auf den Wert 50 gekürzt
Diagonale
- NOX scheint zwei Cluster zu haben, einen um 0.5 und einen um 0.85.
Um mehr darüber zu erfahren, können Sie sich den unteren Teil ansehen. Die multivariate Kerneldichte ist insofern interessant, als sie dort einfärbt, wo sich die meisten Punkte befinden. Der Unterschied zum Streudiagramm ergibt eine Wahrscheinlichkeitsdichte, obwohl es für eine bestimmte Koordinate keinen Punkt im Datensatz gibt. Wenn die Farbe kräftiger ist, weist dies auf eine hohe Konzentration von Punkten um diesen Bereich herum hin.
Wenn Sie die multivariante Dichte für INDUS und NOX überprüfen, können Sie die positive Korrelation und die beiden Cluster sehen. Wenn der Anteil der Industrie über 18 liegt, liegt die Stickoxidkonzentration über 0.6.
Sie können darüber nachdenken, eine Interaktion zwischen INDUS und NOX in die lineare Beziehung aufzunehmen.
Schließlich können Sie das zweite von Google erstellte Tool verwenden, Facets Deep Dive. Die Benutzeroberfläche ist in vier Hauptabschnitte unterteilt. Der zentrale Bereich in der Mitte ist eine zoombare Anzeige der Daten. Oben im Bedienfeld befindet sich das Dropdown-Menü, in dem Sie die Anordnung der Daten ändern können, um Facettierung, Positionierung und Farbe zu steuern. Auf der rechten Seite befindet sich eine Detailansicht einer bestimmten Datenzeile. Das bedeutet, dass Sie auf einen beliebigen Datenpunkt in der zentralen Visualisierung klicken können, um die Details zu diesem bestimmten Datenpunkt anzuzeigen.
Während des Datenvisualisierungsschritts möchten Sie nach der paarweisen Korrelation zwischen der unabhängigen Variable und dem Hauspreis suchen. Allerdings sind dafür mindestens drei Variablen erforderlich und die Arbeit mit 3D-Diagrammen ist kompliziert.
Eine Möglichkeit, dieses Problem anzugehen, besteht darin, eine kategoriale Variable zu erstellen. Das heißt, wir können ein 2D-Diagramm mit einer Farbe für den Punkt erstellen. Sie können die Variable PREIS in vier Kategorien aufteilen, wobei jede Kategorie ein Quartil ist (dh 0.25, 0.5, 0.75). Sie nennen diese neue Variable Q_PRICE.
## Check non linearity with important features df['Q_PRICE'] = pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"]) ## Show non linearity between RM and LSTAT ax = sns.lmplot(x="DIS", y="INDUS", hue="Q_PRICE", data=df, fit_reg = False,palette="Set3")
Facetten Deep Dive
Um Deep Dive zu öffnen, müssen Sie die Daten in ein JSON-Format umwandeln. Pandas als Objekt dafür. Sie können to_json nach dem Pandas-Datensatz verwenden.
Die erste Codezeile behandelt die Größe des Datensatzes.
df['Q_PRICE'] = pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"]) sprite_size = 32 if len(df.index)>50000 else 64 jsonstr = df.to_json(orient='records')
Der folgende Code stammt von Google GitHub. Nachdem Sie den Code ausgeführt haben, sollten Sie Folgendes sehen können:
# Display thde Dive visualization for this data from IPython.core.display import display, HTML # Create Facets template HTML_TEMPLATE = """<link rel="import" href="/de/nbextensions/facets-dist/facets-jupyter.html"> <facets-dive sprite-image-width="{sprite_size}" sprite-image-height="{sprite_size}" id="elem" height="600"></facets-dive> <script> document.querySelector("#elem").data = {jsonstr}; </script>""" # Load the json dataset and the sprite_size into the template html = HTML_TEMPLATE.format(jsonstr=jsonstr, sprite_size=sprite_size) # Display the template display(HTML(html))
Es interessiert Sie, ob ein Zusammenhang zwischen Branchentarif, Oxidkonzentration, Entfernung zum Jobcenter und dem Hauspreis besteht.
Dazu teilen Sie die Daten zunächst nach Branchenbereich und Farbe mit dem Preisquartil auf:
- Wählen Sie Facettierung X und wählen Sie INDUS.
- Wählen Sie „Anzeige“ und dann „DIS“. Die Punkte werden mit dem Quartil des Hauspreises gefärbt
Dunklere Farben bedeuten hier, dass die Entfernung zum ersten Jobcenter weit ist.
Bisher zeigt es wieder, was Sie wissen: niedrigerer Branchentarif, höherer Preis. Jetzt können Sie sich die Aufschlüsselung nach INDUX und NOX ansehen.
- Wählen Sie Facettierung Y und wählen Sie NOX.
Jetzt können Sie sehen, dass das Haus am weitesten vom ersten Jobcenter entfernt den niedrigsten Industrieanteil und damit die niedrigste Oxidkonzentration hat. Wenn Sie den Typ mit Q_PRICE anzeigen und in die untere linke Ecke zoomen, können Sie sehen, um welchen Preistyp es sich handelt.
Sie haben einen weiteren Hinweis darauf, dass die Interaktion zwischen IND, NOX und DIS gute Kandidaten für die Verbesserung des Modells sein kann.
TensorFlow
In diesem Abschnitt schätzen Sie den linearen Klassifikator mit der TensorFlow-Schätzer-API. Sie gehen wie folgt vor:
- Bereiten Sie die Daten vor
- Schätzen Sie ein Benchmark-Modell: Keine Interaktion
- Schätzen Sie ein Modell mit Interaktion
Denken Sie daran, dass das Ziel des maschinellen Lernens darin besteht, Fehler zu minimieren. In diesem Fall gewinnt das Modell mit dem niedrigsten mittleren quadratischen Fehler. Der TensorFlow-Schätzer berechnet diese Metrik automatisch.
Vorbereitungsdaten
In den meisten Fällen müssen Sie Ihre Daten transformieren. Deshalb ist Facets Overview faszinierend. Anhand der zusammenfassenden Statistik haben Sie gesehen, dass es Ausreißer gibt. Diese Werte wirken sich auf die Schätzungen aus, da sie nicht mit der von Ihnen analysierten Grundgesamtheit übereinstimmen. Ausreißer verzerrten normalerweise die Ergebnisse. Beispielsweise neigt ein positiver Ausreißer dazu, den Koeffizienten zu überschätzen.
Eine gute Lösung zur Bewältigung dieses Problems besteht darin, die Variable zu standardisieren. Unter Standardisierung versteht man eine Standardabweichung von eins und einen Mittelwert von null. Der Standardisierungsprozess umfasst zwei Schritte. Zunächst wird der Mittelwert der Variablen subtrahiert. Zweitens wird durch die Standardabweichung dividiert, sodass die Verteilung eine Einheitsstandardabweichung aufweist.
Die Bibliothek sklearn ist hilfreich, um Variablen zu standardisieren. Hierzu können Sie das Modul Vorverarbeitung mit der Objektskala nutzen.
Mit der folgenden Funktion können Sie einen Datensatz skalieren. Beachten Sie, dass Sie die Beschriftungsspalte und die kategorialen Variablen nicht skalieren.
from sklearn import preprocessing def standardize_data(df): X_scaled = preprocessing.scale(df[['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']]) X_scaled_df = pd.DataFrame(X_scaled, columns = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']) df_scale = pd.concat([X_scaled_df, df['CHAS'], df['PRICE']],axis=1, join='inner') return df_scale
Sie können die Funktion verwenden, um den skalierten Zug-/Testsatz zu erstellen.
df_train_scale = standardize_data(df_train) df_test_scale = standardize_data(df_test)
Grundlegende Regression: Benchmark
Zunächst trainieren und testen Sie ein Modell ohne Interaktion. Der Zweck besteht darin, die Leistungsmetrik des Modells anzuzeigen.
Die Methode zum Trainieren des Modells entspricht genau der Anleitung im Tutorial High-Level-API. Sie verwenden den TensorFlow-Schätzer LinearRegressor.
Zur Erinnerung: Sie müssen Folgendes auswählen:
- die Funktionen, die in das Modell eingefügt werden sollen
- Verwandeln Sie die Funktionen
- Konstruieren Sie den linearen Regressor
- Konstruieren Sie die Funktion input_fn
- Trainieren Sie das Modell
- Testen Sie das Modell
Sie verwenden alle Variablen im Datensatz, um das Modell zu trainieren. Insgesamt gibt es kontinuierliche Variablen auf gleicher Ebene und eine kategoriale Variable
## Add features to the bucket: ### Define continuous list CONTI_FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'] CATE_FEATURES = ['CHAS']
Sie konvertieren die Features in eine numerische Spalte oder eine kategoriale Spalte
continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES] #categorical_features = tf.feature_column.categorical_column_with_hash_bucket(CATE_FEATURES, hash_bucket_size=1000) categorical_features = [tf.feature_column.categorical_column_with_vocabulary_list('CHAS', ['yes','no'])]
Sie erstellen das Modell mit dem linearRegressor. Sie speichern das Modell im Ordner train_Boston
model = tf.estimator.LinearRegressor( model_dir="train_Boston", feature_columns=categorical_features + continuous_features)
Ausgang
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train_Boston', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a19e76ac8>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
Jede Spalte in den Zug- oder Testdaten wird mit der Funktion get_input_fn in einen Tensor umgewandelt
FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT', 'CHAS'] LABEL= 'PRICE' def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True): return tf.estimator.inputs.pandas_input_fn( x=pd.DataFrame({k: data_set[k].values for k in FEATURES}), y = pd.Series(data_set[LABEL].values), batch_size=n_batch, num_epochs=num_epochs, shuffle=shuffle)
Sie schätzen das Modell anhand der Zugdaten.
model.train(input_fn=get_input_fn(df_train_scale, num_epochs=None, n_batch = 128, shuffle=False), steps=1000)
Ausgang
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train_Boston/model.ckpt. INFO:tensorflow:loss = 56417.703, step = 1 INFO:tensorflow:global_step/sec: 144.457 INFO:tensorflow:loss = 76982.734, step = 101 (0.697 sec) INFO:tensorflow:global_step/sec: 258.392 INFO:tensorflow:loss = 21246.334, step = 201 (0.383 sec) INFO:tensorflow:global_step/sec: 227.998 INFO:tensorflow:loss = 30534.78, step = 301 (0.439 sec) INFO:tensorflow:global_step/sec: 210.739 INFO:tensorflow:loss = 36794.5, step = 401 (0.477 sec) INFO:tensorflow:global_step/sec: 234.237 INFO:tensorflow:loss = 8562.981, step = 501 (0.425 sec) INFO:tensorflow:global_step/sec: 238.1 INFO:tensorflow:loss = 34465.08, step = 601 (0.420 sec) INFO:tensorflow:global_step/sec: 237.934 INFO:tensorflow:loss = 12241.709, step = 701 (0.420 sec) INFO:tensorflow:global_step/sec: 220.687 INFO:tensorflow:loss = 11019.228, step = 801 (0.453 sec) INFO:tensorflow:global_step/sec: 232.702 INFO:tensorflow:loss = 24049.678, step = 901 (0.432 sec) INFO:tensorflow:Saving checkpoints for 1000 into train_Boston/model.ckpt. INFO:tensorflow:Loss for final step: 23228.568. <tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a19e76320>
Abschließend schätzen Sie die Leistung des Modells auf dem Testsatz ab
model.evaluate(input_fn=get_input_fn(df_test_scale, num_epochs=1, n_batch = 128, shuffle=False), steps=1000)
Ausgang
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-29-02:40:43 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train_Boston/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-29-02:40:43 INFO:tensorflow:Saving dict for global step 1000: average_loss = 86.89361, global_step = 1000, loss = 1650.9785 {'average_loss': 86.89361, 'global_step': 1000, 'loss': 1650.9785}
Der Verlust des Modells beträgt 1650. Dies ist die Metrik, die es im nächsten Abschnitt zu schlagen gilt
Verbessern Sie das Modell: Interaktionsterm
Im ersten Teil des Tutorials haben Sie eine interessante Beziehung zwischen den Variablen gesehen. Die verschiedenen Visualisierungstechniken haben gezeigt, dass INDUS und NOS miteinander verknüpft sind und den Effekt auf den Preis verstärken. Nicht nur die Interaktion zwischen INDUS und NOS beeinflusst den Preis, sondern dieser Effekt ist auch stärker, wenn sie mit DIS interagiert.
Es ist an der Zeit, diese Idee zu verallgemeinern und zu prüfen, ob Sie das vorhergesagte Modell verbessern können.
Sie müssen jedem Datensatzsatz zwei neue Spalten hinzufügen: Train + Test. Dazu erstellen Sie eine Funktion zur Berechnung des Interaktionsterms und eine weitere zur Berechnung des dreifachen Interaktionsterms. Jede Funktion erzeugt eine einzelne Spalte. Nachdem die neuen Variablen erstellt wurden, können Sie sie mit dem Trainingsdatensatz und dem Testdatensatz verketten.
Zunächst müssen Sie eine neue Variable für das Zusammenspiel zwischen INDUS und NOX erstellen.
Die folgende Funktion gibt zwei Datenrahmen zurück, Train und Test, mit der Interaktion zwischen var_1 und var_2, in Ihrem Fall INDUS und NOX.
def interaction_term(var_1, var_2, name): t_train = df_train_scale[var_1]*df_train_scale[var_2] train = t_train.rename(name) t_test = df_test_scale[var_1]*df_test_scale[var_2] test = t_test.rename(name) return train, test
Sie speichern die beiden neuen Spalten
interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS') interation_ind_ns_train.shape (325,)
Zweitens erstellen Sie eine zweite Funktion, um den Term der dreifachen Interaktion zu berechnen.
def triple_interaction_term(var_1, var_2,var_3, name): t_train = df_train_scale[var_1]*df_train_scale[var_2]*df_train_scale[var_3] train = t_train.rename(name) t_test = df_test_scale[var_1]*df_test_scale[var_2]*df_test_scale[var_3] test = t_test.rename(name) return train, test interation_ind_ns_dis_train, interation_ind_ns_dis_test= triple_interaction_term('INDUS', 'NOX', 'DIS','INDUS_NOS_DIS')
Nachdem Sie nun über alle benötigten Spalten verfügen, können Sie diese zum Trainings- und Testdatensatz hinzufügen. Sie benennen diese beiden neuen Datenrahmen:
- df_train_new
- df_test_new
df_train_new = pd.concat([df_train_scale, interation_ind_ns_train, interation_ind_ns_dis_train], axis=1, join='inner') df_test_new = pd.concat([df_test_scale, interation_ind_ns_test, interation_ind_ns_dis_test], axis=1, join='inner') df_train_new.head(5)
Ausgang
Das ist es; Sie können das neue Modell anhand der Interaktionsterme abschätzen und sehen, wie die Leistungsmetrik ist.
CONTI_FEATURES_NEW = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT', 'INDUS_NOS', 'INDUS_NOS_DIS'] ### Define categorical list continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW] model = tf.estimator.LinearRegressor( model_dir="train_Boston_1", feature_columns= categorical_features + continuous_features_new)
Ausgang
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train_Boston_1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a1a5d5860>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
CODE
FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT','INDUS_NOS', 'INDUS_NOS_DIS','CHAS'] LABEL= 'PRICE' def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True): return tf.estimator.inputs.pandas_input_fn( x=pd.DataFrame({k: data_set[k].values for k in FEATURES}), y = pd.Series(data_set[LABEL].values), batch_size=n_batch, num_epochs=num_epochs, shuffle=shuffle)
model.train(input_fn=get_input_fn(df_train_new, num_epochs=None, n_batch = 128, shuffle=False), steps=1000)
Ausgang
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train_Boston_1/model.ckpt. INFO:tensorflow:loss = 56417.703, step = 1 INFO:tensorflow:global_step/sec: 124.844 INFO:tensorflow:loss = 65522.3, step = 101 (0.803 sec) INFO:tensorflow:global_step/sec: 182.704 INFO:tensorflow:loss = 15384.148, step = 201 (0.549 sec) INFO:tensorflow:global_step/sec: 208.189 INFO:tensorflow:loss = 22020.305, step = 301 (0.482 sec) INFO:tensorflow:global_step/sec: 213.855 INFO:tensorflow:loss = 28208.812, step = 401 (0.468 sec) INFO:tensorflow:global_step/sec: 209.758 INFO:tensorflow:loss = 7606.877, step = 501 (0.473 sec) INFO:tensorflow:global_step/sec: 196.618 INFO:tensorflow:loss = 26679.76, step = 601 (0.514 sec) INFO:tensorflow:global_step/sec: 196.472 INFO:tensorflow:loss = 11377.163, step = 701 (0.504 sec) INFO:tensorflow:global_step/sec: 172.82 INFO:tensorflow:loss = 8592.07, step = 801 (0.578 sec) INFO:tensorflow:global_step/sec: 168.916 INFO:tensorflow:loss = 19878.56, step = 901 (0.592 sec) INFO:tensorflow:Saving checkpoints for 1000 into train_Boston_1/model.ckpt. INFO:tensorflow:Loss for final step: 19598.387. <tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a1a5d5e10>
model.evaluate(input_fn=get_input_fn(df_test_new, num_epochs=1, n_batch = 128, shuffle=False), steps=1000)
Ausgang
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-29-02:41:14 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train_Boston_1/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-29-02:41:14 INFO:tensorflow:Saving dict for global step 1000: average_loss = 79.78876, global_step = 1000, loss = 1515.9863 {'average_loss': 79.78876, 'global_step': 1000, 'loss': 1515.9863}
Der neue Verlust beträgt 1515. Allein durch das Hinzufügen zweier neuer Variablen konnten Sie den Verlust verringern. Dies bedeutet, dass Sie eine bessere Vorhersage treffen können als mit dem Benchmark-Modell.