Handledning för linjär regression med TensorFlow [Exempel]

⚡ Smart sammanfattning

Linjär regression i TensorFlow modellerar förhållandet mellan numeriska funktioner och ett kontinuerligt målvärde. Denna genomgång tränar en prediktor för bostadspriser i Boston på tre separata sätt, med hjälp av Pandas, NumPy och nativa TensorFlow-inmatningspipelines med LinearRegressor-estimatorn.

  • 🔘 Modellform: En linjär regression anpassar y = bias + vikt × x, utökad med fler kovariater för multivariata problem.
  • ☑️ Träningsslinga: Gradient descent justerar vikterna vid varje iteration tills medelkvadratfelet slutar minska.
  • Kalkylator-API: LinearRegressor behöver bara funktionskolumner, en modellkatalog och en inmatningsfunktion.
  • 🧪 Tre rörledningar: Pandas, NumPy och native TensorFlow-datauppsättningar matar samma modell och returnerar identiska förutsägelser.
  • 🛠️ Utarbetat exempel: Nio Boston-funktioner förutspår medianhusvärde och når en testförlust på 3215.
  • ⚠️ Versionens verklighet: Uppskattningsverktyg föråldrades i TensorFlow 2.12 och togs bort i 2.16, så portera nytt arbete till Keras.

Linjär regression med TensorFlow

Vad är linjär regression?

linjär regression är en metod inom statistik för att modellera samband mellan två variabler. Denna modellering görs mellan ett skalärt svar och en eller flera förklarande variabler. Sambandet med en förklarande variabel kallas enkel linjär regression, och med mer än en förklarande variabel kallas det multipel linjär regression.

TensorFlow tillhandahåller verktyg för att ha full kontroll över beräkningarna. Detta görs med lågnivå API. Utöver det är TensorFlow utrustad med ett stort utbud av API:er för att utföra många maskininlärning algoritmer. Detta är högnivå-API:et, och TensorFlow kallar dem estimatorer.

  • API på låg nivåBygg arkitekturen och optimeringen av modellen från grunden. Det är komplicerat för en nybörjare.
  • API på hög nivåDefiniera algoritmen. Den är användarvänlig. TensorFlow tillhandahåller en verktygslåda som heter uppskattare att konstruera, träna, utvärdera och göra en förutsägelse.

I den här handledningen kommer du att använda endast estimerareBeräkningarna är snabbare och enklare att implementera. Den första delen förklarar hur man använder gradient descent-optimeraren för att träna en linjär regression i TensorFlow. I en andra del kommer du att använda Boston-datasetet för att förutsäga priset på ett hus med hjälp av en TensorFlow-estimator.

Ladda ner Boston DataSet

Hur man tränar en linjär regressionsmodell

Innan vi börjar träna modellen, låt oss titta på vad en linjär regression egentligen är.

Tänk dig att du har två variabler, x och y, och din uppgift är att förutsäga värdet på y med värdet på x. Om du plottar data kan du se ett positivt samband mellan din oberoende variabel, x, och din beroende variabel, y, som spridningsdiagrammet nedan visar.

Spridningsdiagram av x mot y som visar ett positivt linjärt samband

Du kan observera att om x=1, kommer y ungefär att vara lika med 6, och om x=2, kommer y att vara runt 8.5.

Detta är inte en särskilt noggrann metod och är felbenägen, särskilt med en datamängd som innehåller hundratusentals punkter.

En linjär regression utvärderas med en ekvation. Variabeln y förklaras av en eller flera kovariater. I ditt exempel finns det bara en beroende variabel. Om du måste skriva den här ekvationen blir det:

Enkel linjär regressionsekvation med en bias, en vikt och en felterm

Med:

  • Symbol för biaskoefficient är biasen. Det vill säga, om x=0, y=Biaskoefficientvärde när x är lika med noll
  • Viktkoefficientsymbol associerad med x är vikten associerad med x
  • Symbol för kvarvarande felterm är residualen, eller modellens fel. Den inkluderar vad modellen inte kan lära sig av data

Föreställ dig att du passar modellen och du hittar följande lösning för:

  • Anpassad biaskoefficient lika med 3.8 = 3.8
  • Monterad viktkoefficient lika med 2.78 = 2.78

Du kan ersätta dessa siffror i ekvationen och det blir:

y= 3.8 + 2.78x

Nu har du ett bättre sätt att hitta värdena för y. Det vill säga, du kan ersätta x med vilket värde du vill för att förutsäga y. I bilden nedan har vi ersatt x i ekvationen med alla värden i datamängden och ritat resultatet.

Anpassad regressionslinje ritad i rött genom de plottade datapunkterna

Den röda linjen representerar det anpassade värdet, det vill säga värdena på y för varje värde på x. Du behöver inte se värdet på x för att förutsäga y; för varje x finns det ett värde som hör till den röda linjen. Du kan också förutsäga för värden på x högre än 2.

Om du vill utöka den linjära regressionen till fler kovariater kan du göra det genom att lägga till fler variabler i modellen. Skillnaden mellan traditionell analys och linjär regression är att linjär regression tittar på hur y kommer att reagera för varje variabel x tagen oberoende av varandra.

