Cele mai frecvente două sarcini de învățare supravegheate sunt regresia liniară și clasificatorul liniar. Regresia liniară prezice o valoare în timp ce clasificatorul liniar prezice o clasă. Acest tutorial este axat pe Clasificator liniar.
Ce este clasificatorul liniar?
Un clasificator liniar în învățarea automată este o metodă pentru găsirea clasei unui obiect pe baza caracteristicilor sale pentru clasificarea statistică. Acesta ia decizii 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 vizează 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ă.
- Dacă eticheta are doar două clase, algoritmul de învățare este un clasificator binar.
- Clasificatorul Multiclass 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 cumpărare. Prezicerea tipului de animal afișat pe o imagine este o problemă de clasificare multiclass, deoarece există mai mult de două varietăți de animale existente.
Partea teoretică a acestui tutorial pune accentul principal pe clasa binară. Veți afla mai multe despre funcția de ieșire multiclass într-un viitor tutorial.
În acest tutorial, veți învăța
- Ce este clasificatorul liniar?
- Cum funcționează clasificatorul binar?
- Cum se măsoară performanța clasificatorului liniar?
- Precizie
- Matrice de confuzie
- Precizie și sensibilitate
- Clasificator liniar cu TensorFlow
- 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
Cum funcționează clasificatorul binar?
Ați aflat î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 sa prin minimizarea erorii pătrate 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 sau nu un produs. 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 cea mai probabilă clasă din care face parte, și anume, potențialul cumpărător sau nu.
Probabilitatea de succes este calculată cu regresie logistică . Algoritmul va calcula o probabilitate bazată pe caracteristica X și 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:
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 utilizând un produs punct: Y este o funcție liniară a tuturor caracteristicilor x i . Dacă modelul nu are caracteristici, predicția este egală cu părtinirea, b.
Greutățile indică direcția corelației dintre caracteristicile x i ș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ă doar numărul real, ceea ce este neconcordant cu măsura probabilității intervalului [0,1]. Funcția logistică este necesară pentru a converti ieșirea modelului liniar la o probabilitate,
Funcția logistică
Funcția logistică sau funcția sigmoidă are o formă S și ieșirea acestei funcții este întotdeauna între 0 și 1.
Este ușor să înlocuiți ieșirea 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?
Precizie
Performanța generală a unui clasificator este măsurată cu metrica de precizie. Acuratețea colectează toate valorile corecte împărțite la numărul total de observații. De exemplu, o valoare de precizie de 80% înseamnă că modelul este corect în 80% din cazuri.
Puteți observa un neajuns cu această valoare, în special pentru clasa de dezechilibru. Un set de date de dezechilibru apare atunci când numărul de observații pe grup nu este egal. Sa spunem; încercați să clasificați un eveniment rar cu o funcție logistică. Imaginați-vă că clasificatorul încearcă să estimeze moartea unui pacient în urma unei boli. În date, 5 la sută dintre pacienți decedează. Puteți instrui un clasificator pentru a prezice numărul decesului și puteți utiliza metrica de precizie pentru a evalua performanțele. Dacă clasificatorul prezice 0 deces pentru întregul set de date, acesta va fi corect în 95 la sută din cazuri.
Matrice de confuzie
O modalitate mai bună de a evalua performanța unui clasificator este de a privi matricea de confuzie.
Matricea 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 prezise corect prezise ca pozitive reale
- FP: Valorile prezise au prezis incorect un pozitiv real. adică, valorile negative prezise ca pozitive
- FN: fals negativ: valori pozitive prezise ca negative
- TN: Adevărat negativ: valorile prezise corect prezise ca negative reale
Din matricea confuziei, este ușor să comparați clasa reală și clasa prezisă.
Precizie și sensibilitate
Matricea de confuzie oferă o bună perspectivă asupra adevăratului pozitiv și a falsului pozitiv. În unele cazuri, este de preferat să aveți o metrică mai concisă.
Precizie
Metrica de precizie arată acuratețea clasei pozitive. Măsurează cât de probabil este corectă predicția clasei pozitive.
Scorul maxim este 1 atunci când clasificatorul clasifică perfect toate valorile pozitive. Precizia singură nu este foarte utilă, deoarece ignoră clasa negativă. Valoarea este de obicei asociată cu valoarea Recall. Revocarea se mai numește sensibilitate sau adevărată rată pozitivă.
Sensibilitate
Sensibilitatea calculează raportul dintre clasele pozitive detectate corect. Această valoare indică cât de bun este modelul pentru a recunoaște o clasă pozitivă.
Clasificator liniar cu TensorFlow
Pentru acest tutorial, vom folosi setul de date de recensământ. Scopul este de a utiliza variabilele din setul de date recensământ pentru a prezice nivelul veniturilor. Rețineți că venitul este o variabilă binară
- cu o valoare de 1 dacă venitul> 50k
- 0 dacă venit <50k.
Această variabilă este eticheta dvs.
Acest set de date include opt variabile categorice:
- la locul de muncă
- educaţie
- marital
- ocupaţie
- relaţie
- rasă
- sex
- tara de origine
în plus, șase variabile continue:
- vârstă
- fnlwgt
- număr_educare
- câștig de capital
- pierderea_capitalului
- ore_saptamana
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 după cum urmează:
- 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 tfimport pandas as pd
Apoi, importați datele din arhiva UCI și definiți numele coloanelor. Veți utiliza CULOANE pentru a denumi coloanele dintr-un cadru de date pandas.
Rețineți că veți antrena clasificatorul folosind un cadru de date 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"
Datele stocate online sunt deja împărțite între un set de trenuri și un set de teste.
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 trenuri 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 int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel objectdtype: object
Tensorflow necesită o valoare booleană pentru a antrena clasificatorul. Trebuie să aruncați valorile de la șir la întreg. Eticheta este stocată ca obiect, cu toate acestea, trebuie să o convertiți într-o valoare numerică. Codul de mai jos creează un dicționar cu valorile pe care trebuie să le convertiți și să faceți o buclă peste elementul coloanei. 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 venituri mai mici decât 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 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
Pasul 2) Conversia datelor
Câțiva pași sunt necesari înainte de a antrena un clasificator liniar cu Tensorflow. Trebuie să pregătiți caracteristicile pe care să le includeți în model. În regresia de referință, veți utiliza datele originale fără a aplica nicio transformare.
Estimatorul trebuie să aibă o listă de caracteristici pentru a instrui modelul. Prin urmare, datele coloanei necesită convertirea într-un tensor.
O bună practică este să definiți două liste de caracteristici în funcție de tipul lor și apoi să le transmiteți în coloanele caracteristice ale estimatorului.
Veți începe prin conversia caracteristicilor continue, apoi veți defini o bucket 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 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']
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 în 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 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.]]
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ă creați coloana categorică cu categorie_coloană_cu_vocabular_list. Acesta va atribui tuturor listelor de vocabular unic un ID.
De exemplu, dacă o stare variabilă are trei valori distincte:
- Soț
- Soție
- Singur
Apoi vor fi atribuite trei ID-uri. De exemplu, Soțul va avea ID-ul 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ă categorică din TensorFlow.
Caracteristica sexului poate avea doar 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 femeie. Dacă sexul este egal cu bărbatul, atunci noua coloană masculină va fi egală cu 1 și femeie 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 fluxul tensorului:
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 codul Python pentru a imprima codificarea. Din nou, nu este nevoie să înțelegeți codul, scopul este să vedeți transformarea
Cu toate acestea, o modalitate mai rapidă de transformare a datelor este utilizarea metodei categorical_column_with_hash_bucket. Modificarea variabilelor de șir într-o matrice rară va fi utilă. O matrice rară este o matrice cu cea mai mare parte zero. Metoda are grijă de toate. Trebuie doar să specificați numărul de găleți și coloana cheie. Numărul de cupe 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 categorice.
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 privind regresia liniară, cu excepția unui argument, n_class. Trebuie să definiți coloana de caracteristici, directorul modelului și să comparați cu regresorul liniar; trebuie să definiți numărul clasei. Pentru o regresie logit, numărul clasei este egal cu 2.
Modelul va calcula greutățile coloanelor conținute în caracteristici_ continue și caracteristici_categorice.
model = tf.estimator.LinearClassifier(n_classes = 2,model_dir="ongoing/train",feature_columns=categorical_features+ continuous_features)
IEȘIRE:
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}
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 a lotului 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. Deoarece utilizați metoda Pandas pentru a transmite datele în model, trebuie să definiți variabilele X ca un cadru de date pandas. Rețineți că parcurgeți toate datele stocate în CARACTERISTICI.
Să antrenăm modelul cu obiectul model.train. 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 Niciuna. Modelul va fi instruit 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 = 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.
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 obiectul de evaluare. 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: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 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 rechemarea 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 precizia. Î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 revizita această idee adăugând un termen polinomial la regresie.
Regresia polinomială este instrumentală atunci când există neliniaritate în date. Există două moduri de a capta non-liniaritatea în date.
- Adăugați termen polinomial
- Bucketize variabila continuă într-o variabilă categorică
Termen polinomial
Din imaginea de mai jos, puteți vedea ce este o regresie polinomială. Este o ecuație cu variabile X cu putere diferită. O regresie polinomială de gradul doi are două variabile, X și X pătrat. Gradul al treilea are trei variabile, X, X 2 și X 3
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 regimuri la regresie (adică y = x + x 2 + x 3 + x 4 + x 5. Modelul captează acum mult mai bine modelul. Acesta este puterea regresiei polinomiale.
Să ne întoarcem la exemplul nostru. Vârsta nu se află într-o relație liniară cu venitul. Vârsta timpurie ar putea avea un venit fix aproape de zero, deoarece copiii sau tinerii nu muncesc. Apoi crește în vârstă de muncă și scade în timpul pensionării. Este de obicei o formă inversată-U. O modalitate de a captura acest tipar este prin adăugarea unei puteri două la regresie.
Să vedem dacă crește precizia.
Trebuie să adăugați această nouă caracteristică la setul de date și în lista caracteristicilor continue.
Adăugați noua variabilă în setul de date tren și test, astfel încât 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 utiliza obiectul pow (2) pentru a păstra 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 caracteristici 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]
Rețineți că ați schimbat directorul Graficului. Nu puteți antrena modele diferite în același director. Înseamnă că trebuie să schimbați calea argumentului model_dir. Dacă nu faceți acest lucru, TensorFlow va arunca 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':, '_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 = 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}
Variabila pătrată a îmbunătățit precizia de la 0,76 la 0,79. Să vedem dacă puteți face mai bine combinând bucketizarea și termenul de interacțiune împreună.
Bucketizarea și interacțiunea
După cum ați văzut mai înainte, un clasificator liniar nu este capabil să capteze corect modelul vârstă-venit. Asta pentru că învață o singură greutate pentru fiecare caracteristică. Pentru a face mai ușor clasificatorul, un lucru pe care îl puteți face este să opriți caracteristica. Bucketing transformă o caracteristică numerică în mai multe caracteristici, în funcție de intervalul în care se încadrează și fiecare dintre aceste caracteristici noi indică dacă vârsta unei persoane se încadrează în intervalul respectiv.
Cu aceste noi caracteristici, modelul liniar poate surprinde relația învățând diferite greutăți pentru fiecare cupă.
În TensorFlow, se face cu bucketized_column. Trebuie să adăugați gama 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])
Știți 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 trecerea caracteristicilor. Trecerea caracteristicilor este o modalitate de a crea funcții noi care sunt combinații ale celor existente, care pot fi utile 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ă, este posibil ca unele grupuri să aibă venituri mari și altele scăzute (Gândiți-vă 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 coloana_crucișată cu variabilele de încrucișat într-o paranteză. Hash_bucket_size indică posibilitățile maxime de traversare. 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 în paranteză pătrată variabila pentru a interacționa și un al doilea argument, dimensiunea cupei. Dimensiunea cupei 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 funcții 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)
IEȘIRE
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)
Sunteți gata să estimați noul model și să vedeți dacă acesta î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 = 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}
Noul nivel de precizie este de 83,58%. 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 dvs. poate suferi de overfitting sau underfitting .
- Suprapunere: modelul nu este în măsură să generalizeze predicția asupra noilor date
- Sub-montare: modelul nu poate capta modelul datelor. adică regresie liniară atunci când datele sunt neliniare
Când un model are o mulțime de parametri și o cantitate relativ mică de date, acesta conduce la predicții slabe. Imaginați-vă, un singur grup are doar trei observații; modelul va calcula o pondere pentru acest grup. Greutatea este utilizată 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, acuratețea este bună, dar nu este bună cu setul de testare, deoarece greutățile calculate nu sunt 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ă posibilitatea de a controla o astfel de complexitate și de a o face mai generalizabilă. Există două tehnici de regularizare:
- L1: Lasso
- L2: Ridge
În TensorFlow, puteți adăuga acești doi hiperparametri în optimizator. De exemplu, cu cât este mai mare hiperparametrul L2, greutatea tinde să fie foarte mică și aproape de zero. Linia montată va fi foarte plană, în timp ce un L2 aproape de zero implică greutățile apropiate de regresia liniară regulată.
Puteți încerca singur diferitele valori ale hiperparametrelor și puteți vedea dacă puteți crește nivelul de precizie.
Rețineți că, dacă schimbați hiperparametrul, trebuie să ștergeți folderul în curs / train4, altfel modelul va începe cu modelul instruit anterior.
Să vedem cum este precizia 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))
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)
IEȘIRE
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}
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ă de nucleu.
rezumat
Pentru a instrui 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:
- Coloane cu caracteristici. Dacă este continuu: tf.feature_column.numeric_column (). Puteți completa o listă cu înțelegerea listei python
- Estimatorul: tf.estimator.LinearClassifier (feature_columns, model_dir, n_classes = 2)
- O funcție pentru importul datelor, dimensiunea lotului și epoca: input_fn ()
După aceea, sunteți gata să vă antrenați, să evaluați și să faceți o predicție cu train (), evaluate () și predict ()
Pentru a îmbunătăți performanța modelului, puteți:
- Folosiți regresia polinomială
- Termen de interacțiune: tf.feature_column.crossed_column
- Adăugați un parametru de regularizare