Clasificare binară TensorFlow: Exemplu de clasificator liniar

Cele două cele mai frecvente învățare supravegheată sarcinile sunt regresia liniară și clasificatorul liniar. Regresia liniară prezice o valoare în timp ce clasificatorul liniar prezice o clasă. Acest tutorial se concentrează pe clasificatorii liniari.

Ce este clasificatorul liniar?

A Clasificator liniar în Machine Learning este o metodă de găsire a clasei unui obiect pe baza caracteristicilor sale pentru clasificarea statistică. Ea ia decizia de clasificare pe baza valorii unei combinații liniare de caracteristici ale unui obiect. Clasificatorul liniar este utilizat în probleme practice, cum ar fi clasificarea documentelor și problemele care au multe variabile.

Problemele de clasificare reprezintă aproximativ 80% din sarcina de învățare automată. Clasificarea are ca scop prezicerea probabilității fiecărei clase având în vedere un set de intrări. Eticheta (adică variabila dependentă) este o valoare discretă, numită clasă.

  1. Dacă eticheta are doar două clase, algoritmul de învățare este un clasificator binar.
  2. Clasificatorul multiclase abordează etichetele cu mai mult de două clase.

De exemplu, o problemă tipică de clasificare binară este de a prezice probabilitatea ca un client să facă o a doua achiziție. Preziceți tipul de animal afișat pe o imagine este o problemă de clasificare multiclasă, deoarece există mai mult de două soiuri de animale.

Partea teoretică a acestui tutorial se concentrează în primul rând pe clasa binară. Veți afla mai multe despre funcția de ieșire multiclasă într-un tutorial viitor.

Cum funcționează clasificatorul binar?

Ați învățat în tutorialul anterior că o funcție este compusă din două tipuri de variabile, o variabilă dependentă și un set de caracteristici (variabile independente). În regresia liniară, o variabilă dependentă este un număr real fără interval. Obiectivul principal este de a prezice valoarea acesteia prin minimizarea erorii pătratice medii.

Pentru TensorFlow Binary Classifier, eticheta poate avea două valori întregi posibile. În majoritatea cazurilor, este fie [0,1], fie [1,2]. De exemplu, obiectivul este de a prezice dacă un client va cumpăra un produs sau nu. Eticheta este definită după cum urmează:

  • Y = 1 (clientul a achiziționat produsul)
  • Y = 0 (clientul nu cumpără produsul)

Modelul folosește caracteristicile X pentru a clasifica fiecare client în clasa cea mai probabilă căreia îi aparține, și anume potențial cumpărător sau nu.

Probabilitatea de succes se calculează cu regresie logistică. Algoritmul va calcula o probabilitate pe baza caracteristicii X și va prezice un succes atunci când această probabilitate este peste 50 la sută. Mai formal, probabilitatea este calculată așa cum se arată în exemplul de clasificare binară TensorFlow de mai jos:

Exemplu de clasificare binară

unde 0 este setul de greutăți, caracteristicile și b părtinirea.

Funcția poate fi descompusă în două părți:

  • Modelul liniar
  • Funcția logistică

Model liniar

Sunteți deja familiarizat cu modul în care sunt calculate greutățile. Greutățile sunt calculate folosind un produs punctual:Produs punct Y este o funcție liniară a tuturor caracteristicilor xi. Dacă modelul nu are caracteristici, predicția este egală cu părtinirea, b.

Greutățile indică direcția corelației dintre caracteristicile xi și eticheta y. O corelație pozitivă crește probabilitatea clasei pozitive, în timp ce o corelație negativă duce probabilitatea mai aproape de 0, (adică, clasa negativă).

Modelul liniar returnează numai un număr real, ceea ce este inconsecvent cu măsura de probabilitate a intervalului [0,1]. Funcția logistică este necesară pentru a converti rezultatul modelului liniar într-o probabilitate,

Funcția logistică

Funcția logistică, sau funcția sigmoidă, are o formă de S, iar rezultatul acestei funcții este întotdeauna între 0 și 1.

Exemplu de funcție logistică

Exemplu de funcție logistică
Exemplu de funcție logistică

