Regressione lineare TensorFlow con termine di sfaccettatura e interazione

In questo tutorial imparerai come controllare i dati e prepararli per creare una semplice attività di regressione lineare.

Questo tutorial è diviso in due parti:

  • Cerca l'interazione
  • Prova il modello

Nel tutorial precedente, hai utilizzato il set di dati di Boston per stimare il prezzo medio di una casa. Il set di dati di Boston ha dimensioni ridotte, con solo 506 osservazioni. Questo set di dati è considerato un punto di riferimento per provare nuovi algoritmi di regressione lineare.

Il dataset è composto da:

Variabile Descrizione
zn La percentuale di terreno residenziale suddiviso in zone per lotti superiori a 25,000 piedi quadrati.
Indus La proporzione di acri commerciali non al dettaglio per città.
nox concentrazione di ossidi nitrici
rm numero medio di stanze per abitazione
la percentuale di unità abitative costruite prima del 1940
DIS distanze ponderate da cinque centri per l'impiego di Boston
imposta aliquota dell'imposta sulla proprietà a valore intero per dollari 10,000
ptratio il rapporto alunni-insegnanti per città
medv Il valore medio delle case occupate dai proprietari in migliaia di dollari
criminale tasso di criminalità pro capite per città
Chas Variabile fittizia Charles River (1 se delimita il fiume; 0 altrimenti)
B la percentuale di neri nella città

In questo tutorial stimeremo il prezzo mediano utilizzando un regressore lineare, ma l'attenzione si concentrerà su un particolare processo di machine learning: “preparazione dei dati”.

Un modello generalizza il modello nei dati. Per catturare un modello del genere, devi prima trovarlo. Una buona pratica è eseguire un'analisi dei dati prima di eseguire qualsiasi algoritmo di machine learning.

Scegliere le caratteristiche giuste fa la differenza nel successo del tuo modello. Immagina di provare a stimare il salario di un popolo, se non includi il genere come covariata, ti ritroverai con una stima inadeguata.

Un altro modo per migliorare il modello è osservare la correlazione tra la variabile indipendente. Tornando all’esempio, si può pensare all’istruzione come un ottimo candidato per prevedere il salario ma anche l’occupazione. È giusto dire che l'occupazione dipende dal livello di istruzione, vale a dire che l'istruzione superiore spesso porta a un'occupazione migliore. Se generalizziamo questa idea, possiamo dire che la correlazione tra la variabile dipendente e una variabile esplicativa può essere amplificata da un'altra variabile esplicativa.

Per catturare l’effetto limitato dell’istruzione sull’occupazione, possiamo usare un termine di interazione.

Termine di interazione

Se osserviamo l’equazione salariale, diventa:

Termine di interazione

If Termine di interazione è positivo, allora implica che un ulteriore livello di istruzione produce un aumento maggiore del valore mediano di una casa per un alto livello di occupazione. In altre parole, esiste un effetto di interazione tra istruzione e occupazione.

In questo tutorial cercheremo di vedere quali variabili possono essere un buon candidato per i termini di interazione. Verificheremo se l’aggiunta di questo tipo di informazioni porta a una migliore previsione dei prezzi.

Statistiche riassuntive

Ci sono alcuni passaggi che puoi seguire prima di procedere con il modello. Come accennato in precedenza, il modello è una generalizzazione dei dati. La pratica migliore è comprendere i dati e fare una previsione. Se non conosci i tuoi dati, hai poche possibilità di migliorare il tuo modello.

Come primo passaggio, caricare i dati come dataframe panda e creare un set di addestramento e un set di test.

Suggerimenti: per questo tutorial è necessario che siano installati matplotlit e seaborn Python. Puoi installare Python pacchetto al volo con Jupyter. È Non dovrebbe fare questo

!conda install -- yes matplotlib

ma

import sys
!{sys.executable} -m pip install matplotlib # Already installed
!{sys.executable} -m pip install seaborn 

Tieni presente che questo passaggio non è necessario se hai installato matplotlib e seaborn.

Matplotlib è la libreria in cui creare un grafico Python. Seaborn è una libreria di visualizzazione statistica costruita su matplotlib. Fornisce trame attraenti e belle.

Il codice seguente importa le librerie necessarie.

import pandas as pd
from sklearn import datasets
import tensorflow as tf
from sklearn.datasets import load_boston
import numpy as np

La libreria sklearn include il set di dati di Boston. Puoi chiamare la sua API per importare i dati.

boston = load_boston()
df = pd.DataFrame(boston.data)

Il nome della funzionalità è memorizzato nell'oggetto feature_names in un array.

boston.feature_names

Uscita

