TensorFlow lineær regression med facet- og interaktionsterm
⚡ Smart opsummering
Lineær regression på boligdataene fra Boston forbedres, når de rigtige interaktionstermer findes først. Google Facetter eksponerer disse relationer visuelt, og to krydsede funktioner reducerede TensorFlow-testtabet fra 1650 til 1515.
TensorFlow lineær regression
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 | Beskrivelse |
|---|---|
| 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.
Den samme estimatorfamilie driver også lineær klassifikator når etiketten er en klasse snarere end en pris. I denne vejledning vil vi forsøge at se, hvilke variabler der kan være en god kandidat til interaktionstermer. Vi vil teste, om tilføjelse af denne type information fører til bedre prisforudsigelser.
Sammenfattende statistik
Der er et par trin, du kan følge, før du går videre til modellen. Som tidligere nævnt er modellen en generalisering af dataene. Den bedste praksis er først at forstå dataene og derefter 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.
Tips: Til denne vejledning skal du have matplotlib og seaborn installeret i PythonDu kan installere en 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 PythonSeaborn er et statistisk visualiseringsbibliotek bygget oven på matplotlib. Det tilbyder følgende:tractive og smukke plots.
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.
Versionsnotat: load_boston blev udfaset i scikit-learn 1.0 og fjernet i scikit-learn 1.2 fordi datasættet koder en racemæssigt ladet funktion. Brug på en aktuel installation fetch_california_boliger eller indlæs råfilen selv. Arbejdsgangen vist nedenfor er uændret; kun indlæseren er anderledes.
boston = load_boston() df = pd.DataFrame(boston.data)
Funktionsnavnene gemmes i objektet feature_names som et array.
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 samplingfunktion til at opdele en dataramme.
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 retter blandningen, så de samme rækker returneres 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 Forskerholdet har udviklet et værktøj til dette job kaldet facetter der hjælper dig med at visualisere dataene og opdele dem på alle mulige måder. Dette er et godt udgangspunkt for at forstå, hvordan datasættet er opbygget.
Med Facetter kan du finde ud af, hvor dataene ikke helt ser ud, som du forventer.
Bortset fra deres webapp, Google gør 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 smart værktøj. Det giver dig mulighed for at få mere overblik over dit datasæt og zoome helt ind for at se et individuelt datasæt. Det betyder, at du kan facettere dataene række for række på tværs af alle funktioner 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.
Før et af værktøjerne kan bruges, skal Facets installeres i den bærbare computer.
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 dette URL Git for Windows download siden 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 PAIR-kode/facetarkivet og download arkiverne.
Ovenstående arkivside indeholder downloadknappen, der bruges af mulighed 2. Hvis du vælger den første mulighed, ender filen i din downloadmappe. 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.
Terminallisten ovenfor bekræfter, at facets er placeret i den aktuelle arbejdsmappe. Du skal pege arbejdsmappen 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:
jupyter nbextension install facets-dist/
Ellers brug:
jupyter nbextension install facets-dist/ --user
Okay, du er klar. Lad os åbne Facet Oversigt.
Oversigt over kørselsfacetter i Jupyter
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="/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))
Korrelationsgraf og pargitter
Når du har kontrolleret dataene og deres fordeling, kan du plotte en korrelationsmatrix. Korrelationsmatrixen beregner Pearson-koefficienten. Denne koefficient er begrænset mellem -1 og 1, hvor en positiv værdi angiver en positiv korrelation, og en negativ værdi en negativ korrelation.
Du er interesseret i at se, hvilke variabler der kan være en god kandidat til interaktionsbegreber.
Versionsnotat: masken nedenfor kalder np.bool, et alias, der blev udfaset i NumPy 1.20 og fjernet i NumPy 1.24På en nylig NumPy hæves den samme linje AttributeError: module 'numpy' has no attribute 'bool'den indbyggede bool er drop-in-erstatningen.
## 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>
I varmekortet ovenfor markerer mørkere firkanter stærkere korrelationer. Fra matricen kan du se:
- LSTAT
- RM
Er stærkt korreleret med PRIS. En anden spændende egenskab er den stærke positive korrelation mellem NOX og INDUS, hvilket betyder, at disse to variabler bevæger sig i samme retning. Begge er også korreleret med PRIS. DIS er også stærkt korreleret med INDUS og NOX.
Du har et første hint om, at INDUS og NOX kan være gode kandidater til et interaktionsterm, og at DIS måske også er 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 er sammensat som følger:
- Overdel: Spredt plot med monteret linie
- Diagonal: Kerneldensitetsplot
- Nederste del: Multivariat kernedensitetsplot
Du fokuserer på fire uafhængige variabler. Valget svarer til de variabler med stærk korrelation med PRICE
- 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 lille ikke-linearitet mellem LSTAT og PRICE
- 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øj, der er skabt af Google, Dybdegående visning af facetter. Grænsefladen er opdelt i fire hovedsektioner. Det centrale område i midten er en zoombar visning af dataene. Øverst i panelet er der en rullemenu, hvor du kan ændre dataenes placering for at kontrollere facettering, placering og farve. Til højre er der en detaljeret visning af en bestemt datarække. Det betyder, at du kan klikke på en hvilken som helst dataprik i den midterste visualisering for at se detaljer 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 oprette et 2D-plot og farvelægge prikkerne. 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")
Brug af facetter dybdegående
For at åbne Deep Dive skal du transformere dataene til et json-format. Pandas har en metode til det: kald to_json på DataFrame.
Den første kodelinje angiver sprite-størrelsen i henhold til, hvor mange rækker datasættet indeholder.
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="/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 større.
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.
Udforskningen har resulteret i to mulige interaktioner, så det næste skridt er at teste dem i en faktisk model.
Lineær regression med TensorFlow
I dette afsnit skal du estimere den lineære regressionsmodel med TensorFlow Estimator API. Du skal fortsætte som følger:
- Forbered dataene
- Estimer en benchmarkmodel: Ingen interaktion
- Estimer en model med interaktion
Versionsnotat: og tf-estimator Pakken sendte sin endelige udgivelse med TensorFlow 2.15 og er fraværende fra TensorFlow 2.16 og fremefter, så tf.estimator.LinearRegressor kører kun på TensorFlow 1.x, medmindre du migrerer den til en Keras lineær model.
Husk, at målet med maskinlæring er at minimere fejlen. I dette tilfælde vinder modellen med den laveste gennemsnitlige kvadratiske fejl. TensorFlow-estimatoren beregner automatisk denne metrik.
Forberedelsesdata
I de fleste tilfælde er du nødt til at transformere dine data. Derfor er Facets Overview fascinerende. Ud fra den opsummerende statistik kan du se, at der er outliers. Disse værdier påvirker estimaterne, fordi de ikke ligner den population, du analyserer. Outliers skæver 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 en gennemsnitsværdi på nul. Standardiseringsprocessen involverer to trin. Først og fremmest er det subtracts er middelværdien af variablen. For det andet divideres den med standardafvigelsen, så fordelingen har en enhedsstandardafvigelse.
Biblioteket scikit-lære er nyttigt til at standardisere variabler. Du kan bruge modulets 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 i vejledningen 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 tolv kontinuerlige variabler og én 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 tog- eller testdataene 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.9785. Dette er den metrik, der skal slås i næste afsnit
Forbedre modellen: Interaktionsudtryk
I den første del af vejledningen så du en interessant sammenhæng mellem variablerne. De forskellige visualiseringsteknikker afslørede, at INDUS og NOX er forbundet og forstærker hinandens effekt på prisen. Ikke alene påvirker interaktionen mellem INDUS og NOX prisen, men denne effekt er også stærkere, når den interagerer med DIS.
Det er tid til at generalisere denne idé og se, om man kan forbedre modelforudsigelsen.
Du skal tilføje to nye kolonner til hvert datasæt: train og test. Til det formål opretter du én funktion til at beregne interaktionstermet og en anden til at beregne det tredobbelte interaktionsterm. Hver funktion producerer en enkelt kolonne. Når de nye variabler er oprettet, kan du sammenkæde dem med 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 interaktionsleddene og se, hvordan præstationsmetrikken 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.9863. 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.
| Model | Funktionssæt | Model bibliotek | gennemsnitligt_tab | off |
|---|---|---|---|---|
| benchmark | 12 standardiserede kontinuerlige kolonner plus CHAS | tog_Boston | 86.89361 | 1650.9785 |
| Med interaktion | Benchmark plus INDUS_NOS og INDUS_NOS_DIS | tog_Boston_1 | 79.78876 | 1515.9863 |
Begge tal stammer fra den samme testopdeling på 101 rækker, så faldet på cirka 8 procent i gennemsnitligt tab kan alene tilskrives de to interaktionskolonner.











