Classificazione binaria TensorFlow: esempio di classificatore lineare
I due piรน comuni apprendimento supervisionato i compiti sono la regressione lineare e il classificatore lineare. La regressione lineare prevede un valore mentre il classificatore lineare prevede una classe. Questo tutorial รจ incentrato sui classificatori lineari.
Cos'รจ il classificatore lineare?
A Classificatore lineare in Machine Learning รจ un metodo per trovare la classe di un oggetto in base alle sue caratteristiche per la classificazione statistica. Prende decisioni di classificazione in base al valore di una combinazione lineare di caratteristiche di un oggetto. Il classificatore lineare viene utilizzato in problemi pratici come la classificazione dei documenti e problemi con molte variabili.
I problemi di classificazione rappresentano circa lโ80% delle attivitร di machine learning. La classificazione mira a prevedere la probabilitร di ciascuna classe dato un insieme di input. L'etichetta (cioรจ la variabile dipendente) รจ un valore discreto, chiamato classe.
- Se l'etichetta ha solo due classi, l'algoritmo di apprendimento รจ un classificatore binario.
- Il classificatore multiclasse affronta le etichette con piรน di due classi.
Ad esempio, un tipico problema di classificazione binaria consiste nel prevedere la probabilitร che un cliente effettui un secondo acquisto. Prevedere il tipo di animale visualizzato su un'immagine รจ un problema di classificazione multiclasse poichรฉ esistono piรน di due varietร di animali.
La parte teorica di questo tutorial si concentra principalmente sulla classe binaria. Imparerai di piรน sulla funzione di output multiclasse in un tutorial futuro.
Come funziona il classificatore binario?
Nel tutorial precedente hai imparato che una funzione รจ composta da due tipi di variabili, una variabile dipendente e un insieme di caratteristiche (variabili indipendenti). Nella regressione lineare, una variabile dipendente รจ un numero reale senza intervallo. L'obiettivo primario รจ prevederne il valore minimizzando l'errore quadratico medio.
Per TensorFlow Binary Classifier, l'etichetta puรฒ avere due possibili valori interi. Nella maggior parte dei casi รจ [0,1] o [1,2]. Ad esempio, lโobiettivo รจ prevedere se un cliente acquisterร o meno un prodotto. L'etichetta รจ definita come segue:
- Y = 1 (il cliente ha acquistato il prodotto)
- Y = 0 (il cliente non acquista il prodotto)
Il modello utilizza le caratteristiche X per classificare ciascun cliente nella classe piรน probabile di appartenenza, ovvero potenziale acquirente o meno.
Si calcola la probabilitร di successo regressione logistica. L'algoritmo calcolerร una probabilitร basata sulla caratteristica X e prevederร un successo quando questa probabilitร sarร superiore al 50%. Piรน formalmente, la probabilitร viene calcolata come mostrato nell'esempio di classificazione binaria TensorFlow riportato di seguito:
dove 0 รจ l'insieme dei pesi, delle caratteristiche eb il bias.
La funzione puรฒ essere scomposta in due parti:
- Il modello lineare
- La funzione logistica
Modello lineare
Conosci giร il modo in cui vengono calcolati i pesi. I pesi vengono calcolati utilizzando un prodotto scalare: Y รจ una funzione lineare di tutte le caratteristiche xi. Se il modello non ha caratteristiche, la previsione รจ uguale al bias, b.
I pesi indicano la direzione della correlazione tra le caratteristiche xi e l'etichetta y. Una correlazione positiva aumenta la probabilitร della classe positiva mentre una correlazione negativa porta la probabilitร piรน vicino a 0 (cioรจ classe negativa).
Il modello lineare restituisce solo un numero reale, che non รจ coerente con la misura di probabilitร dell'intervallo [0,1]. La funzione logistica รจ necessaria per convertire l'output del modello lineare in una probabilitร ,
Funzione logistica
La funzione logistica, o funzione sigmoide, ha una forma a S e l'output di questa funzione รจ sempre compreso tra 0 e 1.

ร facile sostituire l'output della regressione lineare nella funzione sigmoidea. Il risultato รจ un nuovo numero con una probabilitร compresa tra 0 e 1.
Il classificatore puรฒ trasformare la probabilitร in una classe
- I valori compresi tra 0 e 0.49 diventano classe 0
- I valori compresi tra 0.5 e 1 diventano classe 1
Come misurare le prestazioni del classificatore lineare?
Precisione
Le prestazioni complessive di un classificatore vengono misurate con la metrica dell'accuratezza. L'accuratezza raccoglie tutti i valori corretti divisi per il numero totale di osservazioni. Ad esempio, un valore di precisione dell'80% significa che il modello รจ corretto nell'80% dei casi.