Este ușor să înlocuiți rezultatul regresiei liniare în funcția sigmoidă. Rezultă un număr nou cu o probabilitate între 0 și 1.

Clasificatorul poate transforma probabilitatea într-o clasă

  • Valorile cuprinse între 0 și 0.49 devin clasa 0
  • Valorile cuprinse între 0.5 și 1 devin clasa 1

Cum se măsoară performanța Clasificatorului liniar?

Acuratete

Performanța generală a unui clasificator este măsurată cu metrica de precizie. Precizia colectează toate valorile corecte împărțite la numărul total de observații. De exemplu, o valoare a preciziei de 80% înseamnă că modelul este corect în 80% din cazuri.

Metrica de precizie
Măsurați performanța Clasificatorului liniar folosind metrica de precizie

Puteți observa o deficiență cu această măsurătoare, în special pentru clasa de dezechilibru. Un set de date de dezechilibru apare atunci când numărul de observații per grup nu este egal. Să zicem; încercați să clasificați un eveniment rar cu o funcție logistică. Imaginați-vă că clasificatorul încearcă să estimeze decesul unui pacient în urma unei boli. În date, 5 la sută dintre pacienți decedează. Puteți antrena un clasificator pentru a prezice numărul de decese și puteți utiliza metrica de precizie pentru a evalua performanțele. Dacă clasificatorul prezice 0 moarte pentru întregul set de date, va fi corect în 95% din cazuri.

Matricea confuziei

O modalitate mai bună de a evalua performanța unui clasificator este să te uiți la matricea de confuzie.

Matricea confuziei
Măsurați performanța Clasificatorului liniar folosind matricea de confuzie

matrice de confuzie vizualizează acuratețea unui clasificator comparând clasele reale și cele prezise, ​​așa cum se arată în exemplul de clasificator liniar de mai sus. Matricea de confuzie binară este compusă din pătrate:

  • TP: Adevărat pozitiv: Valorile estimate prezise corect ca fiind pozitive efective
  • FP: Valorile estimate au prezis incorect un pozitiv real. adică, valorile negative prezise ca pozitive
  • FN: Fals Negativ: Valori pozitive prezise ca negative
  • TN: True Negative: Valorile estimate prezise corect ca fiind negative reale

Din matricea de confuzie, este ușor de comparat clasa reală și clasa prezisă.

Precizie și sensibilitate

Matricea de confuzie oferă o bună perspectivă asupra adevăratului pozitiv și fals pozitiv. În unele cazuri, este de preferat să aveți o măsură mai concisă.

Precizie

Metrica de precizie arată acuratețea clasei pozitive. Măsoară cât de probabilă este corectă predicția clasei pozitive.

Precizie

Scorul maxim este 1 atunci când clasificatorul clasifică perfect toate valorile pozitive. Numai precizia nu este de mare ajutor deoarece ignoră clasa negativă. Valoarea este de obicei asociată cu valoarea Recall. Reamintirea se mai numește și sensibilitate sau adevărată rată pozitivă.

Sensibilitate

Sensibilitatea calculează raportul dintre clasele pozitive detectate corect. Această măsurătoare arată cât de bun este modelul pentru a recunoaște o clasă pozitivă.

Sensibilitate

Clasificator liniar cu TensorFlow

Pentru acest tutorial, vom folosi setul de date al recensământului. Scopul este de a utiliza variabilele din setul de date de recensământ pentru a prezice nivelul venitului. Rețineți că venitul este o variabilă binară

  • cu valoarea 1 dacă venitul > 50k
  • 0 dacă venitul < 50k.

Această variabilă este eticheta dvs

Acest set de date include opt variabile categoriale:

  • la locul de muncă
  • educaţie
  • marital
  • ocupație
  • relaţie
  • rasă
  • sex
  • tara de origine

în plus, șase variabile continue:

  • vârstă
  • fnlwgt
  • educație_num
  • câștig de capital
  • pierdere_capital
  • ore_săptămână

Prin acest exemplu de Clasificare TensorFlow, veți înțelege cum să antrenați clasificatori liniari TensorFlow cu estimatorul TensorFlow și cum să îmbunătățiți metrica de precizie.