Låt oss se ett exempel. Tänk dig att du vill förutsäga försäljningen i en glassbutik. Datasetet innehåller olika uppgifter såsom väder (regnigt, soligt, molnigt) och kundinformation (lön, kön, civilstånd).

Traditionell analys försöker förutsäga försäljningen genom att, låt oss säga, beräkna medelvärdet för varje variabel och försöka uppskatta försäljningen för olika scenarier. Det kommer att leda till dåliga förutsägelser och begränsa analysen till det valda scenariot.

Om du använder linjär regression kan du skriva denna ekvation:

Multipel linjär regressionsekvation som kombinerar flera viktade kovariater

Algoritmen kommer att hitta den bästa lösningen för vikterna; det betyder att den kommer att försöka minimera kostnaden, vilket är skillnaden mellan den anpassade linjen och datapunkterna.

Hur algoritmen fungerar

Diagrammet nedan sammanfattar loopen som algoritmen upprepar: välj vikter, förutsäg y-värdet, mät felet och korrigera vikterna.

Flödesdiagram för den linjära regressionsträningsslingan från slumpmässiga vikter till minimerat fel

Algoritmen kommer att välja ett slumpmässigt tal för varje Slumpmässigt initierad biaskoefficient och Slumpmässigt initierad viktkoefficient och ersätt värdet på x för att få det förutsagda värdet på y. Om datasetet har 100 observationer, beräknar algoritmen 100 förutsagda värden.

Vi kan beräkna felet, noterade Modellfelsterm som används i förlustberäkningen, för modellen, vilket är skillnaden mellan det förutspådda värdet och det verkliga värdet. Ett positivt fel innebär att modellen underskattar förutsägelsen av y, och ett negativt fel innebär att modellen överskattar förutsägelsen av y.

Mål för minimerad felkvadrering skrivet i matematisk notation

Ditt mål är att minimera kvadraten av felet. Algoritmen beräknar medelvärdet av kvadratfelet. Detta steg kallas minimering av felet. För linjär regression är detta Mean Square Error, även kallad MSE. Matematiskt är det:

Formel för medelkvadratfel skriven i matrisnotation

Var:

  • Viktvektorsymbol som används i MSE-formeln är vikterna, så Notation för förutspått värde som används i MSE-formeln hänvisar till det förutsagda värdet
  • y är de verkliga värdena
  • m är antalet observationer

Observera att Transponerad viktmatrisnotation betyder att den använder transponeringen av matriserna. De Summations- och medelvärdesnotation som används i MSE-formeln är den matematiska notationen av medelvärdet.

Målet är att hitta det bästa Symbol för optimal vikt som minimerar MSE som minimerar MSE.

Om medelfelet är stort betyder det att modellen presterar dåligt och att vikterna inte är rätt valda. För att korrigera vikterna måste du använda en optimerare. Den traditionella optimeraren kallas Gradient härkomst.

Gradientnedgången tar derivatan och minskar eller ökar vikten. Om derivatan är positiv minskas vikten. Om derivatan är negativ ökar vikten. Modellen uppdaterar vikterna och beräknar om felet. Denna process upprepas tills felet inte längre ändras. Varje pass kallas en iterationDessutom multipliceras gradienterna med en inlärningshastighet, vilket indikerar inlärningshastigheten.

Om inlärningshastigheten är för liten tar det mycket lång tid för algoritmen att konvergera, eftersom det kräver många fler iterationer. Om inlärningshastigheten är för hög kanske algoritmen aldrig konvergerar. Förlustkurvan nedan visar felet mot iterationsantalet för denna datamängd.

Förlustkurva som visar felet som minskar och stabiliseras efter cirka tjugo iterationer

Du kan se från bilden ovan att modellen upprepar processen ungefär 20 gånger innan den hittar ett stabilt värde för vikterna och därmed når det lägsta felet.

Observera att felet inte är lika med noll utan stabiliseras runt 5. Det betyder att modellen gör ett typiskt fel på 5. Om du vill minska felet behöver du lägga till mer information i modellen, till exempel fler variabler, eller använda andra estimatorer.

Du minns den första ekvationen:

Slutlig anpassad linjär regressionsekvation med de lösta vikterna

De slutliga vikterna är 3.8 och 2.78. Videon nedan visar hur gradientdestinationen optimerar förlustfunktionen för att hitta dessa vikter.

Hur man tränar en linjär regression med TensorFlow

Nu när du har en bättre förståelse för vad som händer bakom huven, är du redo att använda estimator-API:et från TensorFlow för att träna din första linjära regression med TensorFlow.

Versionsnotering: Estimatorarbetsflödet som visas nedan skrevs mot TensorFlow 1.x och de tidiga 2.x-versionerna. TensorFlow markerade tf.estimator och tf.feature_column API:er är helt föråldrade i version 2.12 och Estimators togs bort i version 2.16. Kör den här koden i en TensorFlow 1.15 eller 2.x-with- på en aktuell installation.tf.compat.v1 miljö, eller portera den till Keras, där tf.keras.layers.Dense(1) plus att förbehandlingslager ersätter LinearRegressor och funktionskolumnerna. Begreppen – funktioner, etiketter, batchar, epoker, MSE och gradientnedgång – bibehålls oförändrade.