array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')

Puoi rinominare le colonne.

df.columns = boston.feature_names
df['PRICE'] = boston.target
df.head(2)

Regressione lineare con termine di sfaccettatura e interazione

Converti la variabile CHAS come variabile stringa e etichettala con sì se CHAS = 1 e no se 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

Con i panda, è semplice dividere il set di dati. Dividi in modo casuale il set di dati con l'80% di set di addestramento e il 20% di set di test. Pandas hanno una funzione di costo incorporata per dividere un campione di frame di dati.

Il primo parametro frac è un valore compreso tra 0 e 1. Lo imposti su 0.8 per selezionare casualmente l'80% del frame di dati.

Random_state consente di restituire lo stesso dataframe per tutti.

### Create train/test set
df_train=df.sample(frac=0.8,random_state=200)
df_test=df.drop(df_train.index)

È possibile ottenere la forma dei dati. Dovrebbe essere:

  • Trenino elettrico: 506*0.8 = 405
  • Set di prova: 506*0.2 = 101
print(df_train.shape, df_test.shape)

Uscita

(405, 14) (101, 14)
df_test.head(5)

Uscita

CRIM ZN INDOS CHAS NOX RM ETÀ DIS RAD TAX PTRAZIONE B LSTAT PREZZO
0 0.00632 18.0 2.31 no 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 no 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 no 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 no 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 no 0.524 6.172 96.1 5.9505 5.0 311.0 15.2 396.90 19.15 27.1

I dati sono disordinati; è spesso sbilanciato e cosparso di valori anomali che ostacolano l'analisi e la formazione sull'apprendimento automatico.

Il primo passo per ripulire il set di dati è capire dove è necessario pulirlo. Ripulire un set di dati può essere complicato, soprattutto in qualsiasi modo generalizzabile

Il team di ricerca di Google ha sviluppato uno strumento per questo lavoro chiamato sfaccettature che aiutano a visualizzare i dati e a suddividerli in tutti i modi. Questo è un buon punto di partenza per comprendere come è strutturato il set di dati.

Le sfaccettature ti consentono di scoprire dove i dati non appaiono esattamente nel modo in cui pensi.

Ad eccezione della loro app Web, Google semplifica l'incorporamento del toolkit in un file Jupyter taccuino.

Ci sono due parti in Facets:

  • Panoramica delle sfaccettature
  • Approfondimento sulle sfaccettature

Panoramica delle sfaccettature

Facets Overview fornisce una panoramica del set di dati. Facets Overview divide le colonne dei dati in righe di informazioni salienti che mostrano

  1. la percentuale di osservazione mancante
  2. valori minimo e massimo
  3. statistiche come media, mediana e deviazione standard.
  4. Aggiunge inoltre una colonna che mostra la percentuale di valori che sono zero, il che è utile quando la maggior parte dei valori sono zero.
  5. È possibile vedere queste distribuzioni sul set di dati di test e sul set di training per ogni feature. Ciò significa che puoi ricontrollare che il test abbia una distribuzione simile ai dati di training.

Questo è almeno il minimo da fare prima di qualsiasi attività di machine learning. Con questo strumento non si perde questo passaggio fondamentale e si evidenziano alcune anomalie.

Approfondimento sulle sfaccettature

Facets Deep Dive è uno strumento fantastico. Consente di avere un po' di chiarezza sul tuo dataset e di ingrandire fino in fondo per vedere un singolo pezzo di dati. Ciò significa che puoi sfaccettare i dati per riga e colonna in tutte le feature del dataset.

Utilizzeremo questi due strumenti con il set di dati di Boston.

Note:: non è possibile utilizzare Panoramica sfaccettature e Approfondimento sfaccettature contemporaneamente. È necessario prima pulire il notebook per cambiare lo strumento.

Installa sfaccettatura

È possibile utilizzare l'app Web Facet per la maggior parte dell'analisi. In questo tutorial vedrai come usarlo all'interno di a Jupyter Taccuino.

Prima di tutto, devi installare nbextensions. Si fa con questo codice. Copia e incolla il seguente codice nel terminale della tua macchina.

pip install jupyter_contrib_nbextensions

Subito dopo, devi clonare i repository sul tuo computer. Hai due scelte:

Opzione 1) Copia e incolla questo codice nel terminale (Consigliata)

Se non hai Git installato sul tuo computer, vai a questo URL https://git-scm.com/download/win e seguire le istruzioni. Una volta terminato, puoi utilizzare il comando git nel terminale per l'utente Mac o il prompt di Anaconda Windows Utente

git clone https://github.com/PAIR-code/facets

