TensorFlow linjär regression med facett & interaktionsterm

I den här handledningen kommer du att lära dig hur du kontrollerar data och förbereder dem för att skapa en enkel linjär regressionsuppgift.

Denna handledning är uppdelad i två delar:

  • Leta efter interaktion
  • Testa modellen

I tidigare handledning, använde du Boston-datauppsättningen för att uppskatta medianpriset för ett hus. Boston dataset har en liten storlek, med endast 506 observationer. Denna datauppsättning betraktas som ett riktmärke för att testa nya linjära regressionsalgoritmer.

Datauppsättningen består av:

Variabel Description
zn Andelen bostadsmark som är planlagd för tomter över 25,000 XNUMX kvm.
indus Andelen icke-handelsföretagare per stad.
nox kväveoxidkoncentration
rm genomsnittligt antal rum per bostad
ålder andelen ägarlägenheter byggda före 1940
DIS vägda avstånd till fem arbetsförmedlingar i Boston
skatt fastighetsskattesats för fullt värde per dollar 10,000 XNUMX
ptratio förhållandet elev-lärare av en stad
medv Medianvärdet för ägda bostäder i tusen dollar
krim brottslighet per capita per stad
Chas Charles River dummyvariabel (1 om gränsen till floden; 0 annars)
B andelen svarta vid staden

I den här handledningen kommer vi att uppskatta medianpriset med hjälp av en linjär regressor, men fokus ligger på en speciell process av maskininlärning: "dataförberedelse."

En modell generaliserar mönstret i datan. För att fånga ett sådant mönster måste du hitta det först. En bra praxis är att utföra en dataanalys innan du kör någon maskininlärningsalgoritm.

Att välja rätt funktioner gör stor skillnad för din modells framgång. Föreställ dig att du försöker uppskatta lönen för ett folk, om du inte tar med könet som en samvariat så hamnar du på en dålig uppskattning.

Ett annat sätt att förbättra modellen är att titta på korrelationen mellan den oberoende variabeln. Tillbaka till exemplet, du kan tänka dig utbildning som en utmärkt kandidat för att förutsäga lönen men också yrket. Det är rimligt att säga att yrket beror på utbildningsnivån, nämligen högre utbildning leder ofta till ett bättre yrke. Om vi ​​generaliserar denna idé kan vi säga att korrelationen mellan den beroende variabeln och en förklaringsvariabel kan förstoras med ännu en förklaringsvariabel.

För att fånga utbildningens begränsade effekt på yrket kan vi använda en interaktionsterm.

Interaktionsperiod

Om man tittar på löneekvationen blir den:

Interaktionsperiod

If Interaktionsperiod är positivt, så innebär det att en extra utbildningsnivå ger en högre ökning av medianvärdet på ett hus för en hög yrkesnivå. Det finns med andra ord en interaktionseffekt mellan utbildning och yrke.

I den här handledningen ska vi försöka se vilka variabler som kan vara en bra kandidat för interaktionstermer. Vi kommer att testa om att lägga till denna typ av information leder till bättre prisförutsägelse.

Sammanfattande statistik

Det finns några steg du kan följa innan du fortsätter till modellen. Som nämnts tidigare är modellen en generalisering av data. Den bästa praxisen är att förstå data och göra en förutsägelse. Om du inte känner till dina data har du små chanser att förbättra din modell.

Som ett första steg, ladda data som en pandas dataram och skapa ett träningsset och testset.

Tips: För den här handledningen måste du ha matplotlit och seaborn installerade i Python. Du kan installera Python paket i farten med Jupyter. Ni Borde inte gör det här

!conda install -- yes matplotlib

men

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

Observera att detta steg inte är nödvändigt om du har matplotlib och seaborn installerat.

Matplotlib är biblioteket att skapa en graf i Python. Seaborn är ett statistiskt visualiseringsbibliotek byggt ovanpå matplotlib. Det ger attraktiva och vackra tomter.

Koden nedan importerar de nödvändiga biblioteken.

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