Du kommer att använda Boston-datasetet, som innehåller följande variabler.

Variabel BESKRIVNING
krim brottslighet per capita per stad
zn andel av bostadsmark som är planlagd för tomter över 25,000 XNUMX kvm.
indus andel icke-detaljhandelsföretag per stad.
nox kväveoxidkoncentration
rm genomsnittligt antal rum per bostad
ålder andel ägarbostäder 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 elev-lärare per stad
medv Medianvärdet av ägda bostäder i tusen dollar

Du kommer att skapa tre olika datamängder:

dataset mål forma
Utbildning Träna modellen och skaffa vikterna 400, 10
Utvärdering Utvärdera modellens prestanda på osynliga data 100, 10
förutsäga Använd modellen för att förutsäga husvärde på ny data 6, 10

Målet är att använda datamängdens funktioner för att förutsäga husets värde.

Under den andra delen av handledningen lär du dig hur du använder TensorFlow med tre olika sätt att importera data:

  • Med pandor
  • Med numpy
  • Endast TensorFlow

Observera att alla tre alternativen ger samma resultat.

Du kommer att lära dig hur du använder högnivå-API:et för att bygga, träna och utvärdera en TensorFlow-linjär regressionsmodell. Om du använde lågnivå-API:et skulle du behöva definiera följande manuellt:

  • Förlustfunktion
  • Optimerare: gradientnedgång
  • Matrix multiplikation
  • Graf och tensor

Detta är tråkigt och mer komplicerat för en nybörjare.

Pandas lösning

Du måste importera de nödvändiga biblioteken för att träna modellen.

import pandas as pd
from sklearn import datasets
import tensorflow as tf
import itertools

Steg 1) Importera data med pandas.

Du definierar kolumnnamnen och lagrar dem i KOLUMNER. Du kan använda pd.read_csv() för att importera data.

COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age",
           "dis", "tax", "ptratio", "medv"]

Peka varje samtal mot de CSV-filer du laddade ner tidigare.

training_set = pd.read_csv("E:/boston_train.csv", skipinitialspace=True,skiprows=1, names=COLUMNS)
test_set = pd.read_csv("E:/boston_test.csv", skipinitialspace=True,skiprows=1, names=COLUMNS)
prediction_set = pd.read_csv("E:/boston_predict.csv", skipinitialspace=True,skiprows=1, names=COLUMNS)

Du kan skriva ut formen på data.

print(training_set.shape, test_set.shape, prediction_set.shape)

Produktion

(400, 10) (100, 10) (6, 10)

Observera att etiketten, det vill säga ditt y, ingår i datamängden. Så du behöver definiera två andra listor: en som endast innehåller objekten och en som endast innehåller etikettens namn. Dessa två listor kommer att berätta för din estimator vilka objekten i datamängden är och vilket kolumnnamn som är etiketten.

Det görs med koden nedan.

FEATURES = ["crim", "zn", "indus", "nox", "rm",
                 "age", "dis", "tax", "ptratio"]
LABEL = "medv"

Steg 2) Konvertera data

Du måste konvertera de numeriska variablerna till rätt format. TensorFlow tillhandahåller en metod för att konvertera en kontinuerlig variabel: tf.feature_column.numeric_column().

I föregående steg definierade du en lista med funktioner som du vill inkludera i modellen. Nu kan du använda den här listan för att konvertera dem till numeriska data. Om du vill exkludera funktioner från din modell kan du gärna ta bort en eller flera variabler från listan FEATURES innan du konstruerar feature_cols.

Observera att du kommer att använda en Python listförståelse med listfunktionerna FEATURES för att skapa en ny lista med namnet feature_cols. Det hjälper dig att undvika att skriva tf.feature_column.numeric_column() nio gånger. Listförståelse är ett snabbare och renare sätt att skapa nya listor.

feature_cols = [tf.feature_column.numeric_column(k) for k in FEATURES]

Steg 3) Definiera estimatorn

I det här steget behöver du definiera estimatorn. TensorFlow tillhandahåller sex förbyggda standardiserade estimatorer, tre för klassificeringsuppgifter och tre för TensorFlow-regressionsuppgifter:

  • Regressor
    • DNNRegressor
    • LinjärRegressor
    • DNNLinjär Kombinerad Regressor
  • klassificera
    • DNNklassificerare
    • LinearClassifier
    • DNNLinearCombinedClassifier

I den här handledningen kommer du att använda den linjära regressorn. För att komma åt denna funktion måste du använda tf.estimator.

Funktionen behöver två argument:

  • feature_columns: innehåller variablerna som ska inkluderas i modellen
  • model_dir: sökväg för att lagra grafen, spara modellparametrarna och så vidare

TensorFlow skapar automatiskt en mapp med namnet train i din arbetskatalog. Du måste använda den här sökvägen för att komma åt TensorBoard, som visas i TensorFlow-regressionsexemplet nedan.

estimator = tf.estimator.LinearRegressor(
        feature_columns=feature_cols,
        model_dir="train")

Produktion

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train', '_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 0x1a215dc550>, '_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}

