TensorFlow binarna klasifikacija: primjer linearnog klasifikatora

Dvije najčešće nadzirano učenje zadaci su linearna regresija i linearni klasifikator. Linearna regresija predviđa vrijednost dok linearni klasifikator predviđa klasu. Ovaj vodič usmjeren je na linearne klasifikatore.

Što je linearni klasifikator?

A Linearni klasifikator u strojnom učenju je metoda za pronalaženje klase objekta na temelju njegovih karakteristika za statističku klasifikaciju. Donosi odluku o klasifikaciji na temelju vrijednosti linearne kombinacije karakteristika objekta. Linearni klasifikator koristi se u praktičnim problemima poput klasifikacije dokumenata i problema s mnogo varijabli.

Problemi s klasifikacijom predstavljaju otprilike 80 posto zadatka strojnog učenja. Klasifikacija ima za cilj predviđanje vjerojatnosti svake klase s obzirom na skup inputa. Oznaka (tj. zavisna varijabla) je diskretna vrijednost, koja se naziva klasa.

  1. Ako oznaka ima samo dvije klase, algoritam učenja je binarni klasifikator.
  2. Multiclass klasifikator bavi se oznakama s više od dvije klase.

Na primjer, tipičan problem binarne klasifikacije je predviđanje vjerojatnosti da kupac obavi drugu kupnju. Predviđanje vrste životinje prikazane na slici problem je višeklasne klasifikacije budući da postoji više od dvije vrste životinja.

Teorijski dio ovog vodiča stavlja primarni fokus na binarnu klasu. Naučit ćete više o funkciji višeklasnog izlaza u budućem vodiču.

Kako radi binarni klasifikator?

U prethodnom ste vodiču naučili da je funkcija sastavljena od dvije vrste varijabli, zavisne varijable i skupa značajki (nezavisne varijable). U linearnoj regresiji, zavisna varijabla je realan broj bez raspona. Primarni cilj je predvidjeti njegovu vrijednost minimiziranjem srednje kvadratne pogreške.

Za TensorFlow binarni klasifikator, oznaka je mogla imati dvije moguće vrijednosti cijelog broja. U većini slučajeva, to je [0,1] ili [1,2]. Na primjer, cilj je predvidjeti hoće li kupac kupiti proizvod ili ne. Oznaka je definirana na sljedeći način:

  • Y = 1 (kupac je kupio proizvod)
  • Y = 0 (kupac ne kupuje proizvod)

Model koristi značajke X za klasificiranje svakog kupca u najvjerojatniji razred kojem pripada, odnosno, potencijalni kupac ili ne.

Vjerojatnost uspjeha izračunava se s logistička regresija. Algoritam će izračunati vjerojatnost na temelju svojstva X i predviđa uspjeh kada je ta vjerojatnost iznad 50 posto. Formalnije, vjerojatnost se izračunava kao što je prikazano u donjem primjeru TensorFlow binarne klasifikacije:

Primjer binarne klasifikacije

gdje je 0 skup težina, značajki, a b pristranost.

Funkcija se može rastaviti na dva dijela:

  • Linearni model
  • Logistička funkcija

Linearni model

Već ste upoznati s načinom na koji se izračunavaju težine. Težine se izračunavaju pomoću točkastog produkta:Točkasti proizvod Y je linearna funkcija svih svojstava xi. Ako model nema značajke, predviđanje je jednako pristranosti, b.

Ponderi pokazuju smjer korelacije između značajki xi i oznaka y. Pozitivna korelacija povećava vjerojatnost pozitivne klase dok negativna korelacija vodi vjerojatnost bliže 0 (tj. negativnoj klasi).

Linearni model vraća samo realni broj, koji nije u skladu s mjerom vjerojatnosti raspona [0,1]. Logistička funkcija je potrebna za pretvaranje izlaza linearnog modela u vjerojatnost,

Logistička funkcija

Logistička funkcija ili sigmoidna funkcija ima oblik slova S, a izlaz ove funkcije je uvijek između 0 i 1.

Primjer logističke funkcije

Primjer logističke funkcije
Primjer logističke funkcije