Vom proceda astfel:

  • Pasul 1) Importați datele
  • Pasul 2) Conversia datelor
  • Pasul 3) Antrenează clasificatorul
  • Pasul 4) Îmbunătățiți modelul
  • Pasul 5) Hiperparametru: Lasso & Ridge

Pasul 1) Importați datele

Mai întâi importați bibliotecile utilizate în timpul tutorialului.

import tensorflow as tf
import pandas as pd

Apoi, importați datele din arhiva UCI și definiți numele coloanelor. Veți folosi COLUMNS pentru a denumi coloanele într-un cadru de date panda.

Rețineți că veți antrena clasificatorul folosind un cadru de date 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"

Datele stocate online sunt deja împărțite între un set de tren și un set de testare.

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)

Setul de tren conține 32,561 de observații, iar setul de testare 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 necesită o valoare booleană pentru a antrena clasificatorul. Trebuie să transformați valorile din șir în număr întreg. Eticheta este stocată ca obiect, totuși, trebuie să o convertiți într-o valoare numerică. Codul de mai jos creează un dicționar cu valorile de convertit și buclă peste elementul din coloană. Rețineți că efectuați această operație de două ori, una pentru testul trenului, una pentru setul de testare

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]

În datele trenului, există 24,720 de venituri mai mici de 50k și 7841 mai sus. Raportul este aproape același pentru setul de testare. Vă rugăm să consultați acest tutorial despre Fațete pentru mai multe.

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

Pasul 2) Conversia datelor

Sunt necesari câțiva pași înainte de a antrena un clasificator liniar cu Tensorflow. Trebuie să pregătiți caracteristicile pentru a le include în model. În regresia de referință, veți folosi datele originale fără a aplica nicio transformare.

Estimatorul trebuie să aibă o listă de caracteristici pentru a antrena modelul. Prin urmare, datele coloanei trebuie convertite într-un tensor.

O bună practică este să definiți două liste de caracteristici pe baza tipului lor și apoi să le treceți în feature_columns ale estimatorului.

Veți începe prin a converti caracteristicile continue, apoi veți defini o găleată cu datele categorice.

Caracteristicile setului de date au două formate:

  • Întreg
  • Obiect

Fiecare caracteristică este listată în următoarele două variabile în funcție de tipurile lor.

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

Feature_column este echipat cu un obiect numeric_column pentru a ajuta la transformarea variabilelor continue în tensor. În codul de mai jos, convertiți toate variabilele din CONTI_FEATURES într-un tensor cu o valoare numerică. Acest lucru este obligatoriu pentru a construi modelul. Toate variabilele independente trebuie convertite în tipul adecvat de tensor.

Mai jos scriem un cod pentru a vă permite să vedeți ce se întâmplă în spatele feature_column.numeric_column. Vom imprima valoarea convertită pentru vârstă. Este cu scop explicativ, prin urmare nu este nevoie să înțelegem codul python. Puteți consulta documentația oficială pentru a înțelege codurile.

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.]]

Valorile sunt exact aceleași ca în df_train

continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]

Conform documentației TensorFlow, există diferite moduri de a converti datele categorice. Dacă lista de vocabular a unei caracteristici este cunoscută și nu are o mulțime de valori, este posibil să se creeze coloana categorică cu categorical_column_with_vocabulary_list. Va atribui tuturor listei de vocabular unic un ID.

De exemplu, dacă o stare variabilă are trei valori distincte:

  • soţul
  • Soție
  • Singur

Apoi vor fi atribuite trei ID-uri. De exemplu, soțul va avea ID 1, soția ID-ul 2 și așa mai departe.

În scop ilustrativ, puteți utiliza acest cod pentru a converti o variabilă obiect într-o coloană categorială în TensorFlow.

Caracteristica sex nu poate avea decât două valori: masculin sau feminin. Când vom converti caracteristica sex, Tensorflow va crea 2 coloane noi, una pentru bărbați și una pentru femei. Dacă sexul este egal cu bărbatul, atunci noua coloană masculină va fi egală cu 1 și femeia cu 0. Acest exemplu este afișat în tabelul de mai jos:

rânduri sex după transformare masculin Femeie
1 masculin => 1 0
2 masculin => 1 0
3 Femeie => 0 1