Det knepiga med TensorFlow är sättet att mata modellen. TensorFlow är utformat för att fungera med parallell beräkning och mycket stora datamängder. På grund av begränsade maskinresurser är det omöjligt att mata modellen med all data på en gång. För det måste du mata en batch data varje gång. Observera att vi talar om enorma datamängder med miljontals eller fler poster. Om du inte lägger till en batch kommer du att få ett minnesfel.

Till exempel, om din data innehåller 100 observationer och du definierar en batchstorlek på 10, betyder det att modellen kommer att se 10 observationer för varje iteration (10*10).

När modellen har sett all data avslutar den en epok. En epok definierar hur många gånger du vill att modellen ska se data. Det är bättre att ställa in det här steget till ingen och låta modellen utföra ett visst antal iterationer.

En andra information att lägga till är om du vill blanda data före varje iteration. Under träningen är det viktigt att blanda data så att modellen inte lär sig ett specifikt mönster i datamängden. Om modellen lär sig detaljerna i det underliggande datamönstret kommer den att ha svårt att generalisera förutsägelsen för osedda data. Detta kallas överanpassning. Modellen presterar bra på träningsdata men kan inte förutsäga korrekt för osedda data.

TensorFlow gör dessa två steg enkla att utföra. När data skickas till pipelinen vet den hur många observationer den behöver (batch) och om den behöver blanda data.

För att instruera TensorFlow hur modellen ska matas kan du använda pandas_input_fn. Detta objekt behöver fem parametrar:

  • x: funktionsdata
  • y: etikettdata
  • batch_size: batch. Som standard 128
  • num_epoch: antal epoker, som standard 1
  • blanda: blanda informationen eller inte. Som standard är ingen

Du behöver mata modellen många gånger, så du definierar en funktion för att upprepa processen. Anropa funktionen get_input_fn.

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)

Den vanliga metoden för att utvärdera en modells prestanda är att:

  • Träna modellen
  • Utvärdera modellen på en annan datamängd
  • Gör en förutsägelse

TensorFlow-estimatorn tillhandahåller tre olika funktioner för att enkelt utföra dessa tre steg.

Steg 4) Träna modellen

Du kan använda estimatorns train-metoden för att anpassa modellen. Tågestimatorn behöver en input_fn och ett antal steg. Du kan använda funktionen du skapade ovan för att mata modellen. Sedan instruerar du modellen att iterera 1000 gånger. Observera att du inte anger antalet epoker; du låter modellen iterera 1000 gånger. Om du ställer in antalet epoker till 1 kommer modellen att iterera fyra gånger, eftersom det finns 400 poster i träningsuppsättningen och batchstorleken är 128:

  1. 128 rader
  2. 128 rader
  3. 128 rader
  4. 16 rader

Därför är det enklare att ställa in antalet epoker till inga och definiera antalet iterationer, som visas i TensorFlow-klassificeringsexemplet nedan.

estimator.train(input_fn=get_input_fn(training_set,
                                           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/model.ckpt.
INFO:tensorflow:loss = 83729.64, step = 1
INFO:tensorflow:global_step/sec: 238.616
INFO:tensorflow:loss = 13909.657, step = 101 (0.420 sec)
INFO:tensorflow:global_step/sec: 314.293
INFO:tensorflow:loss = 12881.449, step = 201 (0.320 sec)
INFO:tensorflow:global_step/sec: 303.863
INFO:tensorflow:loss = 12391.541, step = 301 (0.327 sec)
INFO:tensorflow:global_step/sec: 308.782
INFO:tensorflow:loss = 12050.5625, step = 401 (0.326 sec)
INFO:tensorflow:global_step/sec: 244.969
INFO:tensorflow:loss = 11766.134, step = 501 (0.407 sec)
INFO:tensorflow:global_step/sec: 155.966
INFO:tensorflow:loss = 11509.922, step = 601 (0.641 sec)
INFO:tensorflow:global_step/sec: 263.256
INFO:tensorflow:loss = 11272.889, step = 701 (0.379 sec)
INFO:tensorflow:global_step/sec: 254.112
INFO:tensorflow:loss = 11051.9795, step = 801 (0.396 sec)
INFO:tensorflow:global_step/sec: 292.405
INFO:tensorflow:loss = 10845.855, step = 901 (0.341 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train/model.ckpt.
INFO:tensorflow:Loss for final step: 5925.9873.

Du kan kontrollera TensorBoard med följande kommando:

activate hello-tf
# For MacOS
tensorboard --logdir=./train
# For Windows
tensorboard --logdir=train

Steg 5) Utvärdera din modell

Du kan utvärdera passformen för din modell på testsetet med koden nedan:

ev = estimator.evaluate(
          input_fn=get_input_fn(test_set,
          num_epochs=1,
          n_batch = 128,
          shuffle=False))

Produktion

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-13-01:43:13
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-13-01:43:13
INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.15896, global_step = 1000, loss = 3215.896

Du kan skriva ut förlusten med koden nedan:

loss_score = ev["loss"]
print("Loss: {0:f}".format(loss_score))

Produktion

Loss: 3215.895996

Modellen har en förlust på 3215. Du kan kontrollera den sammanfattande statistiken för att få en uppfattning om hur stort felet är.

training_set['medv'].describe()

Produktion

count    400.000000
mean      22.625500
std        9.572593
min        5.000000
25%       16.600000
50%       21.400000
75%       25.025000
max       50.000000
Name: medv, dtype: float64

Från den sammanfattande statistiken ovan vet du att genomsnittspriset för ett hus är 22 tusen, med ett lägsta pris på 5 tusen och ett högsta pris på 50 tusen. Eftersom den rapporterade förlusten är medelkvadratfelet, är det typiska felet i de ursprungliga enheterna ungefär kvadratroten ur 32.16, vilket är cirka 5.7 tusen dollar.

Steg 6) Gör förutsägelsen

Slutligen kan du använda estimatorn TensorFlows predikteringsmetod för att uppskatta värdet av sex hus i Boston.

y = estimator.predict(
         input_fn=get_input_fn(prediction_set,
         num_epochs=1,
         n_batch = 128,
         shuffle=False))

För att skriva ut de uppskattade värdena kan du använda den här koden:

predictions = list(p["predictions"] for p in itertools.islice(y, 6))
print("Predictions: {}".format(str(predictions)))

Produktion

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Predictions: [array([32.297546], dtype=float32), array([18.96125], dtype=float32), array([27.270979], dtype=float32), array([29.299236], dtype=float32), array([16.436684], dtype=float32), array([21.460876], dtype=float32)]

Modellen prognostiserar följande värden:

Huset Förutsägelse
1 32.29
2 18.96
3 27.27
4 29.29
5 16.43
6 21.46

Observera att vi inte vet det verkliga värdet av dessa sex hus. I handledningen för djupinlärning kommer du att försöka besegra den linjära modellen.

NumPy-lösning

Det här avsnittet förklarar hur man tränar modellen med hjälp av en NumPy-estimator för att mata in data. Metoden är densamma, förutom att du använder numpy_input_fn-estimatorn.

Läs samma tre CSV-filer, men behåll bara de råa NumPy-arrayererna med .values.

training_set_n = pd.read_csv("E:/boston_train.csv").values
test_set_n = pd.read_csv("E:/boston_test.csv").values
prediction_set_n = pd.read_csv("E:/boston_predict.csv").values

Steg 1) Importera data