Lako je zamijeniti izlaz linearne regresije u sigmoidnu funkciju. Rezultat je novi broj s vjerojatnošću između 0 i 1.

Klasifikator može transformirati vjerojatnost u klasu

  • Vrijednosti između 0 i 0.49 postaju klasa 0
  • Vrijednosti između 0.5 i 1 postaju klasa 1

Kako izmjeriti izvedbu linearnog klasifikatora?

Točnost

Ukupna izvedba klasifikatora mjeri se metrikom točnosti. Točnost prikuplja sve točne vrijednosti podijeljene s ukupnim brojem opažanja. Na primjer, vrijednost točnosti od 80 posto znači da je model točan u 80 posto slučajeva.

metrika točnosti
Izmjerite izvedbu Linearnog klasifikatora pomoću metrike točnosti

Možete primijetiti nedostatak ove metrike, posebno za klasu neravnoteže. Skup podataka o neravnoteži javlja se kada broj opažanja po skupini nije jednak. Recimo; pokušavate klasificirati rijedak događaj s logističkom funkcijom. Zamislite da klasifikator pokušava procijeniti smrt pacijenta nakon bolesti. Prema podacima, 5 posto pacijenata premine. Možete uvježbati klasifikator da predvidi broj smrti i koristite metriku točnosti za procjenu performansi. Ako klasifikator predviđa 0 smrti za cijeli skup podataka, to će biti točno u 95 posto slučajeva.

Matrica zabune

Bolji način za procjenu učinka klasifikatora je pogled na matricu zabune.

Matrica zabune
Izmjerite izvedbu Linearnog klasifikatora pomoću matrice zabune

Korištenje električnih romobila ističe matrica zabune vizualizira točnost klasifikatora uspoređujući stvarne i predviđene klase kao što je prikazano u gornjem primjeru linearnog klasifikatora. Binarna matrica zabune sastoji se od kvadrata:

  • TP: True Positive: Predviđene vrijednosti točno predviđene kao stvarne pozitivne
  • FP: Predviđene vrijednosti netočno su predvidjele stvarni pozitivan. tj. Negativne vrijednosti predviđene kao pozitivne
  • FN: Lažno negativno: Pozitivne vrijednosti predviđene kao negativne
  • TN: Istinski negativan: Predviđene vrijednosti točno predviđene kao stvarni negativni

Iz matrice zabune lako je usporediti stvarnu klasu i predviđenu klasu.

Preciznost i osjetljivost

Matrica zabune pruža dobar uvid u pravu pozitivu i lažno pozitivu. U nekim slučajevima, poželjno je imati sažetiju metriku.

Preciznost

Metrika preciznosti pokazuje točnost pozitivne klase. Mjeri koliko je vjerojatno da je predviđanje pozitivne klase točno.

Preciznost

Maksimalna ocjena je 1 kada klasifikator savršeno klasificira sve pozitivne vrijednosti. Sama preciznost nije od velike pomoći jer zanemaruje negativnu klasu. Metrika je obično uparena s metrikom opoziva. Prisjećanje se također naziva osjetljivost ili prava pozitivna stopa.

Osjetljivost

Osjetljivost izračunava omjer pravilno detektiranih pozitivnih klasa. Ova metrika pokazuje koliko je model dobar za prepoznavanje pozitivne klase.

Osjetljivost

Linearni klasifikator s TensorFlowom

Za ovaj vodič koristit ćemo skup podataka popisa stanovništva. Svrha je koristiti varijable u skupu podataka popisa za predviđanje razine prihoda. Imajte na umu da je prihod binarna varijabla

  • s vrijednošću 1 ako je prihod > 50k
  • 0 ako je prihod < 50k.

Ova varijabla je vaša oznaka

Ovaj skup podataka uključuje osam kategoričkih varijabli:

  • na radnom mjestu
  • obrazovanje
  • bračni
  • okupacija
  • odnos
  • utrka
  • seks
  • rodna_zemlja

osim toga, šest kontinuiranih varijabli:

  • starost
  • fnlwgt
  • obrazovanje_br
  • kapitalni dobitak
  • gubitak_kapitala
  • sati_tjedan