În flux tensor:

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

Mai jos, am adăugat Python cod pentru a imprima codificarea. Din nou, nu trebuie să înțelegeți codul, scopul este să vedeți transformarea

Cu toate acestea, o modalitate mai rapidă de a transforma datele este utilizarea metodei categorical_column_with_hash_bucket. Modificarea variabilelor șir într-o matrice rară va fi utilă. O matrice rară este o matrice cu cea mai mare parte zero. Metoda are grijă de tot. Trebuie doar să specificați numărul de găleți și coloana cheie. Numărul de găleți este cantitatea maximă de grupuri pe care Tensorflow le poate crea. Coloana cheie este pur și simplu numele coloanei de convertit.

În codul de mai jos, creați o buclă peste toate caracteristicile categoriale.

categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]

Pasul 3) Antrenează clasificatorul

TensorFlow oferă în prezent un estimator pentru regresia liniară și clasificarea liniară.

  • Regresie liniară: LinearRegressor
  • Clasificare liniară: LinearClassifier

Sintaxa clasificatorului liniar este aceeași ca în tutorialul despre regresie liniara cu excepția unui argument, n_class. Trebuie să definiți coloana de caracteristici, directorul modelului și să comparați cu regresorul liniar; ai definit numărul de clasă. Pentru o regresie logit, numărul clasei este egal cu 2.

Modelul va calcula greutățile coloanelor conținute în continuous_features și categorical_features.

model = tf.estimator.LinearClassifier(
    n_classes = 2,
    model_dir="ongoing/train", 
    feature_columns=categorical_features+ continuous_features)

producție

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}

Acum că clasificatorul este definit, puteți crea funcția de intrare. Metoda este aceeași ca în tutorialul regresor liniar. Aici, utilizați o dimensiune de lot de 128 și amestecați datele.

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)

Creați o funcție cu argumentele cerute de estimatorul liniar, adică numărul de epoci, numărul de loturi și amestecați setul de date sau nota. Din moment ce utilizați ursi panda pentru a trece datele în model, trebuie să definiți variabilele X ca un cadru de date panda. Rețineți că treceți peste toate datele stocate în FEATURES.

Să antrenăm modelul cu modelul obiect.tren. Utilizați funcția definită anterior pentru a alimenta modelul cu valorile corespunzătoare. Rețineți că setați dimensiunea lotului la 128 și numărul de epoci la Niciunul. Modelul va fi antrenat pe o mie de pași.

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>

Rețineți că pierderea a scăzut ulterior în ultimii 100 de pași, adică de la 901 la 1000.

Pierderea finală după o mie de iterații este de 5444. Puteți estima modelul dvs. pe setul de testare și puteți vedea performanța. Pentru a evalua performanța modelului dvs., trebuie să utilizați evaluarea obiectului. Alimentați modelul cu setul de testare și setați numărul de epoci la 1, adică datele vor merge la model o singură dată.

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 returnează toate valorile pe care le-ați învățat în partea teoretică. Fără surpriză, precizia este mare datorită etichetei dezechilibrate. De fapt, modelul funcționează puțin mai bine decât o presupunere aleatorie. Imaginați-vă că modelul prezice toate gospodăriile cu venituri mai mici de 50K, apoi modelul are o precizie de 70%. La o analiză mai atentă, puteți vedea că predicția și amintirea sunt destul de scăzute.

Pasul 4) Îmbunătățiți modelul

Acum că aveți un model de referință, puteți încerca să-l îmbunătățiți, adică să creșteți acuratețea. În tutorialul anterior, ați învățat cum să îmbunătățiți puterea de predicție cu un termen de interacțiune. În acest tutorial, veți revizui această idee adăugând un termen polinom la regresie.

Regresia polinomială este instrumentală atunci când există neliniaritate în date. Există două moduri de a capta neliniaritatea datelor.

  • Adăugați termenul polinom
  • Distribuiți variabila continuă într-o variabilă categorială

Termen polinom

Din imaginea de mai jos, puteți vedea ce este o regresie polinomială. Este o ecuație cu X variabile cu putere diferită. O regresie polinomială de gradul doi are două variabile, X și X pătrat. Gradul al treilea are trei variabile, X, X2, și X3