Biblioteket sklearn inkluderar Boston dataset. Du kan anropa dess API för att importera data.

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

Funktionens namn lagras i objektet feature_names i en array.

boston.feature_names

Produktion

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

Du kan byta namn på kolumnerna.

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

Linjär regression med facett & interaktionsterm

Du konverterar variabeln CHAS till en strängvariabel och märker den med ja om CHAS = 1 och nej om 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 pandor är det enkelt att dela upp datasetet. Du delar upp datasetet slumpmässigt med 80 procent träningsuppsättning och 20 procent testsats. pandas har en inbyggd kostnadsfunktion för att dela upp ett dataramprov.

Den första parametern frac är ett värde från 0 till 1. Du ställer in det på 0.8 för att slumpmässigt välja 80 procent av dataramen.

Random_state tillåter att samma dataram returneras för alla.

### 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å datan. Det borde vara:

  • Tågsats: 506*0.8 = 405
  • Testuppsättning: 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 ÅLDER DIS RAD sKATT PTRATIO B LSTAT PRIS
0 0.00632 18.0 2.31 Nej 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 Nej 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 Nej 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 Nej 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 Nej 0.524 6.172 96.1 5.9505 5.0 311.0 15.2 396.90 19.15 27.1

Data är rörigt; den är ofta felbalanserad och beströdd med extremvärden som kastar bort analysen och maskininlärningsträningen.

Det första steget för att få datauppsättningen ren är att förstå var den behöver rengöras. Att rensa upp en datauppsättning kan vara knepigt att göra, särskilt på alla generaliserbara sätt

Googles forskningsteam har utvecklat ett verktyg för detta jobb som heter fasetter som hjälper till att visualisera data och skära upp den på alla möjliga sätt. Detta är en bra utgångspunkt för att förstå hur datasetet är upplagt.

Facetter låter dig hitta var data inte riktigt ser ut som du tänker.

Förutom deras webbapp gör Google det enkelt att bädda in verktygslådan i en Jupyter anteckningsbok.

Det finns två delar till Facets:

  • Fasettöversikt
  • Facetter Deep Dive

Fasettöversikt

Facets Overview ger en översikt över datamängden. Fasettöversikt delar upp kolumnerna med data i rader med framträdande information som visas

  1. procentandelen saknade observationer
  2. min och max värden
  3. statistik som medelvärde, median och standardavvikelse.
  4. Den lägger också till en kolumn som visar procentandelen värden som är nollor, vilket är användbart när de flesta värdena är nollor.
  5. Det är möjligt att se dessa distributioner på testdatauppsättningen såväl som träningsuppsättningen för varje funktion. Det betyder att du kan dubbelkolla att testet har en liknande fördelning som träningsdata.

Detta är åtminstone det minsta att göra innan någon maskininlärningsuppgift. Med det här verktyget missar du inte detta avgörande steg, och det lyfter fram några avvikelser.

Facetter Deep Dive

Facets Deep Dive är ett coolt verktyg. Det gör det möjligt att få lite klarhet i din datauppsättning och zooma in hela vägen för att se en enskild databit. Det betyder att du kan facettera data efter rad och kolumn över alla funktioner i datasetet.

Vi kommer att använda dessa två verktyg med Boston dataset.

Anmärkningar: Du kan inte använda Facets Overview och Facets Deep Dive samtidigt. Du måste rensa anteckningsboken först för att byta verktyg.

Installera Facet

Du kan använda Facet-webbappen för det mesta av analysen. I den här handledningen kommer du att se hur du använder den inom en Jupyter Anteckningsbok.

Först och främst måste du installera nbextensions. Det görs med denna kod. Du kopierar och klistrar in följande kod i terminalen på din maskin.

pip install jupyter_contrib_nbextensions

Direkt efter det måste du klona arkiven i din dator. Du har två val:

Alternativ 1) Kopiera och klistra in denna kod i terminalen (Rekommenderas)

Om du inte har Git installerat på din maskin, gå till denna URL https://git-scm.com/download/win och följ instruktionerna. När du är klar kan du använda git-kommandot i terminalen för Mac-användare eller Anaconda-prompten för Windows användare

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