Opzione 2) Vai su https://github.com/PAIR-code/facets e scaricare i repository.

Installa sfaccettatura

Se scegli la prima opzione, il file finirà nel file di download. Puoi lasciare scaricare il file o trascinarlo su un altro percorso.

Puoi verificare dove sono archiviati i Facet con questa riga di comando:

echo `pwd`/`ls facets`

Ora che hai individuato Facets, devi installarlo Jupyter Taccuino. È necessario impostare la directory di lavoro sul percorso in cui si trovano i facet.

La directory di lavoro attuale e la posizione del file zip di Facets dovrebbero essere le stesse.

Installa sfaccettatura

È necessario indirizzare la directory di lavoro su Facet:

cd facets

Per installare Facets in Jupyter, hai due opzioni. Se hai installato Jupyter con Conda per tutti gli utenti, copia questo codice:

puoi usare jupyter nbextension install facets-dist/

jupyter nbextension install facets-dist/

Altrimenti usa:

jupyter nbextension install facets-dist/ --user

Va bene, è tutto a posto. Apriamo Panoramica delle faccette.

Panoramica

Panoramica utilizza a Python script per calcolare le statistiche. Devi importare lo script denominato generic_feature_statistics_generator in Jupyter. Non preoccuparti; lo script si trova nei file delle sfaccettature.

È necessario individuare il suo percorso. È facile da fare. Apri facets, apri il file facets_overview e poi python. Copia il percorso

Panoramica sfaccettatura

Dopodiché, torna a Jupytere scrivi il seguente codice. Cambia il percorso '/Users/Thomas/facets/facets_overview/python' nel tuo percorso.

# Add the facets overview python code to the python path# Add t 
import sys
sys.path.append('/Users/Thomas/facets/facets_overview/python')

Puoi importare lo script con il codice seguente.

from generic_feature_statistics_generator import 
GenericFeatureStatisticsGenerator

In Windows, lo stesso codice diventa

import sys
sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python")

from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator

Per calcolare le statistiche delle funzionalità, è necessario utilizzare la funzione GenericFeatureStatisticsGenerator() e utilizzi l'oggetto ProtoFromDataFrames. Puoi passare il frame di dati in un dizionario. Se ad esempio vogliamo creare una statistica riepilogativa per il convoglio, possiamo memorizzare le informazioni in un dizionario e utilizzarle nell'oggetto "ProtoFromDataFrames"

  • 'name': 'train', 'table': df_train

Nome è il nome della tabella visualizzata e si utilizza il nome della tabella di cui si desidera calcolare il riepilogo. Nel tuo esempio, la tabella contenente i dati è 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")

Infine, basta copiare e incollare il codice qui sotto. Il codice proviene direttamente da GitHub. Dovresti essere in grado di vedere questo:

Panoramica sfaccettatura

# Display the facets overview visualization for this data# Displ 
from IPython.core.display import display, HTML

