Zelfstudie lineaire regressie met TensorFlow [Voorbeelden]
โก Slimme samenvatting
Lineaire regressie in TensorFlow modelleert de relatie tussen numerieke kenmerken en een continue doelwaarde. Deze handleiding traint een voorspeller voor huizenprijzen in Boston op drie verschillende manieren: met behulp van Pandas, NumPy en native TensorFlow-inputpipelines met de LinearRegressor-estimator.
Wat is lineaire regressie?
Lineaire regressie Regressieanalyse is een statistische methode om relaties tussen twee variabelen te modelleren. Deze modellering vindt plaats tussen een scalaire respons en een of meer verklarende variabelen. De relatie met รฉรฉn verklarende variabele wordt enkelvoudige lineaire regressie genoemd, en met meer dan รฉรฉn verklarende variabele meervoudige lineaire regressie.
TensorFlow biedt tools om volledige controle over de berekeningen te hebben. Dit gebeurt met de low-level API. Bovendien is TensorFlow uitgerust met een breed scala aan API's om er vele uit te voeren machine learning algoritmen. Dit is de API op hoog niveau, en TensorFlow noemt ze estimators.
- API op laag niveau: Bouw de architectuur en de optimalisatie van het model helemaal vanaf nul op. Dat is ingewikkeld voor een beginner.
- API op hoog niveauDefinieer het algoritme. Het is gebruiksvriendelijk. TensorFlow biedt een toolbox genaamd taxateur construeren, trainen, evalueren en een voorspelling doen.
In deze zelfstudie gebruikt u de alleen schattersDe berekeningen zijn sneller en eenvoudiger te implementeren. Het eerste deel legt uit hoe je de gradient descent optimizer gebruikt om een โโlineaire regressie te trainen in TensorFlow. In een tweede deel ga je de Boston-dataset gebruiken om de prijs van een huis te voorspellen met behulp van een TensorFlow-estimator.
Hoe een lineair regressiemodel te trainen
Voordat we beginnen met het trainen van het model, laten we eerst eens kijken wat lineaire regressie precies inhoudt.
Stel je voor dat je twee variabelen hebt, x en y, en het is jouw taak om de waarde van y te voorspellen op basis van de waarde van x. Als je de gegevens plot, zie je een positieve relatie tussen je onafhankelijke variabele, x, en je afhankelijke variabele, y, zoals de onderstaande spreidingsgrafiek laat zien.
Je kunt zien dat als x=1, y ongeveer gelijk zal zijn aan 6, en als x=2, y ongeveer 8.5 zal zijn.
Dit is geen erg nauwkeurige methode en is foutgevoelig, vooral bij een dataset met honderdduizenden punten.
Een lineaire regressie wordt geรซvalueerd met een vergelijking. De variabele y wordt verklaard door een of meerdere covariaten. In uw voorbeeld is er slechts รฉรฉn afhankelijke variabele. Als je deze vergelijking moet schrijven, wordt het:
Met:
is de vertekening. Dat wil zeggen, als x=0, dan is y=
is het gewicht dat geassocieerd is met x
Dit is het residu, oftewel de fout van het model. Het omvat wat het model niet kan leren uit de data.
Stel je voor dat je het model toepast en de volgende oplossing vindt voor:
= 3.8
= 2.78
Je kunt deze getallen in de vergelijking vervangen, dan wordt het:
y= 3.8 + 2.78x
Je hebt nu een betere manier om de waarden voor y te vinden. Je kunt x namelijk vervangen door elke gewenste waarde om y te voorspellen. In de onderstaande afbeelding hebben we x in de vergelijking vervangen door alle waarden uit de dataset en het resultaat weergegeven in een grafiek.
De rode lijn geeft de geschatte waarde weer, oftewel de waarden van y voor elke waarde van x. Je hoeft de waarde van x niet te zien om y te voorspellen; voor elke x is er een waarde die bij de rode lijn hoort. Je kunt ook voorspellingen doen voor waarden van x groter dan 2.
Als je de lineaire regressie wilt uitbreiden naar meer covariaten, kun je dat doen door meer variabelen aan het model toe te voegen. Het verschil tussen traditionele analyse en lineaire regressie is dat lineaire regressie kijkt naar hoe y reageert op elke variabele x afzonderlijk.
Laten we een voorbeeld bekijken. Stel, je wilt de omzet van een ijssalon voorspellen. De dataset bevat verschillende gegevens, zoals het weer (regenachtig, zonnig, bewolkt) en klantgegevens (salaris, geslacht, burgerlijke staat).
Traditionele analyses proberen de verkoop te voorspellen door bijvoorbeeld het gemiddelde van elke variabele te berekenen en de verkoop voor verschillende scenario's te schatten. Dit leidt tot slechte voorspellingen en beperkt de analyse tot het gekozen scenario.
Als u lineaire regressie gebruikt, kunt u deze vergelijking schrijven:
Het algoritme zal de beste oplossing voor de gewichten vinden; dat wil zeggen dat het zal proberen de kosten te minimaliseren, oftewel het verschil tussen de aangepaste lijn en de datapunten.
Hoe het algoritme werkt
Het onderstaande diagram vat de cyclus samen die het algoritme herhaalt: gewichten kiezen, y voorspellen, de fout meten en de gewichten corrigeren.
Het algoritme kiest voor elk een willekeurig getal en
en vervang de waarde van x om de voorspelde waarde van y te krijgen. Als de dataset 100 waarnemingen bevat, berekent het algoritme 100 voorspelde waarden.
We kunnen de fout berekenen, opgemerkt De foutmarge van het model is het verschil tussen de voorspelde waarde en de werkelijke waarde. Een positieve foutmarge betekent dat het model de voorspelling van y onderschat, en een negatieve foutmarge betekent dat het model de voorspelling van y overschat.
Je doel is om het kwadraat van de fout te minimaliseren. Het algoritme berekent het gemiddelde van de kwadratische fout. Deze stap wordt foutminimalisatie genoemd. Voor lineaire regressie is dit de Gemiddelde kwadratische fout, ook wel MSE genoemd. Wiskundig gezien is het:
Waar:
zijn de gewichten, dus
verwijst naar de voorspelde waarde
- y zijn de echte waarden
- m is het aantal waarnemingen
Merk op dat betekent dat het de transpositie van de matrices gebruikt. De
is de wiskundige notatie van het gemiddelde.
Het doel is om de beste te vinden dat de MSE minimaliseert.
Als de gemiddelde fout groot is, betekent dit dat het model slecht presteert en dat de gewichten niet goed zijn gekozen. Om de gewichten te corrigeren, moet u een optimizer gebruiken. De traditionele optimizer wordt genoemd Gradient Afdaling.
De gradiรซntdaling berekent de afgeleide en verlaagt of verhoogt het gewicht. Als de afgeleide positief is, wordt het gewicht verlaagd. Als de afgeleide negatief is, wordt het gewicht verhoogd. Het model werkt de gewichten bij en berekent de fout opnieuw. Dit proces wordt herhaald totdat de fout niet meer verandert. Elke iteratie wordt een stap genoemd. herhalingBovendien worden de gradiรซnten vermenigvuldigd met een leerfrequentie, die de snelheid van het leerproces aangeeft.
Als de leerfrequentie te laag is, duurt het erg lang voordat het algoritme convergeert, omdat er veel meer iteraties nodig zijn. Als de leerfrequentie te hoog is, convergeert het algoritme mogelijk nooit. De onderstaande verliescurve geeft de fout weer ten opzichte van het aantal iteraties voor deze dataset.
Zoals je op de afbeelding hierboven kunt zien, herhaalt het model het proces ongeveer 20 keer voordat een stabiele waarde voor de gewichten wordt gevonden en daarmee de laagste fout wordt bereikt.
Merk op dat de fout niet gelijk is aan nul, maar stabiliseert rond de 5. Dit betekent dat het model een typische fout van 5 maakt. Als u de fout wilt verkleinen, moet u meer informatie aan het model toevoegen, zoals meer variabelen, of andere schatters gebruiken.
Je herinnert je de eerste vergelijking nog:
De uiteindelijke gewichten zijn 3.8 en 2.78. De video hieronder laat zien hoe de gradiรซntafdalingsmethode de verliesfunctie optimaliseert om deze gewichten te vinden.
Hoe u een lineaire regressie traint met TensorFlow
Nu u beter begrijpt wat er achter de motorkap gebeurt, bent u klaar om de schatter-API van TensorFlow te gebruiken om uw eerste lineaire regressie te trainen met behulp van TensorFlow.
Versie-opmerking: De onderstaande workflow voor het schatten van gegevens is geschreven voor TensorFlow 1.x en de eerste 2.x-versies. TensorFlow heeft de tf.estimator en tf.feature_column API's zijn volledig afgekeurd in versie 2.12 en Estimators zijn verwijderd in versie 2.16. Voer deze code op een huidige installatie uit binnen een TensorFlow 1.15 of 2.x-omgeving.tf.compat.v1 omgeving, of porteer het naar Keras, waar tf.keras.layers.Dense(1) Daarnaast vervangen voorverwerkingslagen de LinearRegressor en de featurekolommen. De concepten โ features, labels, batches, epochs, MSE en gradient descent โ blijven ongewijzigd.
Je gebruikt de Boston-dataset, die de volgende variabelen bevat.
| Veranderlijk | Beschrijving |
| crimineel | criminaliteit per hoofd van de bevolking per stad |
| zn | aandeel van de residentiรซle grond bestemd voor kavels van meer dan 25,000 vierkante meter. |
| onnodig | aandeel van het areaal niet-detailhandelsbedrijven per stad. |
| nox | concentratie stikstofoxiden |
| rm | gemiddeld aantal kamers per woning |
| leeftijd | aandeel koopwoningen gebouwd vรณรณr 1940 |
| dis | gewogen afstanden tot vijf werkgelegenheidscentra in Boston |
| belasting | onroerendgoedbelasting over de volledige waarde per dollar 10,000 |
| ptratio | leerling-leraar-ratio per stad |
| met V | Mediaanwaarde van koopwoningen in duizend dollar |
U maakt drie verschillende datasets:
| dataset | doel van de persoon | vorm |
| Training | Train het model en verkrijg de gewichten | 400, 10 |
| Evaluatie | Evalueer de prestaties van het model op basis van onzichtbare gegevens | 100, 10 |
| Voorspellen | Gebruik het model om de woningwaarde te voorspellen op basis van nieuwe gegevens | 6, 10 |
Het doel is om de kenmerken van de dataset te gebruiken om de waarde van het huis te voorspellen.
Tijdens het tweede deel van de tutorial leer je hoe je TensorFlow op drie verschillende manieren kunt gebruiken om de gegevens te importeren:
- Met Panda's
- Met NumPy
- Alleen TensorFlow
Merk op dat alle drie de opties hetzelfde resultaat opleveren.
Je leert hoe je de API op hoog niveau gebruikt om een โโlineair regressiemodel van TensorFlow te bouwen, te trainen en te evalueren. Als je de API op laag niveau zou gebruiken, zou je de volgende zaken handmatig moeten definiรซren:
- Verliesfunctie
- Optimalisatiemethode: gradiรซntafdaling
- Matrix vermenigvuldiging
- Grafiek en tensor
Dit is omslachtig en ingewikkelder voor een beginner.
Pandas-oplossing
U moet de benodigde bibliotheken importeren om het model te trainen.
import pandas as pd from sklearn import datasets import tensorflow as tf import itertools
Stap 1) Importeer de gegevens met Pandas.
Je definieert de kolomnamen en slaat ze op in COLUMNS. Je kunt pd.read_csv() gebruiken om de gegevens te importeren.
COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio", "medv"]
Richt elke aanroep op de CSV-bestanden die je eerder hebt gedownload.
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)
U kunt de vorm van de gegevens afdrukken.
print(training_set.shape, test_set.shape, prediction_set.shape)
uitgang
(400, 10) (100, 10) (6, 10)
Houd er rekening mee dat het label, oftewel uw y, in de dataset is opgenomen. U moet dus twee andere lijsten definiรซren: รฉรฉn met alleen de kenmerken en รฉรฉn met alleen de naam van het label. Deze twee lijsten vertellen uw estimator welke kenmerken er in de dataset zitten en welke kolomnaam het label is.
Het wordt gedaan met de onderstaande code.
FEATURES = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio"] LABEL = "medv"
Stap 2) Converteer de gegevens
Je moet de numerieke variabelen omzetten naar het juiste formaat. TensorFlow biedt een methode om een โโcontinue variabele om te zetten: tf.feature_column.numeric_column().
In de vorige stap heb je een lijst gedefinieerd met kenmerken die je in het model wilt opnemen. Nu kun je deze lijst gebruiken om ze om te zetten in numerieke gegevens. Als je kenmerken uit je model wilt verwijderen, kun je gerust een of meer variabelen uit de lijst FEATURES verwijderen voordat je feature_cols aanmaakt.
Houd er rekening mee dat u een zult gebruiken Python Met behulp van een list comprehension met de lijst FEATURES creรซer je een nieuwe lijst met de naam feature_cols. Dit voorkomt dat je tf.feature_column.numeric_column() negen keer hoeft te schrijven. Een list comprehension is een snellere en overzichtelijkere manier om nieuwe lijsten te maken.
feature_cols = [tf.feature_column.numeric_column(k) for k in FEATURES]
Stap 3) Definieer de schatter
In deze stap moet u de schatter definiรซren. TensorFlow biedt zes vooraf gedefinieerde schatters, drie voor classificatietaken en drie voor TensorFlow-regressietaken:
- Regressor
- DNNRegressor
- Lineaire regressor
- DNNLinearCombinedRegressor
- classifier
- DNNClassificator
- Lineaire Classificator
- DNNLinearCombinedClassifier
In deze zelfstudie gebruikt u de lineaire regressor. Om toegang te krijgen tot deze functie moet u tf.estimator gebruiken.
De functie heeft twee argumenten nodig:
- feature_columns: bevat de variabelen die in het model moeten worden opgenomen.
- model_dir: pad waar de grafiek, de modelparameters, enzovoort worden opgeslagen.
TensorFlow maakt automatisch een map met de naam 'train' aan in je werkmap. Je moet dit pad gebruiken om toegang te krijgen tot de bestanden. TensorBoard, zoals blijkt uit het onderstaande TensorFlow-regressievoorbeeld.
estimator = tf.estimator.LinearRegressor(
feature_columns=feature_cols,
model_dir="train")
uitgang
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}
Het lastige aan TensorFlow is de manier waarop je het model voedt. TensorFlow is ontworpen voor parallelle berekeningen en zeer grote datasets. Vanwege de beperkingen van de computerbronnen is het onmogelijk om het model in รฉรฉn keer met alle data te voeden. Daarvoor moet je telkens een batch data aanleveren. Let wel, we hebben het hier over enorme datasets met miljoenen records of meer. Als je geen batch toevoegt, krijg je een geheugenprobleem.
Als uw gegevens bijvoorbeeld 100 waarnemingen bevatten en u een batchgrootte van 10 definieert, betekent dit dat het model voor elke iteratie 10 waarnemingen ziet (10*10).
Wanneer het model alle gegevens heeft gezien, is een epoch voltooid. Een epoch bepaalt hoe vaak het model de gegevens moet bekijken. Het is beter om deze stap op 'geen' in te stellen en het model een vast aantal iteraties te laten uitvoeren.
Een tweede belangrijk punt is of je de data wilt schudden vรณรณr elke iteratie. Tijdens de training is het belangrijk om de data te schudden, zodat het model geen specifiek patroon in de dataset leert. Als het model de details van het onderliggende patroon van de data leert, zal het moeite hebben om de voorspelling te generaliseren naar onbekende data. Dit wordt overfitting genoemd. Het model presteert goed op de trainingsdata, maar kan geen correcte voorspellingen doen voor onbekende data.
TensorFlow maakt deze twee stappen eenvoudig. Wanneer de data naar de pipeline gaat, weet het hoeveel observaties het nodig heeft (batch) en of de data geschud moet worden.
Om TensorFlow te instrueren hoe het model moet worden gevoed, kunt u pandas_input_fn gebruiken. Dit object heeft vijf parameters nodig:
- x: kenmerkgegevens
- y: labelgegevens
- batch_grootte: batch. Standaard 128
- num_epoch: aantal epochs, standaard 1
- shuffle: de gegevens al dan niet schudden. Standaard is dit None.
Je moet het model meerdere keren van invoer voorzien, dus definieer je een functie om dit proces te herhalen. Noem deze functie `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)
De gebruikelijke methode om de prestaties van een model te evalueren is:
- Train het model
- Evalueer het model op een andere dataset.
- Een voorspelling doen
De TensorFlow-estimator biedt drie verschillende functies om deze drie stappen eenvoudig uit te voeren.
Stap 4) Train het model
Je kunt de `estimator train`-methode gebruiken om het model te trainen. De `estimator train` vereist een `input_fn` en een aantal stappen. Je kunt de functie die je hierboven hebt gemaakt gebruiken om het model te voeden. Vervolgens geef je het model de opdracht om 1000 keer te itereren. Merk op dat je het aantal epochs niet specificeert; je laat het model 1000 keer itereren. Als je het aantal epochs instelt op 1, dan zal het model vier keer itereren, omdat er 400 records in de trainingsset zijn en de batchgrootte 128 is.
- 128 rijen
- 128 rijen
- 128 rijen
- 16 rijen
Daarom is het eenvoudiger om het aantal epochs op 'none' in te stellen en het aantal iteraties te definiรซren, zoals in het onderstaande TensorFlow-classificatievoorbeeld wordt getoond.
estimator.train(input_fn=get_input_fn(training_set,
num_epochs=None,
n_batch = 128,
shuffle=False),
steps=1000)
uitgang
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.
Je kunt TensorBoard controleren met het volgende commando:
activate hello-tf # For MacOS tensorboard --logdir=./train # For Windows tensorboard --logdir=train
Stap 5) Evalueer uw model
Met de onderstaande code kunt u de pasvorm van uw model op de testset beoordelen:
ev = estimator.evaluate(
input_fn=get_input_fn(test_set,
num_epochs=1,
n_batch = 128,
shuffle=False))
uitgang
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
Met onderstaande code kunt u de schade uitprinten:
loss_score = ev["loss"] print("Loss: {0:f}".format(loss_score))
uitgang
Loss: 3215.895996
Het model heeft een verlies van 3215. Je kunt de samenvattende statistieken bekijken om een โโidee te krijgen van hoe groot de fout is.
training_set['medv'].describe()
uitgang
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
Uit de bovenstaande samenvattende statistieken blijkt dat de gemiddelde prijs van een huis 22 euro is, met een minimumprijs van 5 euro en een maximumprijs van 50 euro. Omdat het gerapporteerde verlies de gemiddelde kwadratische fout is, is de typische fout in de oorspronkelijke eenheden ruwweg de wortel van 32.16, oftewel ongeveer 5.7 euro.
Stap 6) Maak de voorspelling
Tot slot kunt u de TensorFlow predict-methode gebruiken om de waarde van zes huizen in Boston te schatten.
y = estimator.predict(
input_fn=get_input_fn(prediction_set,
num_epochs=1,
n_batch = 128,
shuffle=False))
Om de geschatte waarden af โโte drukken, kunt u deze code gebruiken:
predictions = list(p["predictions"] for p in itertools.islice(y, 6)) print("Predictions: {}".format(str(predictions)))
uitgang
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)]
Het model voorspelt de volgende waarden:
| Huis | Voorspelling |
| 1 | 32.29 |
| 2 | 18.96 |
| 3 | 27.27 |
| 4 | 29.29 |
| 5 | 16.43 |
| 6 | 21.46 |
Houd er rekening mee dat we de werkelijke waarde van deze zes huizen niet kennen. In de deep learning-tutorial ga je proberen het lineaire model te verslaan.
NumPy-oplossing
In dit gedeelte wordt uitgelegd hoe je het model traint met behulp van een NumPy-estimator om de data te voeden. De methode is hetzelfde, alleen gebruik je nu de numpy_input_fn-estimator.
Lees dezelfde drie CSV-bestanden, maar behoud alleen de onbewerkte NumPy-arrays met .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
Stap 1) Importeer de gegevens
Allereerst moet je de kenmerkvariabelen onderscheiden van de labels. Dit moet je doen voor zowel de trainingsdata als de evaluatiedata. Het is sneller om een โโfunctie te definiรซren om de data te splitsen.
def prepare_data(df): X_train = df[:, :-3] y_train = df[:,-3] return X_train, y_train
Je kunt de functie gebruiken om het label te scheiden van de kenmerken van de trainings- en evaluatiegegevenssets.
X_train, y_train = prepare_data(training_set_n) X_test, y_test = prepare_data(test_set_n)
Je moet de laatste kolom van de voorspellingsdataset uitsluiten, omdat deze alleen NaN-waarden bevat.
x_predict = prediction_set_n[:, :-2]
Controleer de vorm van de array. Let op: het label mag geen tweede dimensie hebben, dus (400,).
print(X_train.shape, y_train.shape, x_predict.shape)
uitgang
(400, 9) (400,) (6, 9)
Je kunt de featurekolommen als volgt samenstellen:
feature_columns = [ tf.feature_column.numeric_column('x', shape=X_train.shape[1:])]
De schatter wordt op dezelfde manier gedefinieerd als voorheen: u specificeert de featurekolommen en waar de grafiek moet worden opgeslagen.
estimator = tf.estimator.LinearRegressor(
feature_columns=feature_columns,
model_dir="train1")
uitgang
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}
Je kunt de NumPy-estimator gebruiken om de data aan het model te voeden en vervolgens het model te trainen. Merk op dat we de functie `input_fn` vooraf definiรซren om de leesbaarheid te verbeteren.
# 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)
uitgang
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>
Je herhaalt dezelfde stap met een andere invoerfunctie om je model te evalueren.
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)
uitgang
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}
Tot slot kun je de voorspelling berekenen. Deze zou vergelijkbaar moeten zijn met het resultaat van Pandas.
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)))
uitgang
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-oplossing
Het laatste gedeelte is gewijd aan een puur TensorFlow oplossing. Deze methode is iets ingewikkelder dan de andere twee.
Houd er rekening mee dat als u een Jupyter notitieboekjeJe moet de computer opnieuw opstarten en de kernel wissen om deze sessie te kunnen uitvoeren.
TensorFlow heeft een uitstekende tool ontwikkeld om gegevens aan de pipeline door te geven. In dit gedeelte ga je zelf de functie `input_fn` bouwen.
Stap 1) Definieer het pad en het formaat van de gegevens
Allereerst declareer je twee variabelen met het pad naar de CSV-bestanden. Let op: je hebt twee bestanden, รฉรฉn voor de trainingsset en รฉรฉn voor de testset.
import tensorflow as tf
df_train = "E:/boston_train.csv"
df_eval = "E:/boston_test.csv"
Vervolgens moet je de kolommen uit het CSV-bestand definiรซren die je wilt gebruiken. We gebruiken ze allemaal. Daarna moet je het gegevenstype van elke variabele opgeven.
Float-variabelen worden gedefinieerd door [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]]
Stap 2) Definieer de input_fn-functie
De functie kan worden opgedeeld in drie delen:
- Importeer de gegevens
- Maak de iterator
- Consumeer de gegevens
Hieronder staat de volledige code om de functie te definiรซren. De code wordt later toegelicht.
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
Importeer de gegevens
Voor een CSV-bestand leest de datasetmethode รฉรฉn regel per keer. Om de dataset te bouwen, moet je het object gebruiken. TextLineDataset. Je dataset heeft een koptekst, dus je moet `skip(1)` gebruiken om de eerste regel over te slaan. Op dit punt lees je alleen de data en sluit je de koptekst uit in de pipeline. Om het model te voeden, moet je de kenmerken scheiden van de labels. De methode die gebruikt wordt om transformaties op de data toe te passen is `map`.
Deze methode roept een functie aan die u zelf maakt om aan te geven hoe de gegevens moeten worden getransformeerd. Kort gezegd moet u de gegevens doorgeven aan de functie. TextLineEen datasetobject, zonder de header, en een transformatie toepassen die door een functie wordt aangegeven.
Code uitleg
- tf.data.TextLineDataset(data_file): deze regel leest het CSV-bestand.
- .skip(1): slaat de header over
- .map(parse_csv)): parseert de records naar tensors.
Je moet een functie definiรซren om het kaartobject te instrueren. Je kunt deze functie `parse_csv` noemen.
Deze functie parseert het CSV-bestand met de methode tf.decode_csv en declareert de kenmerken en het label. De kenmerken kunnen worden gedeclareerd als een dictionary of een tuple. We gebruiken de dictionary-methode omdat die handiger is.
Code uitleg
- tf.decode_csv(value, record_defaults= RECORDS_ALL): de methode decode_csv gebruikt de uitvoer van de TextLineDataset om het CSV-bestand te lezen. `record_defaults` geeft TensorFlow instructies over de kolomtypen. In TensorFlow 2.x bevindt dit symbool zich in `tf.io.decode_csv`.
- dict(zip(COLUMNS, columns)): vult het woordenboek met alle kolommen extracted tijdens deze gegevensverwerking
- features.pop('medv'): sluit de doelvariabele uit van de featurevariabelen en creรซert een labelvariabele.
De dataset heeft meer elementen nodig om de tensors iteratief te voeden. Je moet de `repeat`-methode toevoegen om ervoor te zorgen dat de dataset het model oneindig kan blijven voeden. Als je deze methode niet toevoegt, zal het model slechts รฉรฉn keer itereren en vervolgens een foutmelding geven omdat er geen gegevens meer aan de pipeline worden toegevoerd.
Daarna kun je de batchgrootte regelen met de batchmethode. Hiermee geef je aan hoeveel data je per iteratie aan de pipeline wilt doorgeven. Als je een grote batchgrootte instelt, zal het model traag zijn.
Stap 3) Maak de iterator
Nu bent u klaar voor de tweede stap: maak een iterator om de elementen in de dataset terug te geven.
De eenvoudigste manier om een โโoperator te maken is met de methode make_one_shot_iterator.
Daarna kunt u de functies en labels maken vanuit de iterator.
Stap 4) Consumeer de gegevens
Je kunt controleren wat er gebeurt met de functie input_fn. Je moet de functie in een sessie aanroepen om de gegevens te kunnen verwerken. Probeer het met een batchgrootte van 1.
Merk op dat de kenmerken in een woordenboek worden afgedrukt en het label als een array.
Het zal de eerste regel van het CSV-bestand weergeven. Je kunt proberen deze code meerdere keren uit te voeren met verschillende batchgroottes.
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)
uitgang
({'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))
Stap 5) Definieer de functiekolom
U dient de numerieke kolommen als volgt te definiรซren:
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')
Houd er rekening mee dat u alle variabelen in een bucket moet combineren.
base_columns = [X1, X2, X3,X4, X5, X6,X7, X8, X9]
Stap 6) Bouw het model
U kunt het model trainen met de schatter LinearRegressor.
model = tf.estimator.LinearRegressor(feature_columns=base_columns, model_dir='train3')
uitgang
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}
Je moet een gebruiken lambda-functie Hiermee kun je de argumenten voor de functie input_fn schrijven. Als je geen lambda-functie gebruikt, kun je het model niet trainen.
# Train the estimator model.train(steps =1000, input_fn= lambda : input_fn(df_train,batch_size=128, num_epoch = None))
uitgang
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>
Met de onderstaande code kunt u de pasvorm van uw model op de testset beoordelen:
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]))
uitgang
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
De laatste stap is het voorspellen van de doelwaarde op basis van de waarden in de featurematrix. Je kunt een dictionary schrijven met de waarden die je wilt voorspellen. Je model heeft negen features, dus je moet voor elke feature een waarde opgeven. Het model zal vervolgens voor elk van deze features een voorspelling doen.
In de onderstaande code schrijf je de waarden van elk kenmerk dat in het CSV-bestand df_predict staat.
Je moet een nieuwe input_fn-functie schrijven omdat er geen labels in de dataset aanwezig zijn. Je kunt hiervoor de from_tensors API van het Dataset-object gebruiken.
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)
Tot slot print je de voorspellingen.
for pred in enumerate(pred_results): print(pred)
uitgang
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)})
Alle drie de pipelines leveren dezelfde zes voorspellingen op, wat bevestigt dat de keuze tussen Pandas, NumPy en een native TensorFlow-dataset een kwestie van gemak is, en niet van nauwkeurigheid.





