TensorFlow lineaire regressie met facet- en interactieterm
In deze zelfstudie leert u hoe u de gegevens kunt controleren en voorbereiden om een eenvoudige lineaire regressietaak te maken.
Deze zelfstudie is verdeeld in twee delen:
- Zoek interactie
- Test het model
In de vorige zelfstudie, je hebt de Boston-dataset gebruikt om de mediaanprijs van een huis te schatten. De Boston-dataset is klein, met slechts 506 observaties. Deze dataset wordt beschouwd als een benchmark om nieuwe lineaire regressiealgoritmen te proberen.
De dataset bestaat uit:
Veranderlijk | BESCHRIJVING |
---|---|
zn | Het aandeel woongrond dat bestemd is voor kavels groter dan 25,000 vierkante meter. |
onnodig | Het aandeel hectaren niet-detailhandel per stad. |
nox | concentratie stikstofoxiden |
rm | gemiddeld aantal kamers per woning |
leeftijd | het aandeel koopwoningen gebouwd vóór 1940 |
dis | gewogen afstanden tot vijf werkgelegenheidscentra in Boston |
belasting | onroerendgoedbelasting over de volledige waarde per dollar 10,000 |
ptratio | de leerling-leraarratio per stad |
met V | De mediaanwaarde van koopwoningen in duizend dollar |
crimineel | criminaliteit per hoofd van de bevolking per stad |
Chas | Charles River dummy variabele (1 als grensrivier; 0 anders) |
B | het aandeel zwarten per stad |
In deze tutorial schatten we de mediaanprijs met behulp van een lineaire regressor, maar de nadruk ligt op één specifiek proces van machine learning: "data voorbereiding."
Een model generaliseert het patroon in de gegevens. Om zo'n patroon vast te leggen, moet je het eerst vinden. Een goede gewoonte is om een data-analyse uit te voeren voordat u een machine learning-algoritme uitvoert.
Het kiezen van de juiste kenmerken maakt het verschil in het succes van uw model. Stel je voor dat je probeert het loon van een volk te schatten. Als je het geslacht niet als covariaat meeneemt, krijg je een slechte schatting.
Een andere manier om het model te verbeteren is door te kijken naar de correlatie tussen de onafhankelijke variabele. Terug naar het voorbeeld: je kunt onderwijs zien als een uitstekende kandidaat om het loon maar ook het beroep te voorspellen. De eerlijkheid gebiedt te zeggen dat het beroep afhankelijk is van het opleidingsniveau, namelijk dat hoger onderwijs vaak leidt tot een beter beroep. Als we dit idee generaliseren, kunnen we zeggen dat de correlatie tussen de afhankelijke variabele en een verklarende variabele kan worden vergroot door nog een andere verklarende variabele.
Om het beperkte effect van opleiding op het beroep weer te geven, kunnen we een interactieterm gebruiken.
Als je naar de loonvergelijking kijkt, wordt het:
If positief is, betekent dit dat een extra opleidingsniveau bij een hoge bezettingsgraad een hogere stijging van de mediaanwaarde van een woning oplevert. Er is met andere woorden sprake van een interactie-effect tussen opleiding en beroep.
In deze tutorial zullen we proberen te zien welke variabelen een goede kandidaat kunnen zijn voor interactietermen. We gaan testen of het toevoegen van dit soort informatie tot een betere prijsvoorspelling leidt.
Samenvattende statistieken
Er zijn een paar stappen die u kunt volgen voordat u doorgaat naar het model. Zoals eerder vermeld, is het model een generalisatie van de gegevens. De best passende praktijk is om de gegevens te begrijpen en een voorspelling te doen. Als u uw gegevens niet kent, heeft u kleine kansen om uw model te verbeteren.
Laad als eerste stap de gegevens als een Panda-dataframe en maak een trainingsset en testset.
Tips: Voor deze tutorial moet je matplotlit en seaborn geïnstalleerd hebben Python. U kunt installeren Python pakket meteen mee Jupyter. Je Zou niet doe dit
!conda install -- yes matplotlib
maar
import sys !{sys.executable} -m pip install matplotlib # Already installed !{sys.executable} -m pip install seaborn
Merk op dat deze stap niet nodig is als je matplotlib en seaborn geïnstalleerd hebt.
Matplotlib is de bibliotheek waarin u een grafiek kunt maken Python. Seaborn is een statistische visualisatiebibliotheek die bovenop matplotlib is gebouwd. Het biedt aantrekkelijke en mooie percelen.
De onderstaande code importeert de benodigde bibliotheken.
import pandas as pd from sklearn import datasets import tensorflow as tf from sklearn.datasets import load_boston import numpy as np
De bibliotheek-sklearn bevat de Boston-dataset. U kunt de API aanroepen om de gegevens te importeren.
boston = load_boston() df = pd.DataFrame(boston.data)
De naam van het object wordt opgeslagen in het object feature_names in een array.
boston.feature_names
uitgang
array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')
U kunt de kolommen hernoemen.
df.columns = boston.feature_names df['PRICE'] = boston.target df.head(2)
Je converteert de variabele CHAS als een stringvariabele en labelt deze met ja als CHAS = 1 en nee als 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
Bij panda’s is het eenvoudig om de dataset te splitsen. Je verdeelt de dataset willekeurig met 80 procent trainingsset en 20 procent testset. Pandas hebben een ingebouwde kostenfunctie om een dataframemonster te splitsen.
De eerste parameter frac is een waarde van 0 tot 1. U stelt deze in op 0.8 om willekeurig 80 procent van het dataframe te selecteren.
Met Random_state kan voor iedereen hetzelfde dataframe worden geretourneerd.
### Create train/test set df_train=df.sample(frac=0.8,random_state=200) df_test=df.drop(df_train.index)
U kunt de vorm van de gegevens achterhalen. Het zou moeten zijn:
- Treinstel: 506*0.8 = 405
- Testset: 506*0.2 = 101
print(df_train.shape, df_test.shape)
uitgang
(405, 14) (101, 14)
df_test.head(5)
uitgang
KRIMEN | ZN | INDUS | CHAS | NOX | RM | LEEFTIJD | DIS | RAD | TAX | PTRATIO | B | LSTAT | PRIJS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.00632 | 18.0 | 2.31 | geen | 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 | geen | 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 | geen | 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 | geen | 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 | geen | 0.524 | 6.172 | 96.1 | 5.9505 | 5.0 | 311.0 | 15.2 | 396.90 | 19.15 | 27.1 |
Gegevens zijn rommelig; het is vaak uit balans en bezaaid met uitschieters die de analyse en machine learning-training in de war brengen.
De eerste stap om de dataset op te schonen, is begrijpen waar deze moet worden opgeschoond. Het opschonen van een dataset kan lastig zijn, vooral op een generaliseerbare manier
Het Google Research-team heeft hiervoor een tool ontwikkeld genaamd facetten die helpen de gegevens te visualiseren en op allerlei manieren op te delen. Dit is een goed startpunt om te begrijpen hoe de dataset is ingedeeld.
Met facetten kunt u ontdekken waar de gegevens er niet helemaal uitzien zoals u denkt.
Behalve hun webapp maakt Google het eenvoudig om de toolkit in te sluiten in een Jupyter notebook.
Facetten bestaan uit twee delen:
- Overzicht facetten
- Facetten diepe duik
Overzicht facetten
Facets Overview geeft een overzicht van de dataset. Facets Overview splitst de kolommen van de data in rijen met saillante informatie die laat zien
- het percentage ontbrekende observatie
- min- en max-waarden
- statistieken zoals het gemiddelde, de mediaan en de standaarddeviatie.
- Er wordt ook een kolom toegevoegd waarin het percentage waarden wordt weergegeven dat uit nullen bestaat, wat handig is als de meeste waarden uit nullen bestaan.
- Het is mogelijk om deze distributies te zien op de testdataset en de trainingsset voor elke feature. Dit betekent dat u dubbel kunt controleren of de test een vergelijkbare distributie heeft als de trainingsdata.
Dit is op zijn minst het minimum dat moet worden gedaan vóór elke machine learning-taak. Met deze tool mist u deze cruciale stap niet en worden enkele afwijkingen benadrukt.
Facetten diepe duik
Facets Deep Dive is een coole tool. Het geeft je wat helderheid over je dataset en je kunt helemaal inzoomen om een individueel stukje data te zien. Het betekent dat je de data kunt facetteren per rij en kolom over alle features van de dataset.
We zullen deze twee tools gebruiken met de Boston-dataset.
Note: U kunt Facets Overview en Facets Deep Dive niet tegelijkertijd gebruiken. U moet eerst het notitieboekje leegmaken om het gereedschap te kunnen wisselen.
Facet installeren
Voor het grootste deel van de analyse kunt u de Facet-webapp gebruiken. In deze tutorial ziet u hoe u het kunt gebruiken binnen een Jupyter Notebook.
Allereerst moet u nbextensions installeren. Dat doet u met deze code. U kopieert en plakt de volgende code in de terminal van uw machine.
pip install jupyter_contrib_nbextensions
Direct daarna moet u de opslagplaatsen op uw computer klonen. Je hebt twee keuzes:
Optie 1) Kopieer en plak deze code in de terminal (Aanbevolen)
Als Git niet op uw computer is geïnstalleerd, ga dan naar deze URL https://git-scm.com/download/win en volg de instructie. Als je klaar bent, kun je het git-commando in de terminal voor Mac-gebruikers of Anaconda-prompt gebruiken Windows gebruiker
git clone https://github.com/PAIR-code/facets
Optie 2) Ga naar https://github.com/PAIR-code/facets en download de opslagplaatsen.
Kiest u voor de eerste optie, dan komt het bestand in uw downloadbestand terecht. U kunt het bestand laten downloaden of naar een ander pad slepen.
U kunt controleren waar Facets is opgeslagen met deze opdrachtregel:
echo `pwd`/`ls facets`
Nu u Facets hebt gevonden, moet u het installeren Jupyter Notitieboekje. U moet de werkmap instellen op het pad waar facetten zich bevinden.
Uw huidige werkmap en locatie van Facets-zip moeten hetzelfde zijn.
U moet de werkmap naar Facet verwijzen:
cd facets
Om Facetten in te installeren Jupyter, heb je twee opties. Als je hebt geïnstalleerd Jupyter met Conda voor alle gebruikers kopieert u deze code:
kan jupyter nbextension gebruiken facets-dist/ installeren
jupyter nbextension install facets-dist/
Gebruik anders:
jupyter nbextension install facets-dist/ --user
Oké, je bent er helemaal klaar voor. Laten we Facetoverzicht openen.
Overzicht
Overzicht gebruikt a Python script om de statistieken te berekenen. U moet het script generic_feature_statistics_generator importeren naar Jupyter. Maak je geen zorgen; het script bevindt zich in de facettenbestanden.
Je moet het pad lokaliseren. Het is gemakkelijk te doen. Je opent facetten, opent het bestand facets_overview en vervolgens python. Kopieer het pad
Ga daarna terug naar Jupyter, en schrijf de volgende code. Verander het pad '/Users/Thomas/facets/facets_overview/python' naar jouw pad.
# Add the facets overview python code to the python path# Add t import sys sys.path.append('/Users/Thomas/facets/facets_overview/python')
U kunt het script importeren met de onderstaande code.
from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator
In Windows wordt dezelfde code
import sys sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python") from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator
Om de featurestatistieken te berekenen, moet u de functie GenericFeatureStatistics gebruikenGenerator(), en u gebruikt het object ProtoFromDataFrames. U kunt het dataframe doorgeven aan een woordenboek. Als we bijvoorbeeld een samenvattende statistiek voor het treinstel willen maken, kunnen we de informatie in een woordenboek opslaan en deze gebruiken in het object `ProtoFromDataFrames“
-
'name': 'train', 'table': df_train
Naam is de naam van de tabel die wordt weergegeven en u gebruikt de naam van de tabel waarvoor u de samenvatting wilt berekenen. In uw voorbeeld is de tabel met de gegevens 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")
Ten slotte kopieert en plakt u de onderstaande code. De code komt rechtstreeks van GitHub. Je zou dit moeten kunnen zien:
# Display the facets overview visualization for this data# Displ from IPython.core.display import display, HTML HTML_TEMPLATE = """<link rel="import" href="/nl/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))
Diagram
Nadat u de gegevens en hun verdeling hebt gecontroleerd, kunt u een correlatiematrix uitzetten. De correlatiematrix berekent de Pearson-coëfficiënt. Deze coëfficiënt ligt tussen -1 en 1, waarbij een positieve waarde een positieve correlatie aangeeft en een negatieve waarde een negatieve correlatie.
Je bent geïnteresseerd om te zien welke variabelen een goede kandidaat kunnen zijn voor interactietermen.
## 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})
uitgang
<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518>
png
Vanuit de matrix kunt u het volgende zien:
- LSTAT
- RM
Zijn sterk gecorreleerd met PRICE. Een andere opwindende eigenschap is de sterke positieve correlatie tussen NOX en INDUS, wat betekent dat die twee variabelen in dezelfde richting bewegen. Daarnaast zijn ze ook gecorreleerd met de PRICE. DIS is ook sterk gecorreleerd met IND en NOX.
U heeft een eerste aanwijzing dat IND en NOX goede kandidaten kunnen zijn voor de onderscheppingstermijn en dat DIS ook interessant zou kunnen zijn om zich op te concentreren.
Je kunt nog een beetje dieper gaan door een paarraster uit te zetten. Het zal de correlatiekaart die u eerder hebt uitgezet, gedetailleerder illustreren.
Het paarraster is als volgt samengesteld:
- Bovenste deel: spreidingsdiagram met gepaste lijn
- Diagonaal: plot van de kerneldichtheid
- Onderste deel: plot van multivariate kerneldichtheid
U kiest de focus op vier onafhankelijke variabelen. De keuze komt overeen met de variabelen met een sterke correlatie met PRICE
- INDUS
- NOX
- RM
- LSTAT
bovendien de PRIJS.
Note dat de standaardfout standaard wordt toegevoegd aan het spreidingsdiagram.
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)
uitgang
Laten we beginnen met het bovenste gedeelte:
- Prijs is negatief gecorreleerd met INDUS, NOX en LSTAT; positief gecorreleerd met RM.
- Er is een enigszins niet-lineariteit met LSTAT en PRICE
- Er is een soort rechte lijn wanneer de prijs gelijk is aan 50. Uit de beschrijving van de dataset blijkt dat PRICE is afgekapt op de waarde 50
Diagonaal
- NOX lijkt twee clusters te hebben, één rond de 0.5 en één rond de 0.85.
Om er meer over te weten te komen, kunt u naar het onderste gedeelte kijken. De Multivariate Kernel Density is interessant in zekere zin, het kleurt waar de meeste punten zijn. Het verschil met de scatterplot tekent een waarschijnlijkheidsdichtheid, ook al is er geen punt in de dataset voor een gegeven coördinaat. Wanneer de kleur sterker is, geeft dit een hoge concentratie van punten rond dit gebied aan.
Als u de multivariate dichtheid voor INDUS en NOX controleert, ziet u de positieve correlatie en de twee clusters. Wanneer het aandeel van de industrie boven de 18 ligt, ligt de stikstofoxideconcentratie boven de 0.6.
Je kunt nadenken over het toevoegen van een interactie tussen INDUS en NOX in de lineaire relatie.
Ten slotte kunt u de tweede tool gebruiken die door Google is gemaakt, Facets Deep Dive. De interface is verdeeld in vier hoofdsecties. Het centrale gebied in het midden is een zoombare weergave van de data. Bovenaan het paneel bevindt zich het dropdownmenu waarmee u de indeling van de data kunt wijzigen om faceting, positionering en kleur te regelen. Rechts is er een gedetailleerde weergave van een specifieke rij data. Dit betekent dat u op een punt met data in de visualisatie in het midden kunt klikken om de details over dat specifieke datapunt te bekijken.
Tijdens de stap van datavisualisatie bent u geïnteresseerd in het zoeken naar de paargewijze correlatie tussen de onafhankelijke variabele op de prijs van het huis. Het omvat echter ten minste drie variabelen en 3D-plots zijn ingewikkeld om mee te werken.
Eén manier om dit probleem aan te pakken is het creëren van een categorische variabele. Dat wil zeggen, we kunnen een 2D-plot maken met een kleur van de stip. U kunt de variabele PRIJS opsplitsen in vier categorieën, waarbij elke categorie een kwartiel is (dwz 0.25, 0.5, 0.75). Je noemt deze nieuwe variabele 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 diepe duik
Om Deep Dive te openen, moet u de gegevens naar een json-indeling transformeren. Panda's als object daarvoor. U kunt to_json gebruiken na de Pandas-gegevensset.
De eerste regel code regelt de grootte van de gegevensset.
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')
Onderstaande code komt van Google GitHub. Nadat je de code hebt uitgevoerd, zou je dit moeten kunnen zien:
# Display thde Dive visualization for this data from IPython.core.display import display, HTML # Create Facets template HTML_TEMPLATE = """<link rel="import" href="/nl/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))
U bent geïnteresseerd om te zien of er een verband bestaat tussen het sectortarief, de oxideconcentratie, de afstand tot het arbeidsbureau en de prijs van het huis.
Daarvoor splitst u de gegevens eerst op per branche en kleur met het prijskwartiel:
- Selecteer facettering X en kies INDUS.
- Selecteer Weergave en kies DIS. Het kleurt de stippen met het kwartiel van de huizenprijs
hier betekenen donkere kleuren dat de afstand tot het eerste arbeidsbureau groot is.
Tot nu toe laat het opnieuw zien wat je weet: een lager industrietarief, een hogere prijs. Nu kunt u de uitsplitsing bekijken per INDUX, per NOX.
- Selecteer facet Y en kies NOX.
Nu kunt u zien dat het huis ver van het eerste jobcentrum het laagste aandeel in de industrie heeft en daarom de laagste oxideconcentratie. Als u ervoor kiest om het type weer te geven met Q_PRICE en de linkerbenedenhoek inzoomt, kunt u zien wat voor soort prijs het is.
U heeft nog een aanwijzing dat de interactie tussen IND, NOX en DIS goede kandidaten kan zijn om het model te verbeteren.
TensorFlow
In deze sectie schat u de lineaire classificator met de TensorFlow Estimators API. U gaat als volgt te werk:
- Bereid de gegevens voor
- Schat een benchmarkmodel: geen interactie
- Schat een model met interactie
Vergeet niet dat het doel van machine learning het minimaliseren van de fout is. In dit geval zal het model met de laagste gemiddelde kwadratische fout winnen. De TensorFlow-schatter berekent deze metriek automatisch.
Voorbereidingsgegevens
In de meeste gevallen moet u uw gegevens transformeren. Daarom is Facettenoverzicht fascinerend. Uit de samenvattende statistiek zag je dat er uitschieters zijn. Deze waarden zijn van invloed op de schattingen, omdat ze niet lijken op de populatie die u analyseert. Uitschieters hebben doorgaans een vertekend beeld gegeven van de resultaten. Een positieve uitbijter heeft bijvoorbeeld de neiging de coëfficiënt te overschatten.
Een goede oplossing om dit probleem aan te pakken is het standaardiseren van de variabele. Standaardisatie betekent een standaardafwijking van één en een gemiddelde van nul. Het standaardisatieproces bestaat uit twee stappen. Allereerst trekt het de gemiddelde waarde van de variabele af. Ten tweede wordt de verdeling gedeeld door de standaarddeviatie, zodat de verdeling een standaarddeviatie per eenheid heeft.
De bibliotheek sklearn is nuttig om variabelen te standaardiseren. Hiervoor kunt u de module voorbewerking met de objectschaal gebruiken.
U kunt de onderstaande functie gebruiken om een gegevensset te schalen. Houd er rekening mee dat u de labelkolom en categorische variabelen niet schaalt.
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
U kunt de functie gebruiken om de trein/testset op schaal te construeren.
df_train_scale = standardize_data(df_train) df_test_scale = standardize_data(df_test)
Basisregressie: benchmark
Allereerst train en test je een model zonder interactie. Het doel is om de prestatiemetriek van het model te zien.
De manier om het model te trainen is precies zoals in de tutorial API op hoog niveau. Je maakt gebruik van de TensorFlow schatter LinearRegressor.
Ter herinnering: u moet kiezen:
- de kenmerken die in het model moeten worden geplaatst
- transformeer de kenmerken
- construeer de lineaire regressor
- construeer de input_fn-functie
- train het model
- test het model
U gebruikt alle variabelen in de gegevensset om het model te trainen. In totaal zijn er continue variabelen op niveau en één categorische variabele
## 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']
U converteert de features naar een numerieke kolom of categorische kolom
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'])]
U maakt het model met de linearRegressor. Je bewaart het model in de map train_Boston
model = tf.estimator.LinearRegressor( model_dir="train_Boston", feature_columns=categorical_features + continuous_features)
uitgang
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}
Elke kolom in de trein- of testgegevens wordt omgezet in een Tensor met de functie get_input_fn
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)
Je schat het model op basis van de treingegevens.
model.train(input_fn=get_input_fn(df_train_scale, num_epochs=None, n_batch = 128, shuffle=False), steps=1000)
uitgang
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>
Tenslotte schat je de prestaties van het model op de testset in
model.evaluate(input_fn=get_input_fn(df_test_scale, num_epochs=1, n_batch = 128, shuffle=False), steps=1000)
uitgang
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}
Het verlies van het model is 1650. Dit is de maatstaf die in de volgende sectie moet worden overtroffen
Verbeter het model: Interactieterm
Tijdens het eerste deel van de tutorial zag je een interessante relatie tussen de variabelen. De verschillende visualisatietechnieken onthulden dat INDUS en NOS aan elkaar gekoppeld zijn en draaien om het effect op de prijs te vergroten. Niet alleen de interactie tussen INDUS en NOS beïnvloedt de prijs, maar dit effect is ook sterker wanneer het interageert met DIS.
Het is tijd om dit idee te generaliseren en te kijken of je het voorspelde model kunt verbeteren.
U moet twee nieuwe kolommen aan elke datasetset toevoegen: train + test. Daarvoor maak je één functie om de interactieterm te berekenen en een andere om de drievoudige interactieterm te berekenen. Elke functie produceert een enkele kolom. Nadat de nieuwe variabelen zijn gemaakt, kunt u deze samenvoegen met de trainingsgegevensset en de testgegevensset.
Allereerst moet u een nieuwe variabele aanmaken voor de interactie tussen INDUS en NOX.
De onderstaande functie retourneert twee dataframes, train en test, met de interactie tussen var_1 en var_2, in jouw geval INDUS en 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
U slaat de twee nieuwe kolommen op
interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS') interation_ind_ns_train.shape (325,)
Ten tweede maak je een tweede functie om de drievoudige interactieterm te berekenen.
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')
Nu u over alle benodigde kolommen beschikt, kunt u deze toevoegen aan het trainen en testen van de gegevensset. U noemt deze twee nieuwe dataframes:
- df_train_nieuw
- df_test_nieuw
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)
uitgang
Dat is het; u kunt het nieuwe model schatten met de interactietermen en zien hoe de prestatiestatistiek is.
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)
uitgang
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)
uitgang
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)
uitgang
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}
Het nieuwe verlies is 1515. Door slechts twee nieuwe variabelen toe te voegen, kon je het verlies verkleinen. Hierdoor kunt u een betere voorspelling doen dan met het benchmarkmodel.