Först och främst måste du skilja funktionsvariablerna från etiketten. Du behöver göra detta för träningsdata och utvärderingsdata. Det är snabbare att definiera en funktion för att dela upp data.

def prepare_data(df):
        X_train = df[:, :-3]
        y_train = df[:,-3]
        return X_train, y_train

Du kan använda funktionen för att dela upp etiketten från tågets funktioner och utvärdera datauppsättningar.

X_train, y_train = prepare_data(training_set_n)
X_test, y_test = prepare_data(test_set_n)

Du måste exkludera den sista kolumnen i prediktionsdatauppsättningen eftersom den bara innehåller NaN.

x_predict = prediction_set_n[:, :-2]

Bekräfta arrayens form. Observera att etiketten inte ska ha en andra dimension, vilket betyder (400,).

print(X_train.shape, y_train.shape, x_predict.shape)

Produktion

(400, 9) (400,) (6, 9)

Du kan konstruera funktionskolumnerna enligt följande:

feature_columns = [      tf.feature_column.numeric_column('x', shape=X_train.shape[1:])]

Estimatorn definieras som tidigare: du anger funktionskolumnerna och var grafen ska sparas.

estimator = tf.estimator.LinearRegressor(
         feature_columns=feature_columns,
         model_dir="train1")

Produktion

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train1', '_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 0x1a218d8f28>, '_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}

Du kan använda NumPy-estimatorn för att mata in data till modellen och sedan träna modellen. Observera att vi definierar funktionen input_fn i förväg för att underlätta läsbarheten.

# Train the estimator
train_input = tf.estimator.inputs.numpy_input_fn(
           x={"x": X_train},
           y=y_train,
           batch_size=128,
           shuffle=False,
           num_epochs=None)
