TensorFlow lineær regression med facet- og interaktionsterm

I denne øvelse lærer du, hvordan du kontrollerer dataene og forbereder dem til at lave en simpel lineær regressionsopgave.

Denne tutorial er opdelt i to dele:

  • Se efter interaktion
  • Test modellen

I tidligere vejledning, brugte du Boston-datasættet til at estimere medianprisen for et hus. Boston-datasættet har en lille størrelse med kun 506 observationer. Dette datasæt betragtes som et benchmark for at prøve nye lineære regressionsalgoritmer.

Datasættet er sammensat af:

Variabel Description
zn Andelen af ​​boligarealer udlagt til grunde over 25,000 kvm.
indu Andelen af ​​ikke-detailvirksomheder pr. by.
nox koncentration af nitrogenoxider
rm gennemsnitligt antal værelser pr. bolig
alder andelen af ​​ejerlejligheder bygget før 1940
dis vægtede afstande til fem Boston beskæftigelsescentre
skat ejendomsskattesats for fuld værdi pr. dollars 10,000
ptratio elev-lærer-forholdet i en by
medv Medianværdien af ​​ejerboliger i tusinde dollars
kriminel kriminalitet pr. indbygger efter by
Chas Charles River dummy-variabel (1 hvis grænser til floden; ellers 0)
B andelen af ​​sorte i byen

I denne vejledning vil vi estimere medianprisen ved hjælp af en lineær regressor, men fokus er på en bestemt proces med machine learning: "dataforberedelse."

En model generaliserer mønstret i dataene. For at fange et sådant mønster skal du først finde det. En god praksis er at udføre en dataanalyse, før du kører nogen maskinlæringsalgoritme.

At vælge de rigtige funktioner gør hele forskellen for din models succes. Forestil dig, at du forsøger at estimere et folks løn, hvis du ikke inkluderer kønnet som en kovariat, ender du med et dårligt skøn.

En anden måde at forbedre modellen på er at se på sammenhængen mellem den uafhængige variabel. Tilbage til eksemplet kan du tænke på uddannelse som en fremragende kandidat til at forudsige lønnen, men også erhvervet. Det er rimeligt at sige, at erhvervet afhænger af uddannelsesniveauet, nemlig videregående uddannelse fører ofte til et bedre erhverv. Hvis vi generaliserer denne idé, kan vi sige, at korrelationen mellem den afhængige variabel og en forklarende variabel kan forstørres af endnu en forklarende variabel.

For at fange uddannelsens begrænsede effekt på erhverv kan vi bruge et interaktionsbegreb.

Interaktionsperiode

Hvis du ser på lønligningen, bliver den:

Interaktionsperiode

If Interaktionsperiode er positivt, så indebærer det, at et ekstra uddannelsesniveau giver en højere stigning i medianværdien af ​​et hus for et højt besættelsesniveau. Der er med andre ord en vekselvirkning mellem uddannelse og erhverv.

I denne tutorial vil vi forsøge at se, hvilke variabler der kan være en god kandidat til interaktionsudtryk. Vi vil teste, om tilføjelse af denne form for information fører til bedre prisforudsigelse.

Sammenfattende statistik

Der er et par trin, du kan følge, før du fortsætter til modellen. Som tidligere nævnt er modellen en generalisering af dataene. Den bedste praksis er at forstå dataene og lave en forudsigelse. Hvis du ikke kender dine data, har du små chancer for at forbedre din model.

Som et første trin skal du indlæse dataene som en panda-dataramme og oprette et træningssæt og testsæt.

Tip: Til denne tutorial skal du have matplotlit og seaborn installeret i Python. Du kan installere Python pakke i farten med Jupyter. Du Burde ikke gør dette

!conda install -- yes matplotlib

men

import sys
!{sys.executable} -m pip install matplotlib # Already installed
!{sys.executable} -m pip install seaborn 

Bemærk, at dette trin ikke er nødvendigt, hvis du har installeret matplotlib og seaborn.

Matplotlib er biblioteket til at lave en graf i Python. Seaborn er et statistisk visualiseringsbibliotek bygget oven på matplotlib. Det giver attraktive og smukke grunde.

Koden nedenfor importerer de nødvendige biblioteker.

import pandas as pd
from sklearn import datasets
import tensorflow as tf
from sklearn.datasets import load_boston
import numpy as np

Biblioteket sklearn inkluderer Boston-datasættet. Du kan kalde dens API for at importere dataene.