Kroz ovaj primjer TensorFlow klasifikacije razumjet ćete kako trenirati linearne TensorFlow klasifikatore s TensorFlow estimatorom i kako poboljšati metriku točnosti.

Postupit ćemo na sljedeći način:

  • Korak 1) Uvezite podatke
  • Korak 2) Pretvorba podataka
  • Korak 3) Obučite klasifikatora
  • Korak 4) Poboljšajte model
  • Korak 5) Hiperparametar: laso i greben

Korak 1) Uvezite podatke

Prvo uvozite biblioteke korištene tijekom poduke.

import tensorflow as tf
import pandas as pd

Zatim uvozite podatke iz arhive UCI-ja i definirate nazive stupaca. Koristit ćete COLUMNS za imenovanje stupaca u pandas podatkovnom okviru.

Imajte na umu da ćete obučiti klasifikator koristeći Pandas podatkovni okvir.

## 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"

Podaci pohranjeni online već su podijeljeni između skupa vlakova i skupa za testiranje.

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)

Skup vlakova sadrži 32,561 16,281 opažanja, a testni skup XNUMX XNUMX

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 zahtijeva Booleovu vrijednost za obuku klasifikatora. Morate pretvoriti vrijednosti iz niza u cijeli broj. Oznaka se pohranjuje kao objekt, međutim, trebate je pretvoriti u numeričku vrijednost. Kod u nastavku stvara rječnik s vrijednostima za pretvaranje i prelazi preko stavke stupca. Imajte na umu da ovu operaciju izvodite dva puta, jednu za test vlaka, jednu za skup testova

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]

U podacima vlaka ima 24,720 prihoda nižih od 50k i 7841 iznad. Omjer je gotovo isti za test set. Za više pogledajte ovaj vodič o aspektima.

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

Korak 2) Pretvorba podataka

Potrebno je nekoliko koraka prije nego što uvježbate linearni klasifikator s Tensorflowom. Morate pripremiti značajke koje ćete uključiti u model. U regresiji referentne vrijednosti koristit ćete izvorne podatke bez primjene bilo kakve transformacije.

Procjenitelj mora imati popis značajki za obuku modela. Stoga se podaci stupca moraju pretvoriti u tenzor.

Dobra praksa je definirati dva popisa značajki na temelju njihove vrste i zatim ih proslijediti u feature_columns estimatora.

Počet ćete pretvaranjem kontinuiranih značajki, zatim definirati kantu s kategoričkim podacima.

Značajke skupa podataka imaju dva formata:

  • Integer
  • Objekt

Svaka značajka navedena je u sljedeće dvije varijable prema njihovoj vrsti.

## 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 opremljen je objektom numeric_column koji pomaže u transformaciji kontinuiranih varijabli u tenzor. U donjem kodu pretvarate sve varijable iz CONTI_FEATURES u tenzor s numeričkom vrijednošću. Ovo je obavezno za konstruiranje modela. Sve nezavisne varijable treba pretvoriti u odgovarajući tip tenzora.

U nastavku pišemo kod da biste vidjeli što se događa iza feature_column.numeric_column. Ispisat ćemo pretvorenu vrijednost za dob. To je u svrhu objašnjenja, stoga nema potrebe za razumijevanjem python koda. Možete pogledati službenu dokumentaciju da biste razumjeli kodove.

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

Vrijednosti su potpuno iste kao u df_train

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

Prema TensorFlow dokumentaciji, postoje različiti načini pretvaranja kategoričkih podataka. Ako je popis rječnika značajke poznat i nema mnogo vrijednosti, moguće je stvoriti kategorički stupac s categorical_column_with_vocabulary_list. Dodijelit će ID svim jedinstvenim popisima vokabulara.

Na primjer, ako status varijable ima tri različite vrijednosti:

  • Suprug
  • Žena
  • jedan

Tada će se pripisati tri ID-a. Na primjer, muž će imati ID 1, žena ID 2 i tako dalje.

U svrhu ilustracije, možete koristiti ovaj kod za pretvaranje varijable objekta u kategorički stupac u TensorFlowu.