estimator.train(input_fn = train_input,steps=5000)

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 train1/model.ckpt.
INFO:tensorflow:loss = 83729.64, step = 1
INFO:tensorflow:global_step/sec: 490.057
INFO:tensorflow:loss = 13909.656, step = 101 (0.206 sec)
INFO:tensorflow:global_step/sec: 788.986
INFO:tensorflow:loss = 12881.45, step = 201 (0.126 sec)
INFO:tensorflow:global_step/sec: 736.339
INFO:tensorflow:loss = 12391.541, step = 301 (0.136 sec)
INFO:tensorflow:global_step/sec: 383.305
INFO:tensorflow:loss = 12050.561, step = 401 (0.260 sec)
INFO:tensorflow:global_step/sec: 859.832
INFO:tensorflow:loss = 11766.133, step = 501 (0.117 sec)
INFO:tensorflow:global_step/sec: 804.394
INFO:tensorflow:loss = 11509.918, step = 601 (0.125 sec)
INFO:tensorflow:global_step/sec: 753.059
INFO:tensorflow:loss = 11272.891, step = 701 (0.134 sec)
INFO:tensorflow:global_step/sec: 402.165
INFO:tensorflow:loss = 11051.979, step = 801 (0.248 sec)
INFO:tensorflow:global_step/sec: 344.022
INFO:tensorflow:loss = 10845.854, step = 901 (0.288 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train1/model.ckpt.
INFO:tensorflow:Loss for final step: 5925.985.
Out[23]:
<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a1b6ea860>

Du replikerar samma steg med en annan inmatningsfunktion för att utvärdera din modell.

eval_input = tf.estimator.inputs.numpy_input_fn(
       x={"x": X_test},
       y=y_test,
       shuffle=False,
       batch_size=128,
       num_epochs=1)
   estimator.evaluate(eval_input,steps=None)

Produktion

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-13-01:44:00
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-13-01:44:00
INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.158947, global_step = 1000, loss = 3215.8945
Out[24]:
{'average_loss': 32.158947, 'global_step': 1000, 'loss': 3215.8945}

Slutligen kan du beräkna förutsägelsen. Den bör likna Pandas resultat.

test_input = tf.estimator.inputs.numpy_input_fn(
        x={"x": x_predict},
        batch_size=128,
        num_epochs=1,
        shuffle=False)
        y = estimator.predict(test_input)

predictions = list(p["predictions"] for p in itertools.islice(y, 6))
print("Predictions: {}".format(str(predictions)))

Produktion

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Predictions: [array([32.297546], dtype=float32), array([18.961248], dtype=float32), array([27.270979], dtype=float32), array([29.299242], dtype=float32), array([16.43668], dtype=float32), array([21.460878], dtype=float32)]

TensorFlow-lösning

Det sista avsnittet är tillägnat en ren TensorFlow lösning. Den här metoden är något mer komplicerad än de andra två.

Observera att om du använder en Jupyter anteckningsbok, måste du starta om och rensa kärnan för att köra den här sessionen.

TensorFlow har byggt ett utmärkt verktyg för att skicka data till pipelinen. I det här avsnittet ska du bygga input_fn-funktionen själv.

Steg 1) Definiera sökvägen och formatet för data

Först och främst deklarerar du två variabler med sökvägen till CSV-filerna. Observera att du har två filer, en för träningsmängden och en för testmängden.

import tensorflow as tf
df_train = "E:/boston_train.csv"
df_eval = "E:/boston_test.csv"

Sedan behöver du definiera de kolumner du vill använda från CSV-filen. Vi kommer att använda alla. Efter det behöver du deklarera typen för varje variabel.

Flytvariabler definieras av [0.]

COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age",
                "dis", "tax", "ptratio", "medv"]
RECORDS_ALL = [[0.0], [0.0], [0.0], [0.0],[0.0],[0.0],[0.0],[0.0],[0.0],[0.0]]

Steg 2) Definiera funktionen input_fn

Funktionen kan delas in i tre delar:

  1. Importera data
  2. Skapa iteratorn
  3. Konsumera data

Nedan följer den övergripande koden för att definiera funktionen. Koden kommer att förklaras senare.

def input_fn(data_file, batch_size, num_epoch = None):
       # Step 1
          def parse_csv(value):
          columns = tf.decode_csv(value, record_defaults= RECORDS_ALL)
          features = dict(zip(COLUMNS, columns))
          #labels = features.pop('median_house_value')
          labels =  features.pop('medv')
          return features, labels

          # Extract lines from input files using the Dataset API.
          dataset = (tf.data.TextLineDataset(data_file) # Read text file
          .skip(1) # Skip header row
          .map(parse_csv))

          dataset = dataset.repeat(num_epoch)
          dataset = dataset.batch(batch_size)
          # Step 3
          iterator = dataset.make_one_shot_iterator()
          features, labels = iterator.get_next()
          return features, labels

Importera data

För en CSV-fil läser dataset-metoden en rad i taget. För att bygga datasetet måste du använda objektet TextLineDataset. Din dataset har en rubrik, så du behöver använda skip(1) för att hoppa över den första raden. I det här skedet läser du bara data och exkluderar rubriken i pipelinen. För att mata modellen måste du separera funktionerna från etiketten. Metoden som används för att tillämpa transformationer på data är map.

Den här metoden anropar en funktion som du skapar för att instruera hur data ska transformeras. Kortfattat behöver du skicka data till TextLineDataset-objekt, exkludera rubriken och tillämpa en transformation som instrueras av en funktion.

Code förklaring

  • tf.data.TextLineDataset(data_file): den här raden läser CSV-filen
  • .skip(1): hoppar över rubriken
  • .map(parse_csv)): analyserar posterna till tensorerna

Du måste definiera en funktion för att instruera kartobjektet. Du kan anropa den här funktionen parse_csv.

Den här funktionen analyserar CSV-filen med metoden tf.decode_csv och deklarerar funktionerna och etiketten. Funktionerna kan deklareras som en ordbok eller en tupel. Du använder ordboksmetoden eftersom den är mer praktisk.

Code förklaring

  • tf.decode_csv(värde, record_defaults= RECORDS_ALL): metoden decode_csv använder utdata från TextLineDataset för att läsa CSV-filen. record_defaults instruerar TensorFlow om kolumntyperna. I TensorFlow 2.x finns den här symbolen på tf.io.decode_csv.
  • dict(zip(COLUMNS, columns)): fyller ordboken med alla kolumner t.ex.tracted under denna databehandling
  • features.pop('medv'): exkluderar målvariabeln från funktionsvariablerna och skapar en etikettvariabel