boston = load_boston()
df = pd.DataFrame(boston.data)

Funktionens navn gemmes i objektet feature_names i en matrix.

boston.feature_names

Produktion

array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')

Du kan omdøbe kolonnerne.

df.columns = boston.feature_names
df['PRICE'] = boston.target
df.head(2)

Lineær regression med facet og interaktionsled

Du konverterer variablen CHAS som en strengvariabel og mærker den med ja hvis CHAS = 1 og nej hvis 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

Med pandaer er det ligetil at opdele datasættet. Du opdeler tilfældigt datasættet med 80 procent træningssæt og 20 procent testsæt. pandas har en indbygget omkostningsfunktion til at opdele en datarammeprøve.

Den første parameter frac er en værdi fra 0 til 1. Du indstiller den til 0.8 for at vælge tilfældigt 80 procent af datarammen.

Random_state gør det muligt at få den samme dataramme returneret for alle.

### Create train/test set
df_train=df.sample(frac=0.8,random_state=200)
df_test=df.drop(df_train.index)

Du kan få formen på dataene. Det bør være:

  • Togsæt: 506*0.8 = 405
  • Testsæt: 506*0.2 = 101
print(df_train.shape, df_test.shape)

Produktion

(405, 14) (101, 14)
df_test.head(5)

Produktion

CRIM ZN INDUS CHAS NOX RM ALDER DIS RAD SKAT PTRATIO B LSTAT PRIS
0 0.00632 18.0 2.31 ingen 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 ingen 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 ingen 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 ingen 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 ingen 0.524 6.172 96.1 5.9505 5.0 311.0 15.2 396.90 19.15 27.1

Data er rodet; det er ofte misbalanceret og overstrøet med afvigende værdier, der afslører analyse- og maskinlæringstræningen.

Det første skridt til at få ryddet op i datasættet er at forstå, hvor det skal renses. Det kan være vanskeligt at rydde op i et datasæt, især på enhver generaliserbar måde

Google Research-teamet har udviklet et værktøj til dette job kaldet facetter der hjælper med at visualisere dataene og skære dem på alle mulige måder. Dette er et godt udgangspunkt for at forstå, hvordan datasættet er lagt op.

Facetter giver dig mulighed for at finde, hvor dataene ikke helt ser ud, som du tænker.

Bortset fra deres webapp gør Google det nemt at integrere værktøjssættet i en Jupyter notesbog.

Der er to dele til Facetter:

  • Oversigt over facetter
  • Facetter Deep Dive

Oversigt over facetter

Oversigt over facetter giver et overblik over datasættet. Oversigt over facetter opdeler kolonnerne med dataene i rækker med fremtrædende information, der vises

  1. procentdelen af ​​manglende observation
  2. min og max værdier
  3. statistik som middelværdi, median og standardafvigelse.
  4. Det tilføjer også en kolonne, der viser procentdelen af ​​værdier, der er nuller, hvilket er nyttigt, når de fleste af værdierne er nuller.
  5. Det er muligt at se disse distributioner på testdatasættet samt træningssættet for hver funktion. Det betyder, at du kan dobbelttjekke, at testen har en lignende fordeling som træningsdataene.

Dette er i det mindste minimum at gøre før enhver maskinlæringsopgave. Med dette værktøj går du ikke glip af dette afgørende trin, og det fremhæver nogle abnormiteter.

Facetter Deep Dive

Facets Deep Dive er et fedt værktøj. Det giver mulighed for at have en vis klarhed på dit datasæt og zoome helt ind for at se et individuelt stykke data. Det betyder, at du kan facettere dataene efter række og kolonne på tværs af alle funktionerne i datasættet.

Vi vil bruge disse to værktøjer med Boston-datasættet.

Bemærk: Du kan ikke bruge Facets Overview og Facets Deep Dive på samme tid. Du skal først rydde notesbogen for at skifte værktøj.

Installer Facet

Du kan bruge Facet-webappen til det meste af analysen. I denne tutorial vil du se, hvordan du bruger den inden for en Jupyter Notebook.

Først og fremmest skal du installere nbextensions. Det gøres med denne kode. Du kopierer og indsætter følgende kode i terminalen på din maskine.

pip install jupyter_contrib_nbextensions

Lige derefter skal du klone lagrene på din computer. Du har to valg:

Mulighed 1) Kopiér og indsæt denne kode i terminalen (Anbefalede)