Obilježje spola može imati samo dvije vrijednosti: muško ili žensko. Kada ćemo pretvoriti značajku spola, Tensorflow će stvoriti 2 nova stupca, jedan za muškarce i jedan za žene. Ako je spol jednak muškom, tada će novi stupac muški biti jednak 1, a ženski 0. Ovaj primjer prikazan je u donjoj tablici:

redaka seks nakon transformacije muški žena
1 muški => 1 0
2 muški => 1 0
3 žena => 0 1

U tenzorskom toku:

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

U nastavku smo dodali Python kod za ispis kodiranja. Opet, ne morate razumjeti kod, svrha je vidjeti transformaciju

Međutim, brži način transformacije podataka je korištenje metode categorical_column_with_hash_bucket. Promjena varijabli niza u rijetkoj matrici bit će korisna. Rijetka matrica je matrica s većinom nula. Metoda se brine za sve. Trebate samo navesti broj spremnika i ključni stupac. Broj spremnika maksimalan je broj grupa koje Tensorflow može stvoriti. Ključni stupac jednostavno je naziv stupca koji treba pretvoriti.

U donjem kodu stvarate petlju preko svih kategoričkih značajki.

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

Korak 3) Obučite klasifikator

TensorFlow trenutno pruža estimator za linearnu regresiju i linearnu klasifikaciju.

  • Linearna regresija: LinearRegressor
  • Linearna klasifikacija: LinearClassifier

Sintaksa linearnog klasifikatora je ista kao u vodiču o Linearna regresija osim jednog argumenta, n_class. Morate definirati stupac značajki, direktorij modela i usporediti s linearnim regresorom; morate definirati broj klase. Za logit regresiju, broj klase je jednak 2.

Model će izračunati težine stupaca sadržanih u continuous_features i categorical_features.

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

Izlaz

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}

Sada kada je klasifikator definiran, možete kreirati funkciju unosa. Metoda je ista kao u vodiču za linearni regresor. Ovdje koristite veličinu serije od 128 i miješate podatke.

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)

Kreirate funkciju s argumentima koje zahtijeva linearni procjenitelj, tj. broj epoha, broj serija i miješate skup podataka ili bilješku. Budući da koristite pande metodu za prosljeđivanje podataka u model, trebate definirati X varijable kao pandas podatkovni okvir. Imajte na umu da prelazite preko svih podataka pohranjenih u FEATURES.

Uvježbajmo model s objektnim modelom.vježbati. Prethodno definiranu funkciju koristite za unos odgovarajućih vrijednosti u model. Imajte na umu da ste postavili veličinu serije na 128, a broj epoha na Ništa. Model će se trenirati preko tisuću koraka.

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>

Imajte na umu da se gubitak naknadno smanjio tijekom zadnjih 100 koraka, tj. s 901 na 1000.

Konačni gubitak nakon tisuću iteracija je 5444. Možete procijeniti svoj model na testnom setu i vidjeti performanse. Da biste procijenili izvedbu svog modela, morate koristiti objektnu ocjenu. Model napunite testnim skupom i postavite broj epoha na 1, tj. podaci će ići u model samo jednom.

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 vraća sve metrike koje ste naučili u teoretskom dijelu. Bez iznenađenja, točnost je velika zbog neuravnotežene oznake. Zapravo, model ima malo bolju izvedbu od nasumične pretpostavke. Zamislite da model predviđa sva kućanstva s prihodom nižim od 50 tisuća, tada model ima točnost od 70 posto. Pri bližoj analizi, možete vidjeti da su predviđanje i prisjećanje prilično niski.

Korak 4) Poboljšajte model

Sada kada imate benchmark model, možete ga pokušati poboljšati, odnosno povećati točnost. U prethodnom vodiču naučili ste kako poboljšati snagu predviđanja pomoću pojma interakcije. U ovom ćete vodiču ponovno razmotriti ovu ideju dodavanjem polinomskog člana regresiji.

Polinomska regresija je korisna kada postoji nelinearnost podataka. Postoje dva načina za bilježenje nelinearnosti u podacima.

  • Dodajte polinomski član
  • Kontinuiranu varijablu pretvorite u kategoričku varijablu