Datasetet behöver ytterligare element för att iterativt mata tensorerna. Du måste lägga till metoden "repeat" för att tillåta att datasetet fortsätter att mata modellen i all oändlighet. Om du inte lägger till metoden kommer modellen bara att iterera en gång och sedan ge ett fel eftersom ingen mer data matas in i pipelinen.

Efter det kan du styra batchstorleken med batchmetoden. Det innebär att du anger för datamängden hur mycket data du vill skicka in i pipelinen för varje iteration. Om du anger en stor batchstorlek kommer modellen att vara långsam.

Steg 3) Skapa iteratorn

Nu är du redo för det andra steget: skapa en iterator för att returnera elementen i datamängden.

Det enklaste sättet att skapa en operator är med metoden make_one_shot_iterator.

Efter det kan du skapa funktionerna och etiketterna från iteratorn.

Steg 4) Konsumera data

Du kan kontrollera vad som händer med funktionen input_fn. Du måste anropa funktionen i en session för att förbruka data. Du försöker med en batchstorlek lika med 1.

Observera att den skriver ut funktionerna i en ordbok och etiketten som en array.

Den första raden i CSV-filen visas. Du kan försöka köra den här koden många gånger med olika batchstorlekar.

next_batch = input_fn(df_train, batch_size = 1, num_epoch = None)
with tf.Session() as sess:
     first_batch  = sess.run(next_batch)
     print(first_batch)

Produktion

({'crim': array([2.3004], dtype=float32), 'zn': array([0.], dtype=float32), 'indus': array([19.58], dtype=float32), 'nox': array([0.605], dtype=float32), 'rm': array([6.319], dtype=float32), 'age': array([96.1], dtype=float32), 'dis': array([2.1], dtype=float32), 'tax': array([403.], dtype=float32), 'ptratio': array([14.7], dtype=float32)}, array([23.8], dtype=float32))

Steg 5) Definiera funktionskolumnen

Du måste definiera de numeriska kolumnerna enligt följande:

X1= tf.feature_column.numeric_column('crim')
X2= tf.feature_column.numeric_column('zn')
X3= tf.feature_column.numeric_column('indus')
X4= tf.feature_column.numeric_column('nox')
X5= tf.feature_column.numeric_column('rm')
X6= tf.feature_column.numeric_column('age')
X7= tf.feature_column.numeric_column('dis')
X8= tf.feature_column.numeric_column('tax')
X9= tf.feature_column.numeric_column('ptratio')

Observera att du måste kombinera alla variabler i en hink.

base_columns = [X1, X2, X3,X4, X5, X6,X7, X8, X9]

Steg 6) Bygg modellen

Du kan träna modellen med estimatorn LinearRegressor.

model = tf.estimator.LinearRegressor(feature_columns=base_columns, model_dir='train3')

Produktion

INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train3', '_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 0x1820a010f0>, '_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}

Du måste använda en lambda-funktion för att låta dig skriva argumenten för funktionen input_fn. Om du inte använder en lambdafunktion kan du inte träna modellen.

