Le due attività di apprendimento supervisionato più comuni sono la regressione lineare e il classificatore lineare. La regressione lineare prevede un valore mentre il classificatore lineare predice una classe. Questo tutorial è incentrato sul classificatore lineare.
Cos'è il classificatore lineare?
Un 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% dell'attività di apprendimento automatico. 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 è 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 pone il focus principale sulla classe binaria. Imparerai di più sulla funzione di output multiclasse in un tutorial futuro.
In questo tutorial imparerai
- Cos'è il classificatore lineare?
- Come funziona il classificatore binario?
- Come misurare le prestazioni del classificatore lineare?
- Precisione
- Matrice di confusione
- Precisione e sensibilità
- Classificatore lineare con TensorFlow
- Passaggio 1) Importa i dati
- Passaggio 2) Conversione dei dati
- Passaggio 3) Addestra il classificatore
- Passaggio 4) Migliora il modello
- Passaggio 5) Iperparametro: Lazo e cresta
Come funziona il classificatore binario?
Hai appreso nel tutorial precedente 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 principale è prevedere il suo 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 ogni cliente nella classe più probabile a cui appartiene, vale a dire, potenziale acquirente o meno.
La probabilità di successo viene calcolata con la regressione logistica . L'algoritmo calcolerà una probabilità in base alla funzione X e prevede un successo quando questa probabilità è superiore al 50 percento. Più formalmente, la probabilità viene calcolata come mostrato nell'esempio di classificazione binaria TensorFlow di seguito:
dove 0 è l'insieme di pesi, le caratteristiche eb il bias.
La funzione può essere scomposta in due parti:
- Il modello lineare
- La funzione logistica
Modello lineare
Hai già familiarità con il modo in cui vengono calcolati i pesi. I pesi vengono calcolati utilizzando un prodotto scalare: Y è una funzione lineare di tutte le caratteristiche x i . Se il modello non ha caratteristiche, la previsione è uguale al bias, b.
I pesi indicano la direzione della correlazione tra le caratteristiche x i 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.

Esempio di funzione logistica
È facile sostituire l'output della regressione lineare nella funzione sigmoidea. Risulta in un nuovo numero con una probabilità tra 0 e 1.
Il classificatore può trasformare la probabilità in una classe
- I valori compresi tra 0 e 0,49 diventano di classe 0
- I valori compresi tra 0,5 e 1 diventano di classe 1
Come misurare le prestazioni del classificatore lineare?
Precisione
La prestazione complessiva di un classificatore viene misurata con la metrica di precisione. La precisione raccoglie tutti i valori corretti divisi per il numero totale di osservazioni. Ad esempio, un valore di precisione dell'80% indica che il modello è corretto nell'80% dei casi.

Misurare le prestazioni del classificatore lineare utilizzando la metrica di precisione
Puoi notare un difetto con questa metrica, specialmente per la classe di squilibrio. Un insieme di dati di squilibrio si verifica quando il numero di osservazioni per gruppo non è uguale. Diciamo; cerchi di classificare un evento raro con una funzione logistica. Immagina che il classificatore cerchi di stimare la morte di un paziente a seguito di una malattia. Nei dati, il 5% dei pazienti muore. È possibile addestrare un classificatore a prevedere il numero di decessi e utilizzare la metrica di precisione 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.

