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.
Om man tittar på löneekvationen blir den:
If ä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)
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
- procentandelen saknade observationer
- min och max värden
- statistik som medelvärde, median och standardavvikelse.
- 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.
- 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.
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.
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
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:
# 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
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
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")
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:
# 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
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.