HTML_TEMPLATE = """<link rel="import" href="/it/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))

Grafico

Dopo aver controllato i dati e la loro distribuzione, puoi tracciare una matrice di correlazione. La matrice di correlazione calcola il coefficiente di Pearson. Questo coefficiente è compreso tra -1 e 1, con un valore positivo indica una correlazione positiva e un valore negativo una correlazione negativa.

Sei interessato a vedere quali variabili possono essere un buon candidato per i termini di interazione.

## 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})

Uscita

<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518>

png

Grafico sfaccettato

Dalla matrice puoi vedere:

  • LSTAT
  • RM

Sono fortemente correlati al PREZZO. Un’altra caratteristica interessante è la forte correlazione positiva tra NOX e INDUS, il che significa che queste due variabili si muovono nella stessa direzione. Inoltre ci sono anche delle correlazioni con il PREZZO. DIS è anche altamente correlato con IND e NOX.

Hai qualche primo indizio che IND e NOX possono essere buoni candidati per il termine di intercetta e anche DIS potrebbe essere interessante su cui concentrarsi.

Puoi andare un po' più in profondità tracciando una griglia di coppia. Illustrerà più in dettaglio la mappa di correlazione tracciata in precedenza.

La griglia delle coppie da noi è composta come segue:

  • Parte superiore: grafico a dispersione con linea montata
  • Diagonale: grafico della densità del kernel
  • Parte inferiore: grafico multivariato della densità del kernel

Scegli il focus su quattro variabili indipendenti. La scelta corrisponde alle variabili con forte correlazione con il PREZZO

  • INDOS
  • NOX
  • RM
  • LSTAT

inoltre, il PREZZO.

Note: che l'errore standard viene aggiunto per impostazione predefinita al grafico a dispersione.

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)

Uscita

Grafico sfaccettato

Cominciamo dalla parte superiore:

  • Il prezzo è correlato negativamente con INDUS, NOX e LSTAT; correlato positivamente con RM.
  • C'è una leggera non linearità con LSTAT e PRICE
  • C'è come una linea retta quando il prezzo è uguale a 50. Dalla descrizione del dataset, PRICE è stato troncato al valore di 50

Diagonale

  • Il NOX sembra avere due cluster, uno intorno a 0.5 e uno intorno a 0.85.

Per verificarlo meglio, puoi guardare la parte inferiore. La densità multivariata del kernel è interessante in un certo senso colora dove si trova la maggior parte dei punti. La differenza con il grafico a dispersione traccia una densità di probabilità, anche se non esiste alcun punto nel set di dati per una determinata coordinata. Quando il colore è più forte, indica un'alta concentrazione di punti intorno a quest'area.

Se controlli la densità multivariata per INDUS e NOX, puoi vedere la correlazione positiva e i due cluster. Quando la quota del settore è superiore a 18, la concentrazione di ossidi di azoto è superiore a 0.6.

Puoi pensare di aggiungere un'interazione tra INDUS e NOX nella relazione lineare.

Infine, puoi usare il secondo strumento creato da Google, Facets Deep Dive. L'interfaccia è divisa in quattro sezioni principali. L'area centrale al centro è una visualizzazione zoomabile dei dati. Nella parte superiore del pannello, c'è il menu a discesa in cui puoi modificare la disposizione dei dati per controllare la sfaccettatura, il posizionamento e il colore. Sulla destra, c'è una vista dettagliata di una riga specifica di dati. Ciò significa che puoi cliccare su qualsiasi punto di dati nella visualizzazione centrale per vedere i dettagli su quel particolare punto dati.

Durante la fase di visualizzazione dei dati, sei interessato a cercare la correlazione a coppie tra la variabile indipendente sul prezzo della casa. Tuttavia, coinvolge almeno tre variabili e i grafici 3D sono complicati da usare.

Un modo per affrontare questo problema è creare una variabile categoriale. Cioè, possiamo creare una trama 2D colorando il punto. È possibile dividere la variabile PREZZO in quattro categorie, ciascuna delle quali è un quartile (ad esempio, 0.25, 0.5, 0.75). Chiami questa nuova variabile 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")

Grafico sfaccettato

Approfondimento sulle sfaccettature

Per aprire Deep Dive è necessario trasformare i dati in un formato json. I panda come oggetto per questo. Puoi utilizzare to_json dopo il set di dati Pandas.

La prima riga di codice gestisce la dimensione del set di dati.

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')

Il codice seguente proviene da Google GitHub. Dopo aver eseguito il codice, dovresti essere in grado di vedere questo:

Approfondimento sulle sfaccettature

# Display thde Dive visualization for this data
from IPython.core.display import display, HTML

# Create Facets template  
HTML_TEMPLATE = """<link rel="import" href="/it/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))

Ti interessa vedere se esiste una connessione tra il tasso di settore, la concentrazione di ossidi, la distanza dal centro per l'impiego e il prezzo della casa.

Per questo, per prima cosa dividi i dati per fascia di settore e colore con il quartile del prezzo:

  • Seleziona la sfaccettatura X e scegli INDUS.
  • Seleziona Visualizza e scegli DIS. Colorerà i punti con il quartile del prezzo della casa

qui i colori più scuri indicano che la distanza dal primo centro per l'impiego è lontana.

Finora, mostra ancora una volta ciò che sai, tasso di settore più basso, prezzo più alto. Ora potete vedere la ripartizione per INDUX e per NOX.

  • Seleziona la sfaccettatura Y e scegli NOX.

Ora puoi vedere che la casa lontana dal primo centro di lavoro ha la quota di settore più bassa e quindi la concentrazione di ossido più bassa. Se scegli di visualizzare il tipo con Q_PRICE e ingrandisci l'angolo in basso a sinistra, puoi vedere di che tipo di prezzo si tratta.

Hai un altro indizio che l’interazione tra IND, NOX e DIS può essere un buon candidato per migliorare il modello.

TensorFlow

In questa sezione stimerai il classificatore lineare con l'API degli stimatori TensorFlow. Procederai come segue:

  • Prepara i dati
  • Stimare un modello di riferimento: nessuna interazione
  • Stimare un modello con interazione

Ricorda, l'obiettivo dell'apprendimento automatico è ridurre al minimo l'errore. In questo caso vincerà il modello con l’errore quadratico medio più basso. Lo stimatore TensorFlow calcola automaticamente questa metrica.