Hvis du ikke har Git installeret på din maskine, skal du gå til denne URL https://git-scm.com/download/win og følg instruktionen. Når du er færdig, kan du bruge git-kommandoen i terminalen til Mac-bruger eller Anaconda-prompten Windows bruger

git clone https://github.com/PAIR-code/facets

Mulighed 2) Gå til https://github.com/PAIR-code/facets og download arkiverne.

Installer Facet

Hvis du vælger den første mulighed, ender filen i din downloadfil. Du kan enten lade filen downloade eller trække den til en anden sti.

Du kan kontrollere, hvor facetter er gemt med denne kommandolinje:

echo `pwd`/`ls facets`

Nu hvor du har fundet Facets, skal du installere det i Jupyter Notesbog. Du skal indstille arbejdsmappen til stien, hvor facetter er placeret.

Din nuværende arbejdsmappe og placering af Facets zip skal være den samme.

Installer Facet

Du skal pege arbejdsbiblioteket til Facet:

cd facets

For at installere Facets i Jupyter, du har to muligheder. Hvis du har installeret Jupyter med Conda for alle brugerne, kopier denne kode:

kan bruge jupyter nbextension install facets-dist/

jupyter nbextension install facets-dist/

Ellers brug:

jupyter nbextension install facets-dist/ --user

Okay, du er klar. Lad os åbne Facet Oversigt.

Oversigt

Oversigt bruger en Python script til at beregne statistikken. Du skal importere scriptet kaldet generic_feature_statistics_generator til Jupyter. Bare rolig; scriptet er placeret i facetfilerne.

Du skal finde dens vej. Det er nemt gjort. Du åbner facetter, åbner filen facets_overview og derefter python. Kopier stien

Oversigt Facet

Gå derefter tilbage til Jupyter, og skriv følgende kode. Skift stien '/Users/Thomas/facets/facets_overview/python' til din sti.

# Add the facets overview python code to the python path# Add t 
import sys
sys.path.append('/Users/Thomas/facets/facets_overview/python')

Du kan importere scriptet med koden nedenfor.

from generic_feature_statistics_generator import 
GenericFeatureStatisticsGenerator

I windows bliver den samme kode

import sys
sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python")

from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator

For at beregne funktionsstatistikken skal du bruge funktionen GenericFeatureStatisticsGenerator(), og du bruger objektet ProtoFromDataFrames. Du kan sende datarammen i en ordbog. For eksempel, hvis vi ønsker at oprette en oversigtsstatistik for togsættet, kan vi gemme informationen i en ordbog og bruge den i objektet `ProtoFromDataFrames“

  • 'name': 'train', 'table': df_train

Navn er navnet på den tabel, der vises, og du bruger navnet på den tabel, du ønsker, til at beregne oversigten. I dit eksempel er tabellen, der indeholder dataene, 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")

Til sidst kopierer og indsætter du blot koden nedenfor. Koden kommer direkte fra GitHub. Du burde kunne se dette:

Oversigt Facet

# Display the facets overview visualization for this data# Displ 
from IPython.core.display import display, HTML

HTML_TEMPLATE = """<link rel="import" href="/da/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))

Graf

Når du har kontrolleret dataene og deres fordeling, kan du plotte en korrelationsmatrix. Korrelationsmatricen beregner Pearson-koefficienten. Denne koefficient er bundet mellem -1 og 1, med en positiv værdi angiver en positiv korrelation og negativ værdi en negativ korrelation.

Du er interesseret i at se, hvilke variabler der kan være en god kandidat til interaktionsbegreber.

## 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})

Produktion

<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518>

png

Facetgraf

Fra matrixen kan du se:

  • LSTAT
  • RM

Er stærkt korreleret med PRICE. En anden spændende funktion er den stærke positive korrelation mellem NOX og INDUS, hvilket betyder, at disse to variabler bevæger sig i samme retning. Desuden er der også korreleret med PRIS. DIS er også stærkt korreleret med IND og NOX.

Du har et første hint om, at IND og NOX kan være gode kandidater til intercept-termen, og DIS kunne også være interessant at fokusere på.

Du kan gå en lille smule dybere ved at plotte et par-gitter. Det vil illustrere mere detaljeret det korrelationskort, du plottede før.

Pargitteret vi er sammensat som følger:

  • Overdel: Spredt plot med monteret linie
  • Diagonal: Kerneldensitetsplot
  • Nederste del: Multivariat kernedensitetsplot

Du vælger fokus på fire uafhængige variable. Valget svarer til de variable med stærk korrelation med PRIS

  • INDUS
  • NOX
  • RM
  • LSTAT

desuden PRISEN.

Bemærk at standardfejlen tilføjes som standard til spredningsplottet.

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)

Produktion

Facetgraf

Lad os begynde med den øverste del:

  • Prisen er negativt korreleret med INDUS, NOX og LSTAT; positivt korreleret med RM.
  • Der er en lidt ikke-linearitet med LSTAT og PRIS
  • Der er ligesom en ret linje, når prisen er lig med 50. Fra beskrivelsen af ​​datasættet er PRICE blevet afkortet til værdien 50

Diagonal

  • NOX ser ud til at have to klynger, en omkring 0.5 og en omkring 0.85.

For at tjekke mere om det, kan du se på den nederste del. Den multivariate kerneltæthed er interessant på en måde, den farver, hvor de fleste af punkterne er. Forskellen med spredningsplottet tegner en sandsynlighedstæthed, selvom der ikke er noget punkt i datasættet for en given koordinat. Når farven er stærkere, indikerer det en høj koncentration af punkt omkring dette område.

Hvis du tjekker den multivariate tæthed for INDUS og NOX, kan du se den positive korrelation og de to klynger. Når industriens andel er over 18, er nitrogenoxidkoncentrationen over 0.6.

Du kan tænke på at tilføje en interaktion mellem INDUS og NOX i det lineære forhold.

Endelig kan du bruge det andet værktøjer skabt af Google, Facets Deep Dive. Interfacet er opdelt i fire hovedsektioner. Det centrale område i midten er en zoombar visning af dataene. Øverst på panelet er der rullemenuen, hvor du kan ændre arrangementet af dataene til at kontrollere facettering, positionering og farve. Til højre er der en detaljeret visning af en bestemt række data. Det betyder, at du kan klikke på en hvilken som helst prik af data i centervisualiseringen for at se detaljerne om det pågældende datapunkt.

Under datavisualiseringstrinnet er du interesseret i at lede efter den parvise sammenhæng mellem den uafhængige variabel på husets pris. Det involverer dog mindst tre variabler, og 3D-plot er komplicerede at arbejde med.

En måde at løse dette problem på er at oprette en kategorisk variabel. Det vil sige, at vi kan skabe et 2D-plot og farve prikken. Du kan opdele variablen PRICE i fire kategorier, hvor hver kategori er en kvartil (dvs. 0.25, 0.5, 0.75). Du kalder denne nye variabel 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")

Facetgraf

Facetter Deep Dive

For at åbne Deep Dive skal du transformere dataene til et json-format. Pandaer som objekt for det. Du kan bruge to_json efter Pandas-datasættet.

Den første kodelinje håndterer datasættets størrelse.

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')

Koden nedenfor kommer fra Google GitHub. Når du har kørt koden, burde du kunne se dette:

Facetter Deep Dive

# Display thde Dive visualization for this data
from IPython.core.display import display, HTML

# Create Facets template  
HTML_TEMPLATE = """<link rel="import" href="/da/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))

Du er interesseret i at se, om der er sammenhæng mellem branchesatsen, oxidkoncentrationen, afstanden til jobcenteret og husets pris.

Til det opdeler du først dataene efter brancheområde og farve med priskvartilen:

  • Vælg facettering X og vælg INDUS.
  • Vælg Display og vælg DIS. Det vil farve prikkerne med kvartilen af ​​boligprisen

her betyder mørkere farver, at afstanden til det første jobcenter er langt.

Indtil videre viser det igen, hvad du ved, lavere branchesats, højere pris. Nu kan du se opdelingen efter INDUX, efter NOX.

  • Vælg facettering Y og vælg NOX.

Nu kan man se huset langt fra det første jobcenter have den laveste brancheandel og dermed den laveste oxidkoncentration. Hvis du vælger at vise typen med Q_PRICE og zoome ned i nederste venstre hjørne, kan du se, hvilken type pris det er.

Du har endnu et hint om, at samspillet mellem IND, NOX og DIS kan være gode kandidater til at forbedre modellen.

TensorFlow

I dette afsnit vil du estimere den lineære klassifikator med TensorFlow estimators API. Du vil fortsætte som følger:

  • Forbered dataene
  • Estimer en benchmarkmodel: Ingen interaktion
  • Estimer en model med interaktion

Husk, at målet med maskinlæring er at minimere fejlen. I dette tilfælde vil modellen med den laveste middelkvadratfejl vinde. TensorFlow-estimatoren beregner automatisk denne metrik.

Forberedelsesdata

I de fleste tilfælde skal du transformere dine data. Derfor er Facets Overview fascinerende. Fra oversigtsstatistikken så du, at der er afvigelser. Disse værdier påvirker estimaterne, fordi de ikke ligner den befolkning, du analyserer. Outliers påvirkede normalt resultaterne. For eksempel har en positiv outlier en tendens til at overvurdere koefficienten.

En god løsning til at løse dette problem er at standardisere variablen. Standardisering betyder en standardafvigelse på én og betyder nul. Standardiseringsprocessen omfatter to trin. Først og fremmest trækker den middelværdien af ​​variablen fra. For det andet divideres den med standardafvigelsen, således at fordelingen har en enhedsstandardafvigelse.

Biblioteket sklearn er nyttigt til at standardisere variabler. Du kan bruge modulet forbehandling med objektskalaen til dette formål.

Du kan bruge funktionen nedenfor til at skalere et datasæt. Bemærk, at du ikke skalerer etiketkolonnen og kategoriske variabler.

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

Du kan bruge funktionen til at konstruere det skalerede tog/testsæt.

df_train_scale = standardize_data(df_train)
df_test_scale = standardize_data(df_test)

Grundlæggende regression: Benchmark

Først og fremmest træner og tester du en model uden interaktion. Formålet er at se modellens præstationsmetrik.

Måden at træne modellen på er præcis som tutorialen på API på højt niveau. Du skal bruge TensorFlow-estimatoren LinearRegressor.

Som en påmindelse skal du vælge:

  • funktionerne til at sætte i modellen
  • transformere funktionerne
  • konstruere den lineære regressor
  • konstruer input_fn-funktionen
  • træne modellen
  • test modellen

Du bruger alle variablerne i datasættet til at træne modellen. I alt er der elevel kontinuerte variable og en kategorisk variabel

## 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']

Du konverterer funktionerne til en numerisk kolonne eller kategorisk kolonne

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'])]

Du opretter modellen med linearRegressor. Du gemmer modellen i mappen train_Boston

model = tf.estimator.LinearRegressor(    
	model_dir="train_Boston",     
    feature_columns=categorical_features + continuous_features)

Produktion

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}

Hver kolonne i toget eller testdata konverteres til en Tensor med funktionen 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)

Du estimerer modellen på togdataene.

model.train(input_fn=get_input_fn(df_train_scale, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Produktion

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>

Til sidst estimerer du modellens ydeevne på testsættet

model.evaluate(input_fn=get_input_fn(df_test_scale, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Produktion

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}

Tabet af modellen er 1650. Dette er den metrik, der skal slås i næste afsnit

Forbedre modellen: Interaktionsudtryk

Under den første del af selvstudiet så du et interessant forhold mellem variablerne. De forskellige visualiseringsteknikker afslørede, at INDUS og NOS er kædet sammen og drejer for at forstørre effekten på prisen. Ikke kun interaktionen mellem INDUS og NOS påvirker prisen, men også denne effekt er stærkere, når den interagerer med DIS.

Det er på tide at generalisere denne idé og se, om du kan forbedre den forudsagte model.

Du skal tilføje to nye kolonner til hvert datasæt: tog + test. Til det opretter du en funktion til at beregne interaktionsleddet og en anden til at beregne det tredobbelte interaktionsled. Hver funktion producerer en enkelt kolonne. Når de nye variabler er oprettet, kan du sammenkæde dem til træningsdatasættet og testdatasættet.

Først og fremmest skal du oprette en ny variabel til interaktionen mellem INDUS og NOX.

Funktionen nedenfor returnerer to datarammer, train og test, med interaktionen mellem var_1 og var_2, i dit tilfælde INDUS og 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

Du gemmer de to nye kolonner

interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS')
interation_ind_ns_train.shape
(325,)

For det andet opretter du en anden funktion til at beregne det tredobbelte interaktionsled.

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 hvor du har alle nødvendige kolonner, kan du tilføje dem til at træne og teste datasæt. Du navngiver disse to nye dataramme:

  • 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)

Produktion

Forbedre modelinteraktionsudtrykket

Det er det; du kan estimere den nye model med interaktionsvilkårene og se, hvordan præstationsmålingen er.

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)

Produktion

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)

Produktion

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)

Produktion

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}

Det nye tab er 1515. Bare ved at tilføje to nye variabler, var du i stand til at mindske tabet. Det betyder, at du kan lave en bedre forudsigelse end med benchmarkmodellen.