Regresia polinomială
Ce este regresia polinomială

Mai jos, am construit un grafic cu două variabile, X și Y. Este evident că relația nu este liniară. Dacă adăugăm o regresie liniară, putem vedea că modelul nu poate captura modelul (imaginea din stânga).

Acum, uitați-vă la imaginea din stânga din imaginea de mai jos, am adăugat cinci termeni la regresie (adică y=x+x2+x3+x4+x5. Modelul surprinde acum mult mai bine modelul. Aceasta este puterea regresiei polinomiale.

Regresia polinomială

Să revenim la exemplul nostru. Vârsta nu este într-o relație liniară cu venitul. Vârstele fragede ar putea avea un venit fix aproape de zero, deoarece copiii sau tinerii nu lucrează. Apoi crește vârsta de muncă și scade în timpul pensionării. Este de obicei o formă de U inversat. O modalitate de a captura acest model este prin adăugarea unei puteri două la regresie.

Să vedem dacă mărește precizia.

Trebuie să adăugați această nouă caracteristică la setul de date și în lista de caracteristici continue.

Adăugați noua variabilă în setul de date tren și testare, deci este mai convenabil să scrieți o funcție.

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

Funcția are 3 argumente:

  • df_t: definiți setul de antrenament
  • df_te: definiți setul de testare
  • var_name = „vârstă”: definiți variabila de transformat

Puteți folosi obiectul pow(2) pentru a pătra vârsta variabilă. Rețineți că noua variabilă se numește „nouă”

Acum că funcția square_var este scrisă, puteți crea noile seturi de date.

df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')

După cum puteți vedea, noul set de date are încă o caracteristică.

print(df_train_new.shape, df_test_new.shape)			
(32561, 16) (16281, 16)

Variabila pătrată este numită nouă în setul de date. Trebuie să-l adăugați la lista de funcții 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]

notițe că ai schimbat directorul Graph-ului. Nu puteți antrena modele diferite în același director. Înseamnă că trebuie să schimbați calea argumentului model_dir. Dacă nu, TensorFlow va arăta o eroare.

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)

Acum că clasificatorul este proiectat cu noul set de date, puteți antrena și evalua modelul.

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}

Variabila pătrat a îmbunătățit precizia de la 0.76 la 0.79. Să vedem dacă vă puteți descurca mai bine combinând împreună termenul de grupare și interacțiune.

Bucketization și interacțiune

După cum ați văzut mai devreme, un clasificator liniar nu poate surprinde corect modelul de vârstă-venit. Asta pentru că învață o singură greutate pentru fiecare caracteristică. Pentru a facilita clasificatorul, un lucru pe care îl puteți face este să găzduiți funcția. Bucketing-ul transformă o caracteristică numerică în câteva anumite în funcție de intervalul în care se încadrează și fiecare dintre aceste caracteristici noi indică dacă vârsta unei persoane se încadrează în acel interval.

Cu aceste noi caracteristici, modelul liniar poate surprinde relația prin învățarea de greutăți diferite pentru fiecare găleată.

În TensorFlow, se face cu bucketized_column. Trebuie să adăugați intervalul de valori în limite.

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

Știi deja că vârsta este neliniară cu venitul. O altă modalitate de a îmbunătăți modelul este prin interacțiune. În cuvântul TensorFlow, este încrucișarea caracteristicilor. Încrucișarea caracteristicilor este o modalitate de a crea noi caracteristici care sunt combinații ale celor existente, care poate fi utilă pentru un clasificator liniar care nu poate modela interacțiunile dintre caracteristici.

Puteți descompune vârsta cu o altă caracteristică, cum ar fi educația. Adică, unele grupuri sunt probabil să aibă un venit mare, iar altele scăzute (Gândește-te la doctorand).

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

Pentru a crea o coloană cu caracteristici încrucișate, utilizați crossed_column cu variabilele de încrucișat între paranteze. Hash_bucket_size indică posibilitățile maxime de trecere. Pentru a crea interacțiune între variabile (cel puțin o variabilă trebuie să fie categorică), puteți utiliza tf.feature_column.crossed_column. Pentru a utiliza acest obiect, trebuie să adăugați între paranteze pătrate variabila pentru a interacționa și un al doilea argument, dimensiunea găleții. Mărimea găleții este numărul maxim de grup posibil într-o variabilă. Aici îl setați la 1000 deoarece nu știți numărul exact de grupuri