Alternativ 2) Gå till https://github.com/PAIR-code/facets och ladda ner arkiven.

Installera Facet

Om du väljer det första alternativet hamnar filen i din nedladdningsfil. Du kan antingen låta filen laddas ner eller dra den till en annan sökväg.

Du kan kontrollera var Facets lagras med den här kommandoraden:

echo `pwd`/`ls facets`

Nu när du har hittat Facets måste du installera den i Jupyter Anteckningsbok. Du måste ställa in arbetskatalogen till sökvägen där fasetter finns.

Din nuvarande arbetskatalog och plats för Facets zip bör vara samma.

Installera Facet

Du måste peka arbetskatalogen till Facet:

cd facets

För att installera Facets i Jupyter, du har två alternativ. Om du har installerat Jupyter med Conda för alla användare, kopiera denna kod:

kan använda jupyter nbextension install facets-dist/

jupyter nbextension install facets-dist/

Använd annars:

jupyter nbextension install facets-dist/ --user

Okej, du är klar. Låt oss öppna Facet Overview.

Översikt

Översikt använder en Python skript för att beräkna statistiken. Du måste importera skriptet som heter generic_feature_statistics_generator till Jupyter. Oroa dig inte; skriptet finns i facettfilerna.

Du måste hitta dess väg. Det är lätt gjort. Du öppnar facets, öppnar filen facets_overview och sedan python. Kopiera sökvägen

Översikt Facet

Efter det, gå tillbaka till Jupyter, och skriv följande kod. Ändra sökvägen '/Users/Thomas/facets/facets_overview/python' till din sökväg.

# 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 importera skriptet med koden nedan.

from generic_feature_statistics_generator import 
GenericFeatureStatisticsGenerator

I windows blir samma kod

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

from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator

För att beräkna funktionsstatistiken måste du använda funktionen GenericFeatureStatisticsGenerator(), och du använder objektet ProtoFromDataFrames. Du kan skicka dataramen i en ordbok. Om vi ​​till exempel vill skapa en sammanfattande statistik för tåguppsättningen kan vi lagra informationen i en ordbok och använda den i objektet `ProtoFromDataFrames“

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

Namn är namnet på tabellen som visas, och du använder namnet på tabellen som du vill beräkna sammanfattningen. I ditt exempel är tabellen som innehåller data 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")

Till sist kopierar och klistrar du bara in koden nedan. Koden kommer direkt från GitHub. Du borde kunna se detta:

Översikt Facet

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

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

Diagrammet

När du har kontrollerat data och deras fördelning kan du rita en korrelationsmatris. Korrelationsmatrisen beräknar Pearson-koefficienten. Denna koefficient är bunden mellan -1 och 1, med ett positivt värde indikerar en positiv korrelation och negativt värde en negativ korrelation.

Du är intresserad av att se vilka variabler som kan vara en bra kandidat för interaktionstermer.

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

Fasettdiagram

Från matrisen kan du se:

  • LSTAT
  • RM

Är starkt korrelerade med PRICE. En annan spännande egenskap är den starka positiva korrelationen mellan NOX och INDUS, vilket innebär att de två variablerna rör sig i samma riktning. Dessutom finns det också korrelerade med PRIS. DIS är också starkt korrelerad med IND och NOX.

Du har en första antydan om att IND och NOX kan vara bra kandidater för intercept-termen och DIS kan också vara intressant att fokusera på.

Du kan gå lite djupare genom att rita ett parrutnät. Det kommer att illustrera mer i detalj korrelationskartan du ritade tidigare.

Parnätet vi är sammansatta enligt följande:

  • Övre del: Spridningstomt med inpassad linje
  • Diagonal: Kärndensitetsdiagram
  • Nedre del: Multivariat kärndensitetsdiagram

Du väljer fokus på fyra oberoende variabler. Valet motsvarar variablerna med stark korrelation med PRICE

  • INDUS
  • NOX
  • RM
  • LSTAT

dessutom PRIS.

Anmärkningar att standardfelet läggs till som standard till spridningsdiagrammet.

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

Fasettdiagram

Låt oss börja med den övre delen:

  • Priset är negativt korrelerat med INDUS, NOX och LSTAT; positivt korrelerad med RM.
  • Det finns en något icke-linjäritet med LSTAT och PRICE
  • Det finns som en rät linje när priset är lika med 50. Från beskrivningen av datasetet har PRICE trunkerats till värdet 50

Diagonal

  • NOX verkar ha två kluster, ett runt 0.5 och ett runt 0.85.

För att kolla mer om det kan du titta på den nedre delen. Den multivariata kärndensiteten är intressant i en mening den färgar där de flesta punkterna finns. Skillnaden med spridningsdiagrammet ritar en sannolikhetstäthet, även om det inte finns någon poäng i datasetet för en given koordinat. När färgen är starkare indikerar det en hög koncentration av punkt runt detta område.

Om du kontrollerar den multivariata densiteten för INDUS och NOX kan du se den positiva korrelationen och de två klustren. När industrins andel är över 18 är kväveoxidkoncentrationen över 0.6.

Du kan tänka på att lägga till en interaktion mellan INDUS och NOX i det linjära förhållandet.

Slutligen kan du använda de andra verktygen skapade av Google, Facets Deep Dive. Gränssnittet är uppdelat i fyra huvudsektioner. Det centrala området i mitten är en zoombar visning av data. Längst upp på panelen finns rullgardinsmenyn där du kan ändra arrangemanget av data till kontroller facettering, positionering och färg. Till höger finns en detaljerad vy av en specifik rad med data. Det betyder att du kan klicka på vilken datapunkt som helst i centrumvisualiseringen för att se detaljer om den specifika datapunkten.

Under datavisualiseringssteget är du intresserad av att leta efter den parvisa korrelationen mellan den oberoende variabeln på husets pris. Det involverar dock minst tre variabler och 3D-plots är komplicerade att arbeta med.

Ett sätt att lösa detta problem är att skapa en kategorisk variabel. Det vill säga, vi kan skapa en 2D-plot och färga punkten. Du kan dela upp variabeln PRICE i fyra kategorier, där varje kategori är en kvartil (dvs. 0.25, 0.5, 0.75). Du kallar denna nya 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")

Fasettdiagram

Facetter Deep Dive

För att öppna Deep Dive måste du omvandla data till ett json-format. Panda som objekt för det. Du kan använda to_json efter Pandas dataset.

Den första raden i kod hanterar datauppsättningens storlek.

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 nedan kommer från Google GitHub. När du har kört koden bör du kunna se detta:

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="/sv/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 är intresserad av att se om det finns ett samband mellan branschtakt, oxidkoncentration, avstånd till arbetsförmedlingen och priset på huset.

För det delar du först upp data efter branschintervall och färg med priskvartilen:

  • Välj facettering X och välj INDUS.
  • Välj Display och välj DIS. Det kommer att färga prickarna med kvartilen av huspriset

här betyder mörkare färger att avståndet till den första arbetsförmedlingen är långt.

Än så länge visar det igen vad du vet, lägre industripris, högre pris. Nu kan du titta på fördelningen av INDUX, efter NOX.

  • Välj facettering Y och välj NOX.

Nu kan man se att huset långt ifrån den första arbetsförmedlingen har lägst industriandel och därmed lägst oxidkoncentration. Om du väljer att visa typen med Q_PRICE och zooma ner i det nedre vänstra hörnet kan du se vilken typ av pris det är.

Du har ytterligare en hint om att interaktionen mellan IND, NOX och DIS kan vara bra kandidater för att förbättra modellen.

TensorFlow

I det här avsnittet kommer du att uppskatta den linjära klassificeraren med TensorFlow estimators API. Du kommer att gå tillväga enligt följande:

  • Förbered data
  • Uppskatta en benchmarkmodell: Ingen interaktion
  • Uppskatta en modell med interaktion

Kom ihåg att målet med maskininlärning är att minimera felet. I det här fallet vinner modellen med det lägsta medelkvadratfelet. TensorFlow-estimatorn beräknar automatiskt detta mått.

Beredningsdata

I de flesta fall måste du omvandla din data. Det är därför som Facets Overview är fascinerande. Från den sammanfattande statistiken såg du att det finns extremvärden. Dessa värden påverkar uppskattningarna eftersom de inte ser ut som den population du analyserar. Outliers påverkade vanligtvis resultaten. Till exempel tenderar en positiv extremvärde att överskatta koefficienten.

En bra lösning för att lösa detta problem är att standardisera variabeln. Standardisering betyder en standardavvikelse på ett och medel på noll. Standardiseringsprocessen omfattar två steg. Först och främst subtraherar den variabelns medelvärde. För det andra dividerar den med standardavvikelsen så att fördelningen har en enhetsstandardavvikelse.

Biblioteket sklearn är till hjälp för att standardisera variabler. Du kan använda modulen förbearbetning med objektskalan för detta ändamål.

Du kan använda funktionen nedan för att skala en datauppsättning. Observera att du inte skalar etikettkolumnen och kategoriska 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 använda funktionen för att konstruera det skalade tåget/testsetet.

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

Grundläggande regression: Benchmark

Först och främst tränar och testar du en modell utan interaktion. Syftet är att se modellens prestandamått.

Sättet att träna modellen är precis som handledningen på API på hög nivå. Du kommer att använda TensorFlow-estimatorn LinearRegressor.

Som en påminnelse måste du välja:

  • funktionerna att sätta i modellen
  • förvandla funktionerna
  • konstruera den linjära regressorn
  • konstruera funktionen input_fn
  • träna modellen
  • testa modellen

Du använder alla variabler i datamängden för att träna modellen. Totalt finns det elva kontinuerliga variabler och 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 konverterar funktionerna till en numerisk kolumn eller kategorisk kolumn

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 skapar modellen med linearRegressor. Du lagrar 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}

Varje kolumn i tåget eller testdata konverteras till 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 uppskattar modellen på tågdata.

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>

Till sist uppskattar du modellens prestanda på testsetet

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}

Förlusten av modellen är 1650. Detta är måtten att slå i nästa avsnitt

Förbättra modellen: Interaktionsterm

Under den första delen av handledningen såg du ett intressant samband mellan variablerna. De olika visualiseringsteknikerna visade att INDUS och NOS är sammanlänkade och vänder för att förstärka effekten på priset. Inte bara interaktionen mellan INDUS och NOS påverkar priset utan även denna effekt är starkare när den interagerar med DIS.

Det är dags att generalisera denna idé och se om du kan förbättra den modellförutspådda modellen.

Du måste lägga till två nya kolumner till varje datauppsättning: tåg + test. För det skapar du en funktion för att beräkna interaktionstermen och en annan för att beräkna den trippelinteraktionstermen. Varje funktion producerar en enda kolumn. När de nya variablerna har skapats kan du koppla dem till träningsdatauppsättningen och testdatauppsättningen.

Först och främst måste du skapa en ny variabel för interaktionen mellan INDUS och NOX.

Funktionen nedan returnerar två dataramar, träna och testa, med interaktionen mellan var_1 och var_2, i ditt fall INDUS och 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 lagrar de två nya kolumnerna

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

För det andra skapar du en andra funktion för att beräkna trippelinteraktionstermen.

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 när du har alla kolumner som behövs kan du lägga till dem för att träna och testa dataset. Du namnger dessa två nya dataramar:

  • 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

Förbättra modellinteraktionstermen

Nu räcker det; du kan uppskatta den nya modellen med interaktionsvillkoren och se hur prestationsmåttet är.

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}

KOD

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}

Den nya förlusten är 1515. Bara genom att lägga till två nya variabler kunde du minska förlusten. Det betyder att du kan göra en bättre förutsägelse än med benchmarkmodellen.