Dati di preparazione

Nella maggior parte dei casi, è necessario trasformare i dati. Ecco perché la panoramica delle sfaccettature è affascinante. Dalla statistica riassuntiva, hai visto che ci sono valori anomali. Questi valori influenzano le stime perché non assomigliano alla popolazione che stai analizzando. I valori anomali di solito influenzano i risultati. Ad esempio, un valore anomalo positivo tende a sovrastimare il coefficiente.

Una buona soluzione per affrontare questo problema è standardizzare la variabile. La standardizzazione significa una deviazione standard pari a uno e una media pari a zero. Il processo di standardizzazione prevede due fasi. Innanzitutto sottrae il valore medio della variabile. In secondo luogo, divide per la deviazione standard in modo che la distribuzione abbia una deviazione standard unitaria.

La libreria sklearn è utile per standardizzare le variabili. A questo scopo è possibile utilizzare la preelaborazione del modulo con la scala dell'oggetto.

È possibile utilizzare la funzione seguente per ridimensionare un set di dati. Tieni presente che non ridimensioni la colonna dell'etichetta e le variabili categoriali.

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

È possibile utilizzare la funzione per costruire il set di treno/test in scala.

df_train_scale = standardize_data(df_train)
df_test_scale = standardize_data(df_test)

Regressione di base: benchmark

Prima di tutto, alleni e testi un modello senza interazione. Lo scopo è vedere la metrica delle prestazioni del modello.

Il modo per addestrare il modello è esattamente come nel tutorial API di alto livello. Utilizzerai lo stimatore TensorFlow LinearRegressor.

Come promemoria, devi scegliere:

  • le caratteristiche da inserire nel modello
  • trasformare le caratteristiche
  • costruire il regressore lineare
  • costruire la funzione input_fn
  • addestrare il modello
  • testare il modello

Utilizzi tutte le variabili nel set di dati per addestrare il modello. In totale, ci sono variabili continue di livello e una variabile categoriale

## 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']

Converti le funzionalità in una colonna numerica o in una colonna categoriale

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'])]

Crei il modello con linearRegressor. Memorizzi il modello nella cartella train_Boston

model = tf.estimator.LinearRegressor(    
	model_dir="train_Boston",     
    feature_columns=categorical_features + continuous_features)

Uscita

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}

Ogni colonna nei dati del treno o del test viene convertita in un tensore con la funzione 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)

Stimi il modello sui dati del treno.

model.train(input_fn=get_input_fn(df_train_scale, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Uscita

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>

Infine, si stimano le prestazioni del modello sul test set

model.evaluate(input_fn=get_input_fn(df_test_scale, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Uscita

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}

La perdita del modello è 1650. Questa è la metrica da battere nella sezione successiva

Migliorare il modello: termine di interazione

Durante la prima parte del tutorial, hai notato un'interessante relazione tra le variabili. Le diverse tecniche di visualizzazione hanno rivelato che INDUS e NOS sono collegati tra loro e amplificano l'effetto sul prezzo. Non solo l'interazione tra INDUS e NOS influisce sul prezzo, ma anche questo effetto è più forte quando interagisce con DIS.

È tempo di generalizzare questa idea e vedere se è possibile migliorare il modello previsto dal modello.

È necessario aggiungere due nuove colonne a ciascun set di dati: train + test. Per questo, crei una funzione per calcolare il termine di interazione e un'altra per calcolare il termine di tripla interazione. Ogni funzione produce una singola colonna. Dopo aver creato le nuove variabili, è possibile concatenarle al set di dati di training e al set di dati di test.

Prima di tutto è necessario creare una nuova variabile per l’interazione tra INDUS e NOX.

La funzione seguente restituisce due dataframe, train e test, con l'interazione tra var_1 e var_2, nel tuo caso INDUS e 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

Memorizzi le due nuove colonne

interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS')
interation_ind_ns_train.shape
(325,)

In secondo luogo, crei una seconda funzione per calcolare il termine della tripla interazione.

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')

Ora che hai tutte le colonne necessarie, puoi aggiungerle al training e al test del set di dati. Dai un nome a questi due nuovi dataframe:

  • df_train_new
  • df_test_nuovo
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)

Uscita

Migliorare il termine di interazione del modello

Questo è tutto; puoi stimare il nuovo modello con i termini di interazione e vedere come è la metrica delle prestazioni.

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)

Uscita

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}

CODICE

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)

Uscita

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)

Uscita

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}

La nuova perdita è 1515. Semplicemente aggiungendo due nuove variabili, sei riuscito a diminuire la perdita. Significa che puoi fare una previsione migliore rispetto al modello di riferimento.