Misurare le prestazioni del classificatore lineare utilizzando la matrice di confusione
La 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 hanno previsto in modo errato un effettivo positivo. vale a dire, valori negativi previsti come positivi
- FN: falso negativo: valori positivi previsti come negativi
- TN: True Negative: Valori previsti correttamente previsti come effettivi negativi
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 è generalmente associata alla metrica Recall. Il richiamo è anche chiamato sensibilità o tasso di vero positivo.
Sensibilità
La sensibilità calcola il rapporto tra le classi positive rilevate correttamente. Questa metrica indica quanto è bravo il modello a 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. Nota che il reddito è una variabile binaria
- con un valore di 1 se il reddito> 50k
- 0 se reddito <50k.
Questa variabile è la tua etichetta
Questo set di dati include otto variabili categoriali:
- posto di lavoro
- formazione scolastica
- coniugale
- occupazione
- relazione
- gara
- sesso
- Paese d'origine
inoltre sei variabili continue:
- età
- fnlwgt
- education_num
- plusvalenza
- capital_loss
- ore_settimana
Attraverso questo esempio di classificazione TensorFlow, capirai come addestrare 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) Addestra il classificatore
- Passaggio 4) Migliora il modello
- Passaggio 5) Iperparametro: Lazo e cresta
Passaggio 1) Importa i dati
Per prima cosa importi le librerie utilizzate durante il tutorial.
import tensorflow as tfimport pandas as pd
Successivamente, si importano i dati dall'archivio dell'UCI e si definiscono i nomi delle colonne. Utilizzerai le COLONNE per denominare le colonne in un frame di dati Panda.
Nota che addestrerai il classificatore utilizzando un dataframe Pandas.
## Define path dataCOLUMNS = ['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 un treno e un 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 int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel objectdtype: object
Tensorflow richiede un valore booleano per addestrare il classificatore. È necessario eseguire il cast dei valori dalla stringa al numero intero. L'etichetta è memorizzata come un oggetto, tuttavia, è necessario convertirla in un valore numerico. Il codice seguente crea un dizionario con i valori da convertire e scorrere l'elemento della colonna. Notare che si esegue questa operazione due volte, una per il test del treno, una per il set di test
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 sui treni, ci sono 24.720 redditi inferiori a 50k e 7841 superiori. Il rapporto è quasi lo stesso per il set di prova. Fare riferimento a questo tutorial su Facets per ulteriori informazioni.
print(df_train["label"].value_counts())### The model will be correct in atleast 70% of the caseprint(df_test["label"].value_counts())## Unbalanced labelprint(df_train.dtypes)0 247201 7841Name: label, dtype: int640 124351 3846Name: label, dtype: int64age int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel int64dtype: object
Passaggio 2) Conversione dei dati
Sono necessari alcuni passaggi prima di addestrare un classificatore lineare con Tensorflow. È necessario preparare le funzionalità da includere nel modello. Nella regressione del benchmark, utilizzerai i dati originali senza applicare alcuna trasformazione.
Lo stimatore deve disporre di un elenco di funzionalità per addestrare il modello. Quindi, i dati della colonna devono essere convertiti in un tensore.
Una buona pratica consiste nel definire due elenchi di caratteristiche in base al loro tipo e quindi passarle nelle colonne_fatture dello stimatore.
Inizierai convertendo le caratteristiche continue, quindi definirai un bucket con i dati categoriali.
Le funzionalità del set di dati hanno due formati:
- Numero intero
- Oggetto
Ogni caratteristica è elencata nelle due variabili successive secondo i loro tipi.
## Add features to the bucket:### Define continuous listCONTI_FEATURES = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']### Define the categorical listCATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']
Il feature_column è dotato 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 appropriato di tensore.
Di seguito scriviamo un codice per farti vedere cosa sta succedendo dietro feature_column.numeric_column. Stamperemo il valore convertito per età È 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 namefeature_names = [feature]## Create dict with the datad = dict(zip(feature_names, [df_train[feature]]))## Convert ageif 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 valueinput_layer = tf.feature_column.input_layer(features=d,feature_columns=feature_columns)## Create lookup tablezero = tf.constant(0, dtype=tf.float32)where = tf.not_equal(input_layer, zero)## Return lookup tbleindices = tf.where(where)values = tf.gather_nd(input_layer, indices)## Initiate graphsess = tf.Session()## Print valueprint(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 categoriali. Se l'elenco dei vocaboli di una caratteristica è 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
- Single
Quindi verranno attribuiti tre ID. Ad esempio, Marito avrà l'ID 1, Moglie l'ID 2 e così via.
A scopo illustrativo, è possibile utilizzare questo codice per convertire una variabile oggetto in una colonna categoriale in TensorFlow.
La caratteristica sesso può avere solo due valori: maschio o femmina. Quando convertiremo la funzione sesso, Tensorflow creerà 2 nuove colonne, una per il maschio e una per la femmina. Se il sesso è uguale a maschio, la nuova colonna maschio sarà uguale a 1 e femmina a 0. Questo esempio viene visualizzato nella tabella seguente:
righe |
sesso |
dopo la trasformazione |
maschio |
femmina |
1 |
maschio |
=> |
1 |
0 |
2 |
maschio |
=> |
1 |
0 |
3 |
femmina |
=> |
0 |
1 |
In tensorflow:
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 il codice Python per stampare la codifica. Anche in questo caso, non è necessario comprendere il codice, lo scopo è vedere la trasformazione
Tuttavia, un modo più veloce 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 per lo più 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 caratteristiche categoriali.
categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]
Passaggio 3) Addestra 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 sulla regressione lineare ad eccezione di un argomento, n_class. È necessario definire la colonna delle caratteristiche, la directory del modello e, confrontare con il regressore lineare; hai il 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)
PRODUZIONE:
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':, '_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. Qui 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)
Si crea una funzione con gli argomenti richiesti dallo stimatore lineare, cioè il numero di epoche, il numero di batch e si mescola l'insieme di dati o la nota. Poiché si utilizza il metodo Pandas per passare i dati nel modello, è necessario definire le variabili X come frame di dati Panda. Notare che si ripetono tutti i dati archiviati in FEATURES.
Addestriamo il modello con l'oggetto model.train. Si utilizza la funzione precedentemente definita per alimentare il modello con i valori appropriati. Notare che si imposta la dimensione del batch su 128 e il numero di epoche su Nessuno. 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 = 1INFO:tensorflow:global_step/sec: 65.8282INFO:tensorflow:loss = 52583.64, step = 101 (1.528 sec)INFO:tensorflow:global_step/sec: 118.386INFO:tensorflow:loss = 25203.816, step = 201 (0.837 sec)INFO:tensorflow:global_step/sec: 110.542INFO:tensorflow:loss = 54924.312, step = 301 (0.905 sec)INFO:tensorflow:global_step/sec: 199.03INFO:tensorflow:loss = 68509.31, step = 401 (0.502 sec)INFO:tensorflow:global_step/sec: 167.488INFO:tensorflow:loss = 9151.754, step = 501 (0.599 sec)INFO:tensorflow:global_step/sec: 220.155INFO:tensorflow:loss = 34576.06, step = 601 (0.453 sec)INFO:tensorflow:global_step/sec: 199.016INFO:tensorflow:loss = 36047.117, step = 701 (0.503 sec)INFO:tensorflow:global_step/sec: 197.531INFO:tensorflow:loss = 22608.148, step = 801 (0.505 sec)INFO:tensorflow:global_step/sec: 208.479INFO: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.
Si noti che la perdita è diminuita successivamente durante gli ultimi 100 passaggi, ovvero 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 modello, è necessario utilizzare l'oggetto valutare. Si alimenta il modello con il set di prova e si imposta il numero di epoche su 1, ovvero i dati andranno 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:22INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train/model.ckpt-1000INFO: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:23INFO: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 è grande 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 un reddito inferiore a 50.000, quindi il modello ha una precisione del 70 percento. A un'analisi più attenta, puoi vedere che la previsione e il ricordo sono piuttosto bassi.
Passaggio 4) Migliora il modello
Ora che hai un modello di riferimento, puoi provare a migliorarlo, ovvero 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 c'è non linearità nei dati. Esistono due modi per acquisire la non linearità nei dati.
- Aggiungi un termine polinomiale
- Suddividi la variabile continua in una variabile categoriale
Termine polinomiale
Dall'immagine qui sotto, puoi vedere cos'è una regressione polinomiale. È un'equazione con X variabili di diversa potenza. Una regressione polinomiale di secondo grado ha due variabili, X e X al quadrato. Il terzo grado ha tre variabili, X, X 2 e X 3