Si puรฒ notare una lacuna con questa metrica, specialmente per la classe di squilibrio. Un set di dati di squilibrio si verifica quando il numero di osservazioni per gruppo non รจ uguale. Diciamo; provi a classificare un evento raro con una funzione logistica. Immagina che il classificatore provi a stimare la morte di un paziente a seguito di una malattia. Nei dati, il 5 percento dei pazienti muore. Puoi addestrare un classificatore a prevedere il numero di decessi e usare la metrica di accuratezza per valutare le prestazioni. Se il classificatore prevede 0 decessi per l'intero set di dati, sarร corretto nel 95 percento dei casi.
Matrice di confusione
Un modo migliore per valutare le prestazioni di un classificatore รจ guardare la matrice di confusione.

Migliori matrice di confusione visualizza l'accuratezza di un classificatore confrontando le classi effettive e previste come mostrato nell'esempio di classificatore lineare sopra. La matrice di confusione binaria รจ composta da quadrati:
- TP: Vero positivo: valori previsti correttamente previsti come positivi effettivi
- FP: I valori previsti prevedevano erroneamente un positivo effettivo. cioรจ, valori negativi previsti come positivi
- FN: Falso negativo: valori positivi previsti come negativi
- TN: vero negativo: valori previsti correttamente previsti come negativi effettivi
Dalla matrice di confusione รจ facile confrontare la classe effettiva e la classe prevista.
Precisione e sensibilitร
La matrice di confusione fornisce una buona visione del vero positivo e del falso positivo. In alcuni casi, รจ preferibile avere una metrica piรน concisa.
Precisione
La metrica di precisione mostra l'accuratezza della classe positiva. Misura la probabilitร che la previsione della classe positiva sia corretta.
Il punteggio massimo รจ 1 quando il classificatore classifica perfettamente tutti i valori positivi. La precisione da sola non รจ molto utile perchรฉ ignora la classe negativa. La metrica รจ solitamente abbinata alla metrica di richiamo. Il richiamo รจ anche chiamato sensibilitร o tasso di vero positivo.
Sensibilitร
La sensibilitร calcola il rapporto delle classi positive rilevate correttamente. Questa metrica indica quanto รจ buono il modello nel riconoscere una classe positiva.
Classificatore lineare con TensorFlow
Per questo tutorial utilizzeremo il set di dati del censimento. Lo scopo รจ utilizzare le variabili nel set di dati del censimento per prevedere il livello di reddito. Si noti che il reddito รจ una variabile binaria
- con valore 1 se reddito > 50k
- 0 se reddito < 50k.
Questa variabile รจ la tua etichetta
Questo set di dati include otto variabili categoriali:
- sul posto di lavoro
- continua
- coniugale
- occupazione
- rapporto
- gara
- sesso
- Paese d'origine
inoltre, sei variabili continue:
- fnlwgt
- numero_istruzione
- plusvalenza
- perdita_capitale
- ore_settimana
Attraverso questo esempio di classificazione TensorFlow, capirai come addestrare i classificatori TensorFlow lineari con lo stimatore TensorFlow e come migliorare la metrica di precisione.
Procederemo come segue:
- Passaggio 1) Importa i dati
- Passaggio 2) Conversione dei dati
- Passaggio 3) Addestrare il classificatore
- Passaggio 4) Migliorare il modello
- Passaggio 5) Iperparametro: Lazo e Ridge
Passaggio 1) Importa i dati
Per prima cosa importi le librerie utilizzate durante il tutorial.
import tensorflow as tf import pandas as pd
Successivamente, importi i dati dall'archivio di UCI e definisci i nomi delle colonne. Utilizzerai COLUMNS per nominare le colonne in un data frame pandas.
Tieni presente che addestrerai il classificatore utilizzando un dataframe Pandas.
## Define path data
COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital',
'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
'hours_week', 'native_country', 'label']
PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"
PATH_test = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test"
I dati memorizzati online sono giร suddivisi tra treno e set di prova.
df_train = pd.read_csv(PATH, skipinitialspace=True, names = COLUMNS, index_col=False) df_test = pd.read_csv(PATH_test,skiprows = 1, skipinitialspace=True, names = COLUMNS, index_col=False)
Il set di treni contiene 32,561 osservazioni e il set di test 16,281
print(df_train.shape, df_test.shape) print(df_train.dtypes) (32561, 15) (16281, 15) age int64 workclass object fnlwgt int64 education object education_num int64 marital object occupation object relationship object race object sex object capital_gain int64 capital_loss int64 hours_week int64 native_country object label object dtype: object
Tensorflow richiede un valore booleano per addestrare il classificatore. ร necessario trasmettere i valori da stringa a numero intero. L'etichetta viene memorizzata come oggetto, tuttavia รจ necessario convertirla in un valore numerico. Il codice seguente crea un dizionario con i valori da convertire ed eseguire il loop sull'elemento della colonna. Tieni presente che questa operazione viene eseguita due volte, una per il test del treno e una per il test set
label = {'<=50K': 0,'>50K': 1}
df_train.label = [label[item] for item in df_train.label]
label_t = {'<=50K.': 0,'>50K.': 1}
df_test.label = [label_t[item] for item in df_test.label]
Nei dati dei treni risultano 24,720 redditi inferiori a 50mila e 7841 superiori. Il rapporto รจ quasi lo stesso per il set di prova. Per ulteriori informazioni, fare riferimento a questo tutorial su Facets.
print(df_train["label"].value_counts()) ### The model will be correct in atleast 70% of the case print(df_test["label"].value_counts()) ## Unbalanced label print(df_train.dtypes) 0 24720 1 7841 Name: label, dtype: int64 0 12435 1 3846 Name: label, dtype: int64 age int64 workclass object fnlwgt int64 education object education_num int64 marital object occupation object relationship object race object sex object capital_gain int64 capital_loss int64 hours_week int64 native_country object label int64 dtype: object
Passaggio 2) Conversione dei dati
Sono necessari alcuni passaggi prima di addestrare un classificatore lineare con Tensorflow. ร necessario preparare le feature da includere nel modello. Nella regressione benchmark utilizzerai i dati originali senza applicare alcuna trasformazione.
Lo stimatore deve disporre di un elenco di funzionalitร per addestrare il modello. Pertanto, i dati della colonna devono essere convertiti in un tensore.
Una buona pratica รจ definire due elenchi di funzionalitร in base al loro tipo e quindi passarli nella feature_columns dello stimatore.
Inizierai convertendo le feature continue, quindi definirai un bucket con i dati categorici.
Le funzionalitร del set di dati hanno due formati:
- Numero intero
- Oggetto
Ciascuna caratteristica รจ elencata nelle due variabili successive in base al tipo.
## Add features to the bucket: ### Define continuous list CONTI_FEATURES = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week'] ### Define the categorical list CATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']
La feature_column รจ dotata di un oggetto numeric_column per aiutare nella trasformazione delle variabili continue in tensore. Nel codice seguente, converti tutte le variabili da CONTI_FEATURES in un tensore con un valore numerico. Questo รจ obbligatorio per costruire il modello. Tutte le variabili indipendenti devono essere convertite nel tipo corretto di tensore.
Di seguito scriviamo un codice per farti vedere cosa sta succedendo dietro feature_column.numeric_column. Stamperemo il valore convertito per age. ร a scopo esplicativo, quindi non รจ necessario comprendere il codice Python. ร possibile fare riferimento alla documentazione ufficiale per comprendere i codici.
def print_transformation(feature = "age", continuous = True, size = 2):
#X = fc.numeric_column(feature)
## Create feature name
feature_names = [
feature]
## Create dict with the data
d = dict(zip(feature_names, [df_train[feature]]))
## Convert age
if continuous == True:
c = tf.feature_column.numeric_column(feature)
feature_columns = [c]
else:
c = tf.feature_column.categorical_column_with_hash_bucket(feature, hash_bucket_size=size)
c_indicator = tf.feature_column.indicator_column(c)
feature_columns = [c_indicator]
## Use input_layer to print the value
input_layer = tf.feature_column.input_layer(
features=d,
feature_columns=feature_columns
)
## Create lookup table
zero = tf.constant(0, dtype=tf.float32)
where = tf.not_equal(input_layer, zero)
## Return lookup tble
indices = tf.where(where)
values = tf.gather_nd(input_layer, indices)
## Initiate graph
sess = tf.Session()
## Print value
print(sess.run(input_layer))
print_transformation(feature = "age", continuous = True)
[[39.]
[50.]
[38.]
...
[58.]
[22.]
[52.]]
I valori sono esattamente gli stessi di df_train
continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]
Secondo la documentazione di TensorFlow, esistono diversi modi per convertire i dati categorici. Se l'elenco dei vocaboli di una funzionalitร รจ noto e non ha molti valori, รจ possibile creare la colonna categoriale con categorical_column_with_vocabulary_list. Assegnerร a tutti gli elenchi di vocaboli univoci un ID.
Ad esempio, se lo stato di una variabile ha tre valori distinti:
- Marito
- Moglie
- Singolo
Verranno quindi attribuiti tre ID. Ad esempio, il marito avrร l'ID 1, la moglie l'ID 2 e cosรฌ via.
A scopo illustrativo, puoi utilizzare questo codice per convertire una variabile oggetto in una colonna categoriale in TensorFlow.
La caratteristica sesso puรฒ avere solo due valori: maschile o femminile. Quando convertiremo la funzione sesso, Tensorflow creerร 2 nuove colonne, una per maschio e una per femmina. Se il sesso รจ uguale a maschio, la nuova colonna maschile sarร uguale a 1 e femminile a 0. Questo esempio รจ visualizzato nella tabella seguente:
| righe | sesso | dopo la trasformazione | maschio | la donna |
|---|---|---|---|---|
| 1 | maschio | => | 1 | 0 |
| 2 | maschio | => | 1 | 0 |
| 3 | la donna | => | 0 | 1 |
Nel tensorflusso:
print_transformation(feature = "sex", continuous = False, size = 2)
[[1. 0.]
[1. 0.]
[1. 0.]
...
[0. 1.]
[1. 0.]
[0. 1.]]
relationship = tf.feature_column.categorical_column_with_vocabulary_list(
'relationship', [
'Husband', 'Not-in-family', 'Wife', 'Own-child', 'Unmarried',
'Other-relative'])
Di seguito, abbiamo aggiunto Python code per stampare la codifica. Ancora una volta, non รจ necessario comprendere il codice, lo scopo รจ vedere la trasformazione
Tuttavia, un modo piรน rapido per trasformare i dati รจ utilizzare il metodo categorical_column_with_hash_bucket. Sarร utile modificare le variabili stringa in una matrice sparsa. Una matrice sparsa รจ una matrice con prevalentemente zero. Il metodo si occupa di tutto. Devi solo specificare il numero di bucket e la colonna chiave. Il numero di bucket รจ la quantitร massima di gruppi che Tensorflow puรฒ creare. La colonna chiave รจ semplicemente il nome della colonna da convertire.
Nel codice seguente, crei un ciclo su tutte le funzionalitร categoriali.
categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]
Passaggio 3) Addestrare il classificatore
TensorFlow attualmente fornisce uno stimatore per la regressione lineare e la classificazione lineare.
- Regressione lineare: LinearRegressor
- Classificazione lineare: LinearClassifier
La sintassi del classificatore lineare รจ la stessa del tutorial su regressione lineare tranne un argomento, n_class. ร necessario definire la colonna delle caratteristiche, la directory del modello e confrontarla con il regressore lineare; devi definire il numero di classe. Per una regressione logit, il numero di classi รจ uguale a 2.
Il modello calcolerร i pesi delle colonne contenute in Continuous_features e categorical_features.
model = tf.estimator.LinearClassifier(
n_classes = 2,
model_dir="ongoing/train",
feature_columns=categorical_features+ continuous_features)
Uscita
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/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 0x181f24c898>, '_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}
Ora che il classificatore รจ definito, puoi creare la funzione di input. Il metodo รจ lo stesso del tutorial sul regressore lineare. In questo caso si utilizza una dimensione batch di 128 e si mescolano i dati.
FEATURES = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country']
LABEL= 'label'
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)
Crei una funzione con gli argomenti richiesti dallo stimatore lineare, ovvero numero di epoche, numero di lotti e mescola il set di dati o la nota. Dal momento che usi il Pandas metodo per passare i dati nel modello, รจ necessario definire le variabili X come frame di dati panda. Tieni presente che esegui il loop su tutti i dati memorizzati in FEATURES.
Addestriamo il modello con l'oggetto model.train. Si utilizza la funzione definita in precedenza per alimentare il modello con i valori appropriati. Tieni presente che imposti la dimensione batch su 128 e il numero di epoche su Nessuna. Il modello verrร addestrato su mille passaggi.
model.train(input_fn=get_input_fn(df_train,
num_epochs=None,
n_batch = 128,
shuffle=False),
steps=1000)
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 ongoing/train/model.ckpt. INFO:tensorflow:loss = 88.722855, step = 1 INFO:tensorflow:global_step/sec: 65.8282 INFO:tensorflow:loss = 52583.64, step = 101 (1.528 sec) INFO:tensorflow:global_step/sec: 118.386 INFO:tensorflow:loss = 25203.816, step = 201 (0.837 sec) INFO:tensorflow:global_step/sec: 110.542 INFO:tensorflow:loss = 54924.312, step = 301 (0.905 sec) INFO:tensorflow:global_step/sec: 199.03 INFO:tensorflow:loss = 68509.31, step = 401 (0.502 sec) INFO:tensorflow:global_step/sec: 167.488 INFO:tensorflow:loss = 9151.754, step = 501 (0.599 sec) INFO:tensorflow:global_step/sec: 220.155 INFO:tensorflow:loss = 34576.06, step = 601 (0.453 sec) INFO:tensorflow:global_step/sec: 199.016 INFO:tensorflow:loss = 36047.117, step = 701 (0.503 sec) INFO:tensorflow:global_step/sec: 197.531 INFO:tensorflow:loss = 22608.148, step = 801 (0.505 sec) INFO:tensorflow:global_step/sec: 208.479 INFO:tensorflow:loss = 22201.918, step = 901 (0.479 sec) INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train/model.ckpt. INFO:tensorflow:Loss for final step: 5444.363. <tensorflow.python.estimator.canned.linear.LinearClassifier at 0x181f223630>
Da notare che la perdita รจ diminuita successivamente durante gli ultimi 100 passi, cioรจ da 901 a 1000.
La perdita finale dopo mille iterazioni รจ 5444. Puoi stimare il tuo modello sul set di test e vedere le prestazioni. Per valutare le prestazioni del tuo modello, devi utilizzare l'oggettovaluta. Si alimenta il modello con il set di test e si imposta il numero di epoche su 1, ovvero i dati verranno inviati al modello solo una volta.
model.evaluate(input_fn=get_input_fn(df_test,
num_epochs=1,
n_batch = 128,
shuffle=False),
steps=1000)
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:22
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:23
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7615626, accuracy_baseline = 0.76377374, auc = 0.63300294, auc_precision_recall = 0.50891197, average_loss = 47.12155, global_step = 1000, label/mean = 0.23622628, loss = 5993.6406, precision = 0.49401596, prediction/mean = 0.18454961, recall = 0.38637546
{'accuracy': 0.7615626,
'accuracy_baseline': 0.76377374,
'auc': 0.63300294,
'auc_precision_recall': 0.50891197,
'average_loss': 47.12155,
'global_step': 1000,
'label/mean': 0.23622628,
'loss': 5993.6406,
'precision': 0.49401596,
'prediction/mean': 0.18454961,
'recall': 0.38637546}
TensorFlow restituisce tutte le metriche apprese nella parte teorica. Senza sorpresa, la precisione รจ elevata a causa dell'etichetta sbilanciata. In realtร , il modello funziona leggermente meglio di un'ipotesi casuale. Immagina che il modello preveda tutte le famiglie con reddito inferiore a 50, quindi il modello ha una precisione del 70%. Ad un'analisi piรน attenta, puoi vedere che la previsione e il richiamo sono piuttosto bassi.
Passaggio 4) Migliorare il modello
Ora che hai un modello di riferimento, puoi provare a migliorarlo, ovvero ad aumentare la precisione. Nel tutorial precedente hai imparato come migliorare il potere di previsione con un termine di interazione. In questo tutorial rivisiterai questa idea aggiungendo un termine polinomiale alla regressione.
La regressione polinomiale รจ strumentale quando รจ presente non linearitร nei dati. Esistono due modi per acquisire la non linearitร nei dati.
- Aggiungi termine polinomiale
- Dividere la variabile continua in una variabile categoriale
Termine polinomiale
Dall'immagine qui sotto puoi vedere cos'รจ una regressione polinomiale. ร un'equazione con X variabili con potenza diversa. Una regressione polinomiale di secondo grado ha due variabili, X e X al quadrato. Il terzo grado ha tre variabili, X, X2, e X3