Polinomski član

Na donjoj slici možete vidjeti što je polinomska regresija. To je jednadžba s X varijablama različite snage. Polinomska regresija drugog stupnja ima dvije varijable, X i X na kvadrat. Treći stupanj ima tri varijable, X, X2, i X3

Polinomska regresija
Što je polinomska regresija

U nastavku smo konstruirali graf s dvije varijable, X i Y. Očito je da odnos nije linearan. Ako dodamo linearnu regresiju, možemo vidjeti da model ne može uhvatiti uzorak (lijeva slika).

Sada, pogledajte lijevu sliku sa slike ispod, dodali smo pet članova regresiji (to je y=x+x2+x3+x4+x5. Model sada puno bolje bilježi uzorak. Ovo je moć polinomske regresije.

Polinomska regresija

Vratimo se našem primjeru. Dob nije u linearnoj vezi s prihodom. Rana dob može imati stalan prihod blizu nule jer djeca ili mladi ljudi ne rade. Zatim se povećava u radnoj dobi i smanjuje tijekom umirovljenja. Obično je oblika obrnutog slova U. Jedan od načina da se uhvati ovaj uzorak je dodavanje snage dva regresiji.

Da vidimo hoće li to povećati točnost.

Morate dodati ovu novu značajku u skup podataka i na popis kontinuiranih značajki.

Novu varijablu dodajete u skup podataka treniranja i testiranja, tako da je prikladnije napisati funkciju.

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

Funkcija ima 3 argumenta:

  • df_t: definirajte skup za obuku
  • df_te: definirajte ispitni skup
  • var_name = 'age': Definirajte varijablu za transformaciju

Možete koristiti objekt pow(2) za kvadriranje varijable starosti. Imajte na umu da je nova varijabla nazvana 'novo'

Sada kada je funkcija square_var napisana, možete stvoriti nove skupove podataka.

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

Kao što vidite, novi skup podataka ima još jednu značajku.

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

Kvadratna varijabla naziva se new u skupu podataka. Morate ga dodati na popis kontinuiranih značajki.

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]

bilješke da ste promijenili direktorij Grafa. Ne možete trenirati različite modele u istom direktoriju. To znači da trebate promijeniti putanju argumenta model_dir. Ako to ne učinite, TensorFlow će izbaciti pogrešku.

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)

Sada kada je klasifikator dizajniran s novim skupom podataka, možete trenirati i procijeniti model.

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}

Kvadratna varijabla poboljšala je točnost s 0.76 na 0.79. Da vidimo možete li uspjeti bolje kombiniranjem izraza bucketization i interakcije.

Bucketizacija i interakcija

Kao što ste vidjeli prije, linearni klasifikator ne može ispravno uhvatiti obrazac dobi i prihoda. To je zato što uči jednu težinu za svaku značajku. Kako biste klasifikatoru olakšali posao, jednu stvar koju možete učiniti je izdvojiti značajku. Bucketing transformira numeričku značajku u nekoliko određenih na temelju raspona u koji spada, a svaka od tih novih značajki pokazuje spada li dob osobe u taj raspon.

S ovim novim značajkama, linearni model može uhvatiti odnos učenjem različitih težina za svaku kantu.

U TensorFlowu se to radi s bucketized_column. Morate dodati raspon vrijednosti u granice.

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

Već znate da dob nije linearna s prihodom. Drugi način poboljšanja modela je interakcija. Riječju TensorFlowa, to je križanje značajki. Križanje značajki način je stvaranja novih značajki koje su kombinacije postojećih, što može biti od pomoći za linearni klasifikator koji ne može modelirati interakcije između značajki.

Dob možete raščlaniti pomoću druge značajke kao što je obrazovanje. Odnosno, neke će skupine vjerojatno imati visoke prihode, a druge niske (razmislite o doktoratu).

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

Da biste stvorili križni stupac značajki, koristite crossed_column s varijablama za križanje u zagradi. Hash_bucket_size označava maksimalne mogućnosti križanja. Za stvaranje interakcije između varijabli (barem jedna varijabla mora biti kategorička), možete koristiti tf.feature_column.crossed_column. Da biste koristili ovaj objekt, morate u uglate zagrade dodati varijablu za interakciju i drugi argument, veličinu spremnika. Veličina spremnika je najveći mogući broj grupa unutar varijable. Ovdje ga postavljate na 1000 jer ne znate točan broj grupa