Cos'è la regressione polinomiale
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 pattern (immagine a sinistra).
Ora, guarda l'immagine a sinistra dall'immagine sotto, abbiamo aggiunto cinque termini alla regressione (cioè y = x + x 2 + x 3 + x 4 + x 5. 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 prima età potrebbe avere un reddito fisso vicino allo zero perché i bambini oi giovani non lavorano. Quindi aumenta l'età lavorativa e diminuisce durante il pensionamento. È 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.
Aggiungete 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
È possibile utilizzare l'oggetto pow (2) per quadrare la variabile età. Nota che la nuova variabile si chiama "new"
Ora che la funzione square_var è scritta, è possibile 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 viene chiamata nuova 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]
Nota che hai cambiato la directory del grafico. Non puoi addestrare diversi modelli nella stessa directory. Significa che devi cambiare il percorso dell'argomento model_dir. Se non lo fai, 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':, '_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 = 1INFO:tensorflow:global_step/sec: 81.487INFO:tensorflow:loss = 70077.66, step = 101 (1.228 sec)INFO:tensorflow:global_step/sec: 111.169INFO:tensorflow:loss = 49522.082, step = 201 (0.899 sec)INFO:tensorflow:global_step/sec: 128.91INFO:tensorflow:loss = 107120.57, step = 301 (0.776 sec)INFO:tensorflow:global_step/sec: 132.546INFO:tensorflow:loss = 12814.152, step = 401 (0.755 sec)INFO:tensorflow:global_step/sec: 162.194INFO:tensorflow:loss = 19573.898, step = 501 (0.617 sec)INFO:tensorflow:global_step/sec: 204.852INFO:tensorflow:loss = 26381.986, step = 601 (0.488 sec)INFO:tensorflow:global_step/sec: 188.923INFO:tensorflow:loss = 23417.719, step = 701 (0.529 sec)INFO:tensorflow:global_step/sec: 192.041INFO:tensorflow:loss = 23946.049, step = 801 (0.521 sec)INFO:tensorflow:global_step/sec: 197.025INFO: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.
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:37INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train1/model.ckpt-1000INFO: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:39INFO: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 al quadrato ha migliorato la precisione da 0,76 a 0,79. Vediamo se puoi fare di meglio combinando insieme bucketization e termine di interazione.
Bucketization e interazione
Come hai visto prima, un classificatore lineare non è in grado di catturare correttamente il modello di reddito per età. Questo perché apprende un unico peso per ogni caratteristica. Per semplificare il classificatore, una cosa che puoi fare è secchio la funzione. La suddivisione in bucket trasforma una caratteristica numerica in diversi determinati 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 ogni bucket.
In TensorFlow, è fatto con bucketized_column. È necessario aggiungere l'intervallo di valori nei confini.
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. Nella parola di TensorFlow, è l'incrocio di funzionalità. L'incrocio delle caratteristiche è un modo per creare nuove caratteristiche che sono combinazioni di quelle esistenti, che possono essere utili per un classificatore lineare che non può modellare le interazioni tra le caratteristiche.
Puoi scomporre l'età con un'altra caratteristica come l'istruzione. Cioè, è probabile che alcuni gruppi abbiano un reddito alto e altri basso (pensa al dottorando).
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 di feature incrociate, utilizzare Cross_column con le variabili da incrociare in una parentesi. Hash_bucket_size indica le massime possibilità di attraversamento. Per creare interazioni tra le variabili (almeno una variabile deve essere categoriale), 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 possibile all'interno di una variabile. Qui lo imposti a 1000 perché non conosci il numero esatto di gruppi
age_buckets deve essere quadrato prima di aggiungerlo alle colonne delle caratteristiche. Aggiungete anche le nuove funzionalità alle colonne delle caratteristiche e preparate 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)
PRODUZIONE
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':, '_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 = 1INFO:tensorflow:global_step/sec: 94.969INFO:tensorflow:loss = 50.334488, step = 101 (1.054 sec)INFO:tensorflow:global_step/sec: 242.342INFO:tensorflow:loss = 56.153225, step = 201 (0.414 sec)INFO:tensorflow:global_step/sec: 213.686INFO:tensorflow:loss = 45.792007, step = 301 (0.470 sec)INFO:tensorflow:global_step/sec: 174.084INFO:tensorflow:loss = 37.485672, step = 401 (0.572 sec)INFO:tensorflow:global_step/sec: 191.78INFO:tensorflow:loss = 56.48449, step = 501 (0.524 sec)INFO:tensorflow:global_step/sec: 163.436INFO:tensorflow:loss = 32.528934, step = 601 (0.612 sec)INFO:tensorflow:global_step/sec: 164.347INFO:tensorflow:loss = 37.438057, step = 701 (0.607 sec)INFO:tensorflow:global_step/sec: 154.274INFO:tensorflow:loss = 61.1075, step = 801 (0.647 sec)INFO:tensorflow:global_step/sec: 189.14INFO: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.
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:52INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train3/model.ckpt-1000INFO: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:54INFO: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 è dell'83,58 percento. È superiore del quattro percento rispetto al modello precedente.
Infine, puoi aggiungere un termine di regolarizzazione per prevenire l'overfitting.
Passaggio 5) Iperparametro: Lazo e cresta
Il tuo modello può soffrire di overfitting o underfitting .
- Overfitting: il modello non è in grado di generalizzare la previsione a nuovi dati
- Underfitting: il modello non è in grado di acquisire il pattern dei dati. cioè, regressione lineare quando i dati non sono lineari
Quando un modello ha molti parametri e una quantità di dati relativamente bassa, porta a previsioni sbagliate. 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, l'accuratezza è buona, ma non buona con il set di test perché i pesi calcolati non sono quelli veri per generalizzare il pattern. In questo caso, non fa una previsione ragionevole su dati invisibili.
Per prevenire l'overfitting, la regolarizzazione offre la possibilità di controllare tale complessità e renderla più generalizzabile. Esistono due tecniche di regolarizzazione:
- L1: Lazo
- L2: Ridge
In TensorFlow, puoi aggiungere questi due iperparametri nell'ottimizzatore. Ad esempio, più è alto l'iperparametro L2, il peso tende ad essere molto basso e prossimo allo zero. La linea adattata sarà molto piatta, mentre un L2 vicino a zero implica che i pesi siano vicini alla regressione lineare regolare.
Puoi provare da solo il diverso valore degli iperparametri e vedere se puoi aumentare il livello di precisione.
Nota che se modifichi l'iperparametro, devi eliminare la cartella in corso / train4 altrimenti il modello inizierà con il modello addestrato in precedenza.
Vediamo com'è 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))
OUPUT
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':, '_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)
OUPUT
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 = 1INFO:tensorflow:global_step/sec: 77.4165INFO:tensorflow:loss = 50.38778, step = 101 (1.294 sec)INFO:tensorflow:global_step/sec: 187.889INFO:tensorflow:loss = 55.38014, step = 201 (0.535 sec)INFO:tensorflow:global_step/sec: 201.895INFO:tensorflow:loss = 46.806694, step = 301 (0.491 sec)INFO:tensorflow:global_step/sec: 217.992INFO:tensorflow:loss = 38.68271, step = 401 (0.460 sec)INFO:tensorflow:global_step/sec: 193.676INFO:tensorflow:loss = 56.99398, step = 501 (0.516 sec)INFO:tensorflow:global_step/sec: 202.195INFO:tensorflow:loss = 33.263622, step = 601 (0.497 sec)INFO:tensorflow:global_step/sec: 216.756INFO:tensorflow:loss = 37.7902, step = 701 (0.459 sec)INFO:tensorflow:global_step/sec: 240.215INFO:tensorflow:loss = 61.732605, step = 801 (0.416 sec)INFO:tensorflow:global_step/sec: 220.336INFO: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.
model_regu.evaluate(input_fn=get_input_fn(df_test_new,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
PRODUZIONE
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:07INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train4/model.ckpt-1000INFO: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:09INFO: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.
Sommario
Per addestrare un modello, devi:
- Definisci le caratteristiche: Variabili indipendenti: X
- Definisci l'etichetta: Variabile dipendente: y
- Costruisci un treno / set di prova
- Definisci il peso iniziale
- Definisci la funzione di perdita: MSE
- Ottimizza il modello: discesa in gradiente
- Definire:
- Tasso di apprendimento
- Numero di epoca
- Dimensione del lotto
- Numero di classe
In questo tutorial, hai imparato a utilizzare l'API di alto livello per un classificatore di regressione lineare. Devi definire:
- Colonne delle caratteristiche. Se continuo: tf.feature_column.numeric_column (). Puoi popolare un elenco con la comprensione degli elenchi 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 ()
Dopodiché, sei pronto per addestrare, valutare e fare una previsione con train (), assess () e prediction ()
Per migliorare le prestazioni del modello, puoi:
- Usa la regressione polinomiale
- Termine di interazione: tf.feature_column.crossed_column
- Aggiungi parametro di regolarizzazione