Di seguito, abbiamo costruito un grafico con due variabili, X e Y. ร ovvio che la relazione non รจ lineare. Se aggiungiamo una regressione lineare, possiamo vedere che il modello non รจ in grado di catturare il modello (immagine a sinistra).
Ora, guarda l'immagine a sinistra dell'immagine qui sotto, abbiamo aggiunto cinque termini alla regressione (ovvero y=x+x2+x3+x4+x5. Il modello ora cattura molto meglio il modello. Questo รจ il potere della regressione polinomiale.
Torniamo al nostro esempio. Lโetร non รจ in una relazione lineare con il reddito. La giovane etร potrebbe avere un reddito piatto vicino allo zero perchรฉ i bambini o i giovani non lavorano. Poi aumenta in etร lavorativa e diminuisce durante la pensione. Tipicamente รจ una forma a U rovesciata. Un modo per catturare questo modello รจ aggiungere una potenza due alla regressione.
Vediamo se aumenta la precisione.
ร necessario aggiungere questa nuova funzionalitร al set di dati e nell'elenco delle funzionalitร continue.
Aggiungi la nuova variabile nel set di dati train e test, quindi รจ piรน conveniente scrivere una funzione.
def square_var(df_t, df_te, var_name = 'age'):
df_t['new'] = df_t[var_name].pow(2)
df_te['new'] = df_te[var_name].pow(2)
return df_t, df_te
La funzione ha 3 argomenti:
- df_t: definisce il set di addestramento
- df_te: definisce il set di test
- var_name = 'age': definisce la variabile da trasformare
Puoi usare l'oggetto pow(2) per elevare al quadrato la variabile etร . Tieni presente che la nuova variabile si chiama "new"
Ora che la funzione sq_var รจ stata scritta, puoi creare i nuovi set di dati.
df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')
Come puoi vedere, il nuovo set di dati ha un'altra funzionalitร .
print(df_train_new.shape, df_test_new.shape) (32561, 16) (16281, 16)
La variabile quadrata รจ chiamata new nel set di dati. ร necessario aggiungerlo all'elenco delle funzionalitร continue.
CONTI_FEATURES_NEW = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week', 'new'] continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW]
Note: che hai cambiato la directory di Graph. Non รจ possibile addestrare modelli diversi nella stessa directory. Significa che devi cambiare il percorso dell'argomento model_dir. In caso contrario, TensorFlow genererร un errore.
model_1 = tf.estimator.LinearClassifier(
model_dir="ongoing/train1",
feature_columns=categorical_features+ continuous_features_new)
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/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 0x1820f04b70>, '_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}
FEATURES_NEW = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country', 'new']
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_NEW}),
y = pd.Series(data_set[LABEL].values),
batch_size=n_batch,
num_epochs=num_epochs,
shuffle=shuffle)
Ora che il classificatore รจ stato progettato con il nuovo set di dati, puoi addestrare e valutare il modello.
model_1.train(input_fn=get_input_fn(df_train,
num_epochs=None,
n_batch = 128,
shuffle=False),
steps=1000)
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 ongoing/train1/model.ckpt. INFO:tensorflow:loss = 88.722855, step = 1 INFO:tensorflow:global_step/sec: 81.487 INFO:tensorflow:loss = 70077.66, step = 101 (1.228 sec) INFO:tensorflow:global_step/sec: 111.169 INFO:tensorflow:loss = 49522.082, step = 201 (0.899 sec) INFO:tensorflow:global_step/sec: 128.91 INFO:tensorflow:loss = 107120.57, step = 301 (0.776 sec) INFO:tensorflow:global_step/sec: 132.546 INFO:tensorflow:loss = 12814.152, step = 401 (0.755 sec) INFO:tensorflow:global_step/sec: 162.194 INFO:tensorflow:loss = 19573.898, step = 501 (0.617 sec) INFO:tensorflow:global_step/sec: 204.852 INFO:tensorflow:loss = 26381.986, step = 601 (0.488 sec) INFO:tensorflow:global_step/sec: 188.923 INFO:tensorflow:loss = 23417.719, step = 701 (0.529 sec) INFO:tensorflow:global_step/sec: 192.041 INFO:tensorflow:loss = 23946.049, step = 801 (0.521 sec) INFO:tensorflow:global_step/sec: 197.025 INFO:tensorflow:loss = 3309.5786, step = 901 (0.507 sec) INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train1/model.ckpt. INFO:tensorflow:Loss for final step: 28861.898. <tensorflow.python.estimator.canned.linear.LinearClassifier at 0x1820f04c88>
model_1.evaluate(input_fn=get_input_fn(df_test_new,
num_epochs=1,
n_batch = 128,
shuffle=False),
steps=1000)
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:37
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:39
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7944229, accuracy_baseline = 0.76377374, auc = 0.6093755, auc_precision_recall = 0.54885805, average_loss = 111.0046, global_step = 1000, label/mean = 0.23622628, loss = 14119.265, precision = 0.6682401, prediction/mean = 0.09116262, recall = 0.2576703
{'accuracy': 0.7944229,
'accuracy_baseline': 0.76377374,
'auc': 0.6093755,
'auc_precision_recall': 0.54885805,
'average_loss': 111.0046,
'global_step': 1000,
'label/mean': 0.23622628,
'loss': 14119.265,
'precision': 0.6682401,
'prediction/mean': 0.09116262,
'recall': 0.2576703}
La variabile quadrata ha migliorato la precisione da 0.76 a 0.79. Vediamo se riesci a fare meglio combinando insieme il termine bucketizzazione e interazione.
Secchizzazione e interazione
Come hai visto prima, un classificatore lineare non รจ in grado di catturare correttamente il modello etร -reddito. Questo perchรฉ apprende un singolo peso per ciascuna funzione. Per semplificare il compito del classificatore, una cosa che puoi fare รจ inserire la funzionalitร in un bucket. Il bucket trasforma una caratteristica numerica in diverse determinate in base all'intervallo in cui rientra e ciascuna di queste nuove funzionalitร indica se l'etร di una persona rientra in tale intervallo.
Con queste nuove funzionalitร , il modello lineare puรฒ catturare la relazione apprendendo pesi diversi per ciascun segmento.
In TensorFlow, viene eseguito con bucketized_column. ร necessario aggiungere l'intervallo di valori nei limiti.
age = tf.feature_column.numeric_column('age')
age_buckets = tf.feature_column.bucketized_column(
age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65])
Sai giร che l'etร non รจ lineare con il reddito. Un altro modo per migliorare il modello รจ attraverso l'interazione. In termini di TensorFlow, si tratta di incrocio di funzionalitร . L'incrocio di funzionalitร รจ un modo per creare nuove funzionalitร che sono combinazioni di quelle esistenti, il che puรฒ essere utile per un classificatore lineare che non puรฒ modellare le interazioni tra le funzionalitร .
Puoi scomporre l'etร con un'altra caratteristica come l'istruzione. Cioรจ, รจ probabile che alcuni gruppi abbiano un reddito alto e altri basso (si pensi allo studente di dottorato).
education_x_occupation = [tf.feature_column.crossed_column(
['education', 'occupation'], hash_bucket_size=1000)]
age_buckets_x_education_x_occupation = [tf.feature_column.crossed_column(
[age_buckets, 'education', 'occupation'], hash_bucket_size=1000)]
Per creare una colonna con caratteristiche incrociate, utilizzare cross_column con le variabili da incrociare tra parentesi. L'hash_bucket_size indica le massime possibilitร di incrocio. Per creare interazione tra variabili (almeno una variabile deve essere categorica), puoi utilizzare tf.feature_column.crossed_column. Per utilizzare questo oggetto รจ necessario aggiungere tra parentesi quadre la variabile con cui interagire e un secondo argomento, la dimensione del bucket. La dimensione del bucket รจ il numero massimo di gruppi possibili all'interno di una variabile. Qui lo imposti su 1000 poichรฉ non conosci il numero esatto di gruppi
age_buckets deve essere elevato al quadrato prima di aggiungerlo alle colonne delle funzionalitร . Aggiungi anche le nuove funzionalitร alle colonne delle funzionalitร e prepari lo stimatore
base_columns = [
age_buckets,
]
model_imp = tf.estimator.LinearClassifier(
model_dir="ongoing/train3",
feature_columns=categorical_features+base_columns+education_x_occupation+age_buckets_x_education_x_occupation)
Uscita
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/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 0x1823021be0>, '_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}
FEATURES_imp = ['age','workclass', 'education', 'education_num', 'marital',
'occupation', 'relationship', 'race', 'sex', 'native_country', 'new']
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_imp}),
y = pd.Series(data_set[LABEL].values),
batch_size=n_batch,
num_epochs=num_epochs,
shuffle=shuffle)
Sei pronto per stimare il nuovo modello e vedere se migliora la precisione.
model_imp.train(input_fn=get_input_fn(df_train_new,
num_epochs=None,
n_batch = 128,
shuffle=False),
steps=1000)
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 ongoing/train3/model.ckpt. INFO:tensorflow:loss = 88.722855, step = 1 INFO:tensorflow:global_step/sec: 94.969 INFO:tensorflow:loss = 50.334488, step = 101 (1.054 sec) INFO:tensorflow:global_step/sec: 242.342 INFO:tensorflow:loss = 56.153225, step = 201 (0.414 sec) INFO:tensorflow:global_step/sec: 213.686 INFO:tensorflow:loss = 45.792007, step = 301 (0.470 sec) INFO:tensorflow:global_step/sec: 174.084 INFO:tensorflow:loss = 37.485672, step = 401 (0.572 sec) INFO:tensorflow:global_step/sec: 191.78 INFO:tensorflow:loss = 56.48449, step = 501 (0.524 sec) INFO:tensorflow:global_step/sec: 163.436 INFO:tensorflow:loss = 32.528934, step = 601 (0.612 sec) INFO:tensorflow:global_step/sec: 164.347 INFO:tensorflow:loss = 37.438057, step = 701 (0.607 sec) INFO:tensorflow:global_step/sec: 154.274 INFO:tensorflow:loss = 61.1075, step = 801 (0.647 sec) INFO:tensorflow:global_step/sec: 189.14 INFO:tensorflow:loss = 44.69645, step = 901 (0.531 sec) INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train3/model.ckpt. INFO:tensorflow:Loss for final step: 44.18133. <tensorflow.python.estimator.canned.linear.LinearClassifier at 0x1823021cf8>
model_imp.evaluate(input_fn=get_input_fn(df_test_new,
num_epochs=1,
n_batch = 128,
shuffle=False),
steps=1000)
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:52
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train3/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:54
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.8358209, accuracy_baseline = 0.76377374, auc = 0.88401634, auc_precision_recall = 0.69599575, average_loss = 0.35122654, global_step = 1000, label/mean = 0.23622628, loss = 44.67437, precision = 0.68986726, prediction/mean = 0.23320661, recall = 0.55408216
{'accuracy': 0.8358209,
'accuracy_baseline': 0.76377374,
'auc': 0.88401634,
'auc_precision_recall': 0.69599575,
'average_loss': 0.35122654,
'global_step': 1000,
'label/mean': 0.23622628,
'loss': 44.67437,
'precision': 0.68986726,
'prediction/mean': 0.23320661,
'recall': 0.55408216}
Il nuovo livello di precisione รจ pari all'83.58%. ร del XNUMX% piรน alto rispetto al modello precedente.
Infine, รจ possibile aggiungere un termine di regolarizzazione per evitare un overfitting.
Passaggio 5) Iperparametro: Lazo e Ridge
Il tuo modello puรฒ soffrirne overfitting or inadeguato.
- Overfitting: il modello non รจ in grado di generalizzare la previsione a nuovi dati
- Underfitting: il modello non รจ in grado di catturare il modello dei dati. cioรจ, regressione lineare quando i dati non sono lineari
Quando un modello ha molti parametri e una quantitร relativamente bassa di dati, porta a previsioni inadeguate. Immagina, un gruppo ha solo tre osservazioni; il modello calcolerร un peso per questo gruppo. Il peso viene utilizzato per fare una previsione; se le osservazioni del set di test per questo particolare gruppo sono completamente diverse dal set di addestramento, il modello farร una previsione sbagliata. Durante la valutazione con il set di addestramento, la precisione รจ buona, ma non buona con il set di test perchรฉ i pesi calcolati non sono quelli reali per generalizzare il modello. In questo caso, non fa una previsione ragionevole su dati invisibili.
Per evitare l'overfitting, la regolarizzazione ti dร la possibilitร di controllare tale complessitร e renderla piรน generalizzabile. Esistono due tecniche di regolarizzazione:
- L1: Lazo
- L2: Cresta
In TensorFlow, puoi aggiungere questi due iperparametri nell'ottimizzatore. Ad esempio, quanto piรน alto รจ l'iperparametro L2, tanto piรน il peso tende ad essere molto basso e prossimo allo zero. La linea adattata sarร molto piatta, mentre una L2 vicina allo zero implica che i pesi siano vicini alla regressione lineare regolare.
Puoi provare tu stesso i diversi valori degli iperparametri e vedere se riesci ad aumentare il livello di precisione.
Note: che se si modifica l'iperparametro, รจ necessario eliminare la cartella going/train4 altrimenti il โโmodello partirร con il modello precedentemente addestrato.
Vediamo come รจ la precisione con l'hype
model_regu = tf.estimator.LinearClassifier(
model_dir="ongoing/train4", feature_columns=categorical_features+base_columns+education_x_occupation+age_buckets_x_education_x_occupation,
optimizer=tf.train.FtrlOptimizer(
learning_rate=0.1,
l1_regularization_strength=0.9,
l2_regularization_strength=5))
USCITA
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train4', '_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 0x1820d9c128>, '_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}
model_regu.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 ongoing/train4/model.ckpt. INFO:tensorflow:loss = 88.722855, step = 1 INFO:tensorflow:global_step/sec: 77.4165 INFO:tensorflow:loss = 50.38778, step = 101 (1.294 sec) INFO:tensorflow:global_step/sec: 187.889 INFO:tensorflow:loss = 55.38014, step = 201 (0.535 sec) INFO:tensorflow:global_step/sec: 201.895 INFO:tensorflow:loss = 46.806694, step = 301 (0.491 sec) INFO:tensorflow:global_step/sec: 217.992 INFO:tensorflow:loss = 38.68271, step = 401 (0.460 sec) INFO:tensorflow:global_step/sec: 193.676 INFO:tensorflow:loss = 56.99398, step = 501 (0.516 sec) INFO:tensorflow:global_step/sec: 202.195 INFO:tensorflow:loss = 33.263622, step = 601 (0.497 sec) INFO:tensorflow:global_step/sec: 216.756 INFO:tensorflow:loss = 37.7902, step = 701 (0.459 sec) INFO:tensorflow:global_step/sec: 240.215 INFO:tensorflow:loss = 61.732605, step = 801 (0.416 sec) INFO:tensorflow:global_step/sec: 220.336 INFO:tensorflow:loss = 46.938225, step = 901 (0.456 sec) INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train4/model.ckpt. INFO:tensorflow:Loss for final step: 43.4942. <tensorflow.python.estimator.canned.linear.LinearClassifier at 0x181ff39e48>
model_regu.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.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:29:07
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train4/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:29:09
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.83833915, accuracy_baseline = 0.76377374, auc = 0.8869794, auc_precision_recall = 0.7014905, average_loss = 0.34691378, global_step = 1000, label/mean = 0.23622628, loss = 44.12581, precision = 0.69720596, prediction/mean = 0.23662092, recall = 0.5579823
{'accuracy': 0.83833915,
'accuracy_baseline': 0.76377374,
'auc': 0.8869794,
'auc_precision_recall': 0.7014905,
'average_loss': 0.34691378,
'global_step': 1000,
'label/mean': 0.23622628,
'loss': 44.12581,
'precision': 0.69720596,
'prediction/mean': 0.23662092,
'recall': 0.5579823}
Con questo iperparametro aumenti leggermente le metriche di precisione. Nel prossimo tutorial imparerai come migliorare un classificatore lineare utilizzando un metodo kernel.
Sintesi
Per addestrare un modello, รจ necessario:
- Definire le caratteristiche: Variabili indipendenti: X
- Definire l'etichetta: Variabile dipendente: y
- Costruisci un set di treni/test
- Definire il peso iniziale
- Definire la funzione di perdita: MSE
- Ottimizza il modello: discesa del gradiente
- Definire:
- Tasso di apprendimento
- Numero di epoche
- Dimensione del lotto
- Numero di classe
In questo tutorial hai imparato come utilizzare l'API di alto livello per un classificatore di regressione lineare. ร necessario definire:
- Colonne di funzionalitร . Se continuo: tf.feature_column.numeric_column(). Puoi popolare un elenco con la comprensione dell'elenco Python
- Lo stimatore: tf.estimator.LinearClassifier(feature_columns, model_dir, n_classes = 2)
- Una funzione per importare i dati, la dimensione del batch e l'epoca: input_fn()
Successivamente, sei pronto per allenarti, valutare e fare una previsione con train(),valuta() e predit()
Per migliorare le prestazioni del modello รจ possibile:
- Utilizzare la regressione polinomiale
- Termine di interazione: tf.feature_column.crossed_column
- Aggiungi parametro di regolarizzazione