age_buckets trebuie să fie pătrat înainte de a-l adăuga la coloanele de caracteristici. De asemenea, adăugați noile caracteristici la coloanele de caracteristici și pregătiți estimatorul

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)

producție

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)

Sunteți gata să estimați noul model și să vedeți dacă îmbunătățește precizia.

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}

Noul nivel de precizie este de 83.58 la sută. Este cu patru procente mai mare decât modelul anterior.

În cele din urmă, puteți adăuga un termen de regularizare pentru a preveni supraadaptarea.

Pasul 5) Hiperparametru: Lasso & Ridge

Modelul tău poate suferi supraîncadrarea or sub-amenajare.

  • Supraadaptare: modelul nu poate generaliza predicția la date noi
  • Underfitting: modelul nu poate capta modelul datelor. adică regresia liniară când datele sunt neliniare

Atunci când un model are o mulțime de parametri și o cantitate relativ mică de date, duce la predicții slabe. Imaginați-vă, un grup are doar trei observații; modelul va calcula o pondere pentru acest grup. Greutatea este folosită pentru a face o predicție; dacă observațiile setului de testare pentru acest grup particular sunt complet diferite de setul de antrenament, atunci modelul va face o predicție greșită. În timpul evaluării cu setul de antrenament, precizia este bună, dar nu bună cu setul de test deoarece ponderile calculate nu sunt cele adevărate pentru a generaliza modelul. În acest caz, nu face o predicție rezonabilă asupra datelor nevăzute.

Pentru a preveni supraadaptarea, regularizarea vă oferă posibilitățile de a controla o astfel de complexitate și de a o face mai generalizabilă. Există două tehnici de regularizare:

  • L1: Lasso
  • L2: creasta

În TensorFlow, puteți adăuga acești doi hiperparametri în optimizator. De exemplu, cu cât hiperparametrul L2 este mai mare, greutatea tinde să fie foarte mică și aproape de zero. Linia ajustată va fi foarte plată, în timp ce un L2 aproape de zero implică că ponderile sunt apropiate de regresia liniară obișnuită.

Puteți încerca singur valoarea diferită a hiperparametrilor și puteți vedea dacă puteți crește nivelul de precizie.

notițe că dacă modificați hiperparametrul, trebuie să ștergeți folderul în curs/train4, altfel modelul va începe cu modelul antrenat anterior.

Să vedem cum este acuratețea cu 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))

IEȘIRE

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)

IEȘIRE

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)

producție

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}

Cu acest hiperparametru, creșteți ușor valorile de precizie. În următorul tutorial, veți învăța cum să îmbunătățiți un clasificator liniar folosind o metodă kernel.

Rezumat

Pentru a antrena un model, trebuie să:

  • Definiți caracteristicile: Variabile independente: X
  • Definiți eticheta: Variabilă dependentă: y
  • Construiți un tren/set de testare
  • Definiți greutatea inițială
  • Definiți funcția de pierdere: MSE
  • Optimizați modelul: Coborâre în gradient
  • Defini:
    • Rata de învățare
    • Numărul epocii
    • Dimensiunea lotului
    • Numărul clasei

În acest tutorial, ați învățat cum să utilizați API-ul de nivel înalt pentru un clasificator de regresie liniară. Trebuie să definiți:

  1. Coloane caracteristice. Dacă este continuă: tf.feature_column.numeric_column(). Puteți completa o listă cu înțelegerea listei Python
  2. Estimatorul: tf.estimator.LinearClassifier(feature_columns, model_dir, n_classes = 2)
  3. O funcție pentru a importa datele, dimensiunea lotului și epoca: input_fn()

După aceea, ești gata să antrenezi, să evaluezi și să faci o predicție cu train(), evaluate() și predict()

Pentru a îmbunătăți performanța modelului, puteți:

  • Utilizați regresia polinomială
  • Termen de interacțiune: tf.feature_column.crossed_column
  • Adăugați parametrul de regularizare