age_buckets potrebno je kvadrirati prije dodavanja u stupce značajki. Također dodajete nove značajke u stupce značajki i pripremate procjenitelj

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)

Izlaz

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)

Spremni ste procijeniti novi model i vidjeti hoće li poboljšati točnost.

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}

Nova razina točnosti je 83.58 posto. To je četiri posto više od prethodnog modela.

Na kraju, možete dodati termin za reguliranje kako biste spriječili prekomjerno opremanje.

Korak 5) Hiperparametar: laso i greben

Vaš model može patiti od prekomjerno opremanje or nedovoljna opremljenost.

  • Prekomjerno opremanje: model ne može generalizirati predviđanje na nove podatke
  • Nedovoljno prilagođavanje: model ne može uhvatiti uzorak podataka. tj. linearna regresija kada su podaci nelinearni

Kada model ima puno parametara i relativno malu količinu podataka, to dovodi do loših predviđanja. Zamislite, jedna grupa ima samo tri zapažanja; model će izračunati težinu za ovu grupu. Težina se koristi za predviđanje; ako se opažanja testnog skupa za ovu posebnu skupinu potpuno razlikuju od skupa za treniranje, tada će model napraviti krivo predviđanje. Tijekom evaluacije sa skupom za vježbanje, točnost je dobra, ali nije dobra s testnim skupom jer izračunate težine nisu prave za generalizaciju uzorka. U ovom slučaju ne donosi razumno predviđanje na temelju nevidljivih podataka.

Kako biste spriječili prekomjerno prilagođavanje, regularizacija vam daje mogućnosti kontrole takve složenosti i da je učinite generaliziranijom. Postoje dvije tehnike regulacije:

  • L1: Laso
  • L2: Greben

U TensorFlowu možete dodati ova dva hiperparametra u optimizator. Na primjer, što je viši hiperparametar L2, težina ima tendenciju da bude vrlo niska i blizu nule. Uklopljena linija bit će vrlo ravna, dok L2 blizu nule implicira da su ponderi blizu regularne linearne regresije.

Možete sami isprobati različite vrijednosti hiperparametara i vidjeti možete li povećati razinu točnosti.

bilješke da ako promijenite hiperparametar, trebate izbrisati mapu ongoing/train4 inače će model započeti s prethodno obučenim modelom.

Pogledajmo kakva je točnost s hypeom

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

IZLAZ

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)

IZLAZ

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)

Izlaz

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}

Ovim hiperparametrom malo povećavate metriku točnosti. U sljedećem vodiču naučit ćete kako poboljšati linearni klasifikator pomoću kernel metode.

rezime

Da biste obučili model, trebate:

  • Definirajte značajke: Neovisne varijable: X
  • Definirajte oznaku: Zavisna varijabla: y
  • Konstruirajte vlak/set za testiranje
  • Definirajte početnu težinu
  • Definirajte funkciju gubitka: MSE
  • Optimizirajte model: Gradijent spuštanja
  • Definirati:
    • Stopa učenja
    • Broj epohe
    • Veličina serije
    • Broj razreda

U ovom vodiču ste naučili kako koristiti API visoke razine za klasifikator linearne regresije. Trebate definirati:

  1. Stupci značajki. Ako je kontinuirano: tf.feature_column.numeric_column(). Popis možete popuniti razumijevanjem popisa u pythonu
  2. Procjenitelj: tf.estimator.LinearClassifier(feature_columns, model_dir, n_classes = 2)
  3. Funkcija za uvoz podataka, veličine serije i epohe: input_fn()

Nakon toga, spremni ste za obuku, procjenu i predviđanje pomoću train(), evaluate() i predict()

Da biste poboljšali performanse modela, možete:

  • Koristite polinomsku regresiju
  • Pojam interakcije: tf.feature_column.crossed_column
  • Dodajte parametar regularizacije