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.
Hvis du ser på lønligningen, bliver den:
If 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)
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
- procentdelen af manglende observation
- min og max værdier
- statistik som middelværdi, median og standardafvigelse.
- 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.
- 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.
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.
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
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:
# 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
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
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")
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:
# 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
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.