# Train the estimator
model.train(steps =1000,
          input_fn= lambda : input_fn(df_train,batch_size=128, num_epoch = None))

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 train3/model.ckpt.
INFO:tensorflow:loss = 83729.64, step = 1
INFO:tensorflow:global_step/sec: 72.5646
INFO:tensorflow:loss = 13909.657, step = 101 (1.380 sec)
INFO:tensorflow:global_step/sec: 101.355
INFO:tensorflow:loss = 12881.449, step = 201 (0.986 sec)
INFO:tensorflow:global_step/sec: 109.293
INFO:tensorflow:loss = 12391.541, step = 301 (0.915 sec)
INFO:tensorflow:global_step/sec: 102.235
INFO:tensorflow:loss = 12050.5625, step = 401 (0.978 sec)
INFO:tensorflow:global_step/sec: 104.656
INFO:tensorflow:loss = 11766.134, step = 501 (0.956 sec)
INFO:tensorflow:global_step/sec: 106.697
INFO:tensorflow:loss = 11509.922, step = 601 (0.938 sec)
INFO:tensorflow:global_step/sec: 118.454
INFO:tensorflow:loss = 11272.889, step = 701 (0.844 sec)
INFO:tensorflow:global_step/sec: 114.947
INFO:tensorflow:loss = 11051.9795, step = 801 (0.870 sec)
INFO:tensorflow:global_step/sec: 111.484
INFO:tensorflow:loss = 10845.855, step = 901 (0.897 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train3/model.ckpt.
INFO:tensorflow:Loss for final step: 5925.9873.
Out[8]:
<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x18225eb8d0>

Du kan utvärdera passformen för din modell på testsetet med koden nedan:

results = model.evaluate(steps =None,input_fn=lambda: input_fn(df_eval, batch_size =128, num_epoch = 1))
for key in results:
print("   {}, was: {}".format(key, results[key]))

Produktion

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-13-02:06:02
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train3/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-13-02:06:02
INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.15896, global_step = 1000, loss = 3215.896
   average_loss, was: 32.158958435058594
   loss, was: 3215.89599609375
   global_step, was: 1000

Det sista steget är att förutsäga målets värde baserat på värdet på funktionsmatrisen. Du kan skriva en ordbok med de värden du vill förutsäga. Din modell har nio funktioner, så du måste ange ett värde för varje. Modellen kommer att ge en förutsägelse för var och en av dem.

I koden nedan skriver du värdena för varje funktion som finns i df_predict CSV-filen.

Du behöver skriva en ny input_fn-funktion eftersom det inte finns någon etikett i datamängden. Du kan använda from_tensors API från Dataset-objektet.

prediction_input = {
          'crim': [0.03359,5.09017,0.12650,0.05515,8.15174,0.24522],
          'zn': [75.0,0.0,25.0,33.0,0.0,0.0],
          'indus': [2.95,18.10,5.13,2.18,18.10,9.90],
          'nox': [0.428,0.713,0.453,0.472,0.700,0.544],
          'rm': [7.024,6.297,6.762,7.236,5.390,5.782],
          'age': [15.8,91.8,43.4,41.1,98.9,71.7],
          'dis': [5.4011,2.3682,7.9809,4.0220,1.7281,4.0317],
          'tax': [252,666,284,222,666,304],
          'ptratio': [18.3,20.2,19.7,18.4,20.2,18.4]
     }
     def test_input_fn():
     dataset = tf.data.Dataset.from_tensors(prediction_input)
     return dataset

     # Predict all our prediction_input
     pred_results = model.predict(input_fn=test_input_fn)

Slutligen skriver du ut förutsägelserna.

for pred in enumerate(pred_results):
print(pred)

Produktion

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train3/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
(0, {'predictions': array([32.297546], dtype=float32)})
(1, {'predictions': array([18.96125], dtype=float32)})
(2, {'predictions': array([27.270979], dtype=float32)})
(3, {'predictions': array([29.299236], dtype=float32)})
(4, {'predictions': array([16.436684], dtype=float32)})
(5, {'predictions': array([21.460876], dtype=float32)})

INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train3/model.ckpt-5000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. (0, {'predictions': array([35.60663], dtype=float32)}) (1, {'predictions': array([22.298521], dtype=float32)}) (2, {'predictions': array([25.74533], dtype=float32)}) (3, {'predictions': array([35.126694], dtype=float32)}) (4, {'predictions': array([17.94416], dtype=float32)}) (5, {'predictions': array([22.606628], dtype=float32)})

Alla tre pipelines returnerar samma sex förutsägelser, vilket bekräftar att valet mellan Pandas, NumPy och en inbyggd TensorFlow-datauppsättning är en fråga om bekvämlighet, inte om noggrannhet.

Vanliga frågor

Nej. TensorFlow markerade Estimatorer och funktionskolumner som helt föråldrade i version 2.12 och tog bort dem i 2.16. Fäst TensorFlow 1.15 eller 2.15 för att köra denna kod oförändrad, eller skriv om modellen med Keras-lager, vilket TensorFlow-teamet nu rekommenderar.

Ladda CSV-filerna med pandas, skala de nio funktionerna med ett normaliseringslager, stapla sedan en enda Dense(1)-enhet. Kompilera med en optimerare och mean_squared_error loss, anropa sedan anpassning. En Dense-enhet utan aktivering är en linjär regression.

Börja runt 0.01 och justera med tio faktorer. En hastighet som är för liten behöver betydligt fler iterationer för att konvergera, medan en hastighet som är för stor gör att förlusten oscillerar. Rita förlustkurvan och behåll den största hastigheten som fortfarande faller jämnt.

scikit-learn tog bort load_boston i version 1.2 på grund av etiska farhågor kring en konstruerad rasvariabel. Den här handledningen läser vanliga CSV-filer, så nedladdningslänken fungerar fortfarande, men nya projekt bör istället använda datamängderna för bostäder i Kalifornien eller Ames.

Root Mean Square Error återställer de ursprungliga enheterna, Mean Absolute Error motverkar extremvärden och R-squared rapporterar den förklarade andelen av variansen. Rapportera ett absolutfelmått tillsammans med R-squared, eftersom ett högt R-squared fortfarande kan dölja stora individuella prediktionsfel.

Linjär regression förutsäger ett kontinuerligt tal, såsom ett huspris. linjär klassificerare förutsäger en diskret klassetikett. Båda passar en viktad summa av egenskaperna, men klassificeraren skickar den summan genom en beslutströskel.

Automatiserade pipelines poängsätter funktioner med lassoregularisering, ömsesidig information eller permutationsviktighet, och tar sedan bort de svagaste. AutoML-verktyg söker efter förbehandlings- och modellalternativ tillsammans, så att du lägger mindre tid på att handplocka vilka kolumner som hör hemma i feature_cols.

Copilot utarbetar snabbt standardversioner, inklusive inmatningsfunktioner, listor med funktionskolumner och utvärderingsloopar. Behandla varje förslag som ett utkast, eftersom det ofta genererar föråldrade Estimator-anrop. Kontrollera varje genererad symbol mot det aktuella TensorFlow API:et innan du kör det.

Sammanfatta detta inlägg med: