TensorFlow binær klassifisering: Eksempel på lineær klassifisering
De to vanligste veiledet læring oppgavene er lineær regresjon og lineær klassifikator. Lineær regresjon forutsier en verdi mens den lineære klassifikatoren forutsier en klasse. Denne opplæringen er fokusert på lineære klassifikatoren.
Hva er lineær klassifisering?
A Lineær klassifiserer i Machine Learning er en metode for å finne et objekts klasse basert på dets egenskaper for statistisk klassifisering. Den tar klassifiseringsbeslutning basert på verdien av en lineær kombinasjon av egenskaper til et objekt. Lineær klassifikator brukes i praktiske problemer som dokumentklassifisering og problemer med mange variabler.
Klassifiseringsproblemer representerer omtrent 80 prosent av maskinlæringsoppgaven. Klassifisering tar sikte på å forutsi sannsynligheten for hver klasse gitt et sett med innganger. Etiketten (dvs. den avhengige variabelen) er en diskret verdi, kalt en klasse.
- Hvis etiketten bare har to klasser, er læringsalgoritmen en binær klassifikator.
- Multiclass classifier takler etiketter med mer enn to klasser.
Et typisk binært klassifiseringsproblem er for eksempel å forutsi sannsynligheten for at en kunde foretar et nytt kjøp. Forutsi hvilken type dyr som vises på et bilde, er et flerklasses klassifiseringsproblem siden det finnes mer enn to varianter av dyr.
Den teoretiske delen av denne opplæringen setter primært fokus på den binære klassen. Du vil lære mer om multiclass output-funksjonen i en fremtidig opplæring.
Hvordan fungerer binær klassifisering?
Du lærte i den forrige opplæringen at en funksjon er sammensatt av to typer variabler, en avhengig variabel og et sett med funksjoner (uavhengige variabler). I den lineære regresjonen er en avhengig variabel et reelt tall uten rekkevidde. Hovedmålet er å forutsi verdien ved å minimere den gjennomsnittlige kvadratfeilen.
For TensorFlow Binary Classifier kan etiketten ha hatt to mulige heltallsverdier. I de fleste tilfeller er det enten [0,1] eller [1,2]. For eksempel er målet å forutsi om en kunde vil kjøpe et produkt eller ikke. Etiketten er definert som følger:
- Y = 1 (kunden kjøpte produktet)
- Y = 0 (kunden kjøper ikke produktet)
Modellen bruker funksjonene X for å klassifisere hver kunde i den mest sannsynlige klassen han tilhører, nemlig potensiell kjøper eller ikke.
Sannsynligheten for suksess beregnes med logistisk regresjon. Algoritmen vil beregne en sannsynlighet basert på funksjonen X og spår en suksess når denne sannsynligheten er over 50 prosent. Mer formelt beregnes sannsynligheten som vist i eksemplet under TensorFlow Binary Classification:
hvor 0 er settet med vekter, funksjonene og b skjevheten.
Funksjonen kan dekomponeres i to deler:
- Den lineære modellen
- Logistikkfunksjonen
Lineær modell
Du er allerede kjent med måten vektene beregnes på. Vekter beregnes ved hjelp av et punktprodukt: Y er en lineær funksjon av alle funksjonene xi. Hvis modellen ikke har funksjoner, er prediksjonen lik bias, b.
Vektene angir retningen på korrelasjonen mellom trekkene xi og etiketten y. En positiv korrelasjon øker sannsynligheten for den positive klassen, mens en negativ korrelasjon fører sannsynligheten nærmere 0, (dvs. negativ klasse).
Den lineære modellen returnerer bare reelle tall, som er inkonsistent med sannsynlighetsmålet for rekkevidde [0,1]. Den logistiske funksjonen er nødvendig for å konvertere den lineære modellens utdata til en sannsynlighet,
Logistikkfunksjon
Den logistiske funksjonen, eller sigmoid-funksjonen, har en S-form og utgangen til denne funksjonen er alltid mellom 0 og 1.

Det er lett å erstatte utgangen av den lineære regresjonen med sigmoidfunksjonen. Det resulterer i et nytt tall med en sannsynlighet mellom 0 og 1.
Klassifisereren kan transformere sannsynligheten til en klasse
- Verdier mellom 0 og 0.49 blir klasse 0
- Verdier mellom 0.5 og 1 blir klasse 1
Hvordan måle ytelsen til Linear Classifier?
Nøyaktighet
Den totale ytelsen til en klassifikator måles med nøyaktighetsmålingen. Nøyaktighet samler alle de riktige verdiene delt på det totale antallet observasjoner. For eksempel betyr en nøyaktighetsverdi på 80 prosent at modellen er riktig i 80 prosent av tilfellene.

Du kan merke en mangel med denne beregningen, spesielt for ubalanseklassen. Et ubalansedatasett oppstår når antall observasjoner per gruppe ikke er likt. La oss si; du prøver å klassifisere en sjelden hendelse med en logistisk funksjon. Tenk deg at klassifisereren prøver å estimere døden til en pasient etter en sykdom. I dataene går 5 prosent av pasientene bort. Du kan trene en klassifiserer til å forutsi antall dødsfall og bruke nøyaktighetsmålingen til å evaluere prestasjonene. Hvis klassifikatoren spår 0 dødsfall for hele datasettet, vil det være riktig i 95 prosent av tilfellet.
Forvirringsmatrise
En bedre måte å vurdere ytelsen til en klassifikator på er å se på forvirringsmatrisen.

Ocuco forvirringsmatrise visualiserer nøyaktigheten til en klassifikator ved å sammenligne de faktiske og forutsagte klassene som vist i eksemplet ovenfor. Den binære forvirringsmatrisen er sammensatt av kvadrater:
- TP: Sant positiv: Forutsagte verdier er korrekt predikert som faktisk positive
- FP: Forutsagte verdier spådde feil en faktisk positiv. dvs. negative verdier spådd som positive
- FN: Falsk Negativ: Positive verdier predikert som negative
- TN: Sann negativ: Forutsagte verdier er korrekt predikert som faktisk negative
Fra forvirringsmatrisen er det lett å sammenligne den faktiske klassen og den predikerte klassen.
Presisjon og følsomhet
Forvirringsmatrisen gir et godt innblikk i det sanne positive og falske positive. I noen tilfeller er det å foretrekke å ha en mer kortfattet beregning.
Precision
Presisjonsmetrikken viser nøyaktigheten til den positive klassen. Den måler hvor sannsynlig prediksjonen til den positive klassen er riktig.
Maksimal poengsum er 1 når klassifisereren klassifiserer alle de positive verdiene perfekt. Presisjon alene er ikke veldig nyttig fordi den ignorerer den negative klassen. Beregningen er vanligvis sammenkoblet med Recall-beregning. Tilbakekalling kalles også sensitivitet eller sann positiv rate.
Følsomhet
Sensitivitet beregner forholdet mellom positive klasser som er riktig oppdaget. Denne beregningen viser hvor god modellen er til å gjenkjenne en positiv klasse.
Lineær klassifisering med TensorFlow
For denne opplæringen vil vi bruke folketellingsdatasettet. Hensikten er å bruke variablene i tellingsdatasettet til å forutsi inntektsnivået. Merk at inntekten er en binær variabel
- med en verdi på 1 hvis inntekten > 50k
- 0 hvis inntekt < 50k.
Denne variabelen er etiketten din
Dette datasettet inkluderer åtte kategoriske variabler:
- arbeidsplass
- utdanning
- ekteskapelig
- okkupasjon
- forholdet
- rase
- kjønn
- native_country
dessuten seks kontinuerlige variabler:
- alder
- fnlwgt
- utdanning_nummer
- kapitalgevinst
- kapitaltap
- timer_uke
Gjennom dette TensorFlow-klassifiseringseksemplet vil du forstå hvordan du trener opp lineære TensorFlow-klassifikatorer med TensorFlow-estimator og hvordan du forbedrer nøyaktighetsmålingen.
Vi vil gå frem som følger:
- Trinn 1) Importer dataene
- Trinn 2) Datakonvertering
- Trinn 3) Tren klassifisereren
- Trinn 4) Forbedre modellen
- Trinn 5) Hyperparameter: Lasso & Ridge
Trinn 1) Importer dataene
Du importerer først bibliotekene som ble brukt under opplæringen.
import tensorflow as tf import pandas as pd
Deretter importerer du dataene fra arkivet til UCI og definerer kolonnenavnene. Du vil bruke KOLONNER for å navngi kolonnene i en panda-dataramme.
Merk at du trener klassifisereren ved å bruke en Pandas-dataramme.
## 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"
Dataene som er lagret på nett er allerede delt mellom et togsett og et testsett.
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)
Togsettet inneholder 32,561 observasjoner og testsettet 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 krever en boolsk verdi for å trene klassifisereren. Du må caste verdiene fra streng til heltall. Etiketten lagres som et objekt, men du må konvertere den til en numerisk verdi. Koden nedenfor lager en ordbok med verdiene som skal konverteres og sløyfe over kolonneelementet. Merk at du utfører denne operasjonen to ganger, en for togtesten, en for testsettet
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]
I togdataene er det 24,720 50 inntekter lavere enn 7841k og XNUMX over. Forholdet er nesten det samme for testsettet. Vennligst se denne veiledningen om fasetter for mer.
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
Trinn 2) Datakonvertering
Noen få trinn kreves før du trener en lineær klassifikator med Tensorflow. Du må forberede funksjonene som skal inkluderes i modellen. I benchmark-regresjonen vil du bruke de originale dataene uten å bruke noen transformasjon.
Estimatoren må ha en liste over funksjoner for å trene modellen. Derfor må kolonnens data konverteres til en tensor.
En god praksis er å definere to lister med funksjoner basert på deres type og deretter sende dem i funksjonskolonnene til estimatoren.
Du vil begynne med å konvertere kontinuerlige funksjoner, og deretter definere en bøtte med de kategoriske dataene.
Funksjonene til datasettet har to formater:
- Heltall
- Objekt
Hver funksjon er oppført i de neste to variablene i henhold til deres type.
## 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 er utstyrt med en objekt numeric_column for å hjelpe til med transformasjonen av de kontinuerlige variablene til tensor. I koden nedenfor konverterer du alle variablene fra CONTI_FEATURES til en tensor med en numerisk verdi. Dette er obligatorisk for å konstruere modellen. Alle de uavhengige variablene må konverteres til riktig type tensor.
Nedenfor skriver vi en kode for å la deg se hva som skjer bak feature_column.numeric_column. Vi vil skrive ut den konverterte verdien for alder. Det er for forklarende formål, derfor er det ikke nødvendig å forstå python-koden. Du kan referere til den offisielle dokumentasjonen for å forstå kodene.
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.]]
Verdiene er nøyaktig de samme som i df_train
continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]
I følge TensorFlow-dokumentasjonen er det forskjellige måter å konvertere kategoriske data på. Hvis vokabularlisten til en funksjon er kjent og ikke har mange verdier, er det mulig å lage den kategoriske kolonnen med categorical_column_with_vocabulary_list. Den vil tildele alle unike ordforrådslister en ID.
For eksempel, hvis en variabelstatus har tre distinkte verdier:
- Mann
- Kone
- enslig
Da vil tre IDer bli tilskrevet. Ektemannen vil for eksempel ha ID 1, Kone ID 2 og så videre.
For illustrasjonsformål kan du bruke denne koden til å konvertere en objektvariabel til en kategorisk kolonne i TensorFlow.
Funksjonen sex kan bare ha to verdier: mann eller kvinne. Når vi skal konvertere funksjonskjønnet, vil Tensorflow opprette 2 nye kolonner, en for mann og en for kvinne. Hvis kjønn er lik mann, vil den nye kolonnen mann være lik 1 og kvinne 0. Dette eksemplet vises i tabellen nedenfor:
| rader | kjønn | etter transformasjon | mann | hunn |
|---|---|---|---|---|
| 1 | mann | => | 1 | 0 |
| 2 | mann | => | 1 | 0 |
| 3 | hunn | => | 0 | 1 |
I tensorflow:
print_transformation(feature = "sex", continuous = False, size = 2)
[[1. 0.]
[1. 0.]
[1. 0.]
...
[0. 1.]
[1. 0.]
[0. 1.]]
relationship = tf.feature_column.categorical_column_with_vocabulary_list(
'relationship', [
'Husband', 'Not-in-family', 'Wife', 'Own-child', 'Unmarried',
'Other-relative'])
Nedenfor la vi til Python kode for å skrive ut kodingen. Igjen, du trenger ikke å forstå koden, hensikten er å se transformasjonen
En raskere måte å transformere dataene på er imidlertid å bruke metoden categorical_column_with_hash_bucket. Det vil være nyttig å endre strengvariabler i en sparsom matrise. En sparsom matrise er en matrise med stort sett null. Metoden tar seg av alt. Du trenger bare å angi antall bøtter og nøkkelkolonnen. Antall bøtter er det maksimale antallet grupper som Tensorflow kan opprette. Nøkkelkolonnen er ganske enkelt navnet på kolonnen som skal konverteres.
I koden nedenfor lager du en løkke over alle de kategoriske funksjonene.
categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]
Trinn 3) Tren klassifisereren
TensorFlow gir for tiden en estimator for lineær regresjon og lineær klassifisering.
- Lineær regresjon: LineærRegressor
- Lineær klassifisering: LinearClassifier
Syntaksen til den lineære klassifikatoren er den samme som i opplæringen på lineær regresjon bortsett fra ett argument, n_class. Du må definere funksjonskolonnen, modellkatalogen og sammenligne med den lineære regressoren; du har definere antall klasse. For en logit-regresjon er antallet klasse lik 2.
Modellen vil beregne vektene til kolonnene i kontinuerlige_funksjoner og kategoriske_funksjoner.
model = tf.estimator.LinearClassifier(
n_classes = 2,
model_dir="ongoing/train",
feature_columns=categorical_features+ continuous_features)
Produksjon
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}
Nå som klassifisereren er definert, kan du opprette inndatafunksjonen. Metoden er den samme som i opplæringen for lineær regressor. Her bruker du en batchstørrelse på 128 og du blander dataene.
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)
Du lager en funksjon med argumentene som kreves av den lineære estimatoren, dvs. antall epoker, antall batcher og blander datasettet eller notatet. Siden du bruker pandaer metode for å sende data inn i modellen, må du definere X-variablene som en panda-dataramme. Merk at du går over alle data som er lagret i FUNKSJONER.
La oss trene modellen med objektet model.train. Du bruker funksjonen som er definert tidligere for å mate modellen med de riktige verdiene. Merk at du setter batchstørrelsen til 128 og antall epoker til Ingen. Modellen skal trenes over tusen trinn.
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>
Merk at tapet ble redusert i løpet av de siste 100 trinnene, dvs. fra 901 til 1000.
Det endelige tapet etter tusen iterasjoner er 5444. Du kan estimere modellen din på testsettet og se ytelsen. For å evaluere ytelsen til modellen din, må du bruke objektevalueringen. Du mater modellen med testsettet og setter antall epoker til 1, dvs. dataene vil kun gå til modellen én gang.
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 returnerer alle beregningene du lærte i den teoretiske delen. Uten overraskelse er nøyaktigheten stor på grunn av den ubalanserte etiketten. Faktisk presterer modellen litt bedre enn en tilfeldig gjetning. Tenk deg modellen forutsi alle husholdninger med inntekt lavere enn 50K, da har modellen en nøyaktighet på 70 prosent. Ved en nærmere analyse kan du se at prediksjonen og tilbakekallingen er ganske lav.
Trinn 4) Forbedre modellen
Nå som du har en benchmark-modell, kan du prøve å forbedre den, det vil si øke nøyaktigheten. I den forrige opplæringen lærte du hvordan du forbedrer prediksjonskraften med et interaksjonsbegrep. I denne opplæringen vil du gå tilbake til denne ideen ved å legge til et polynomledd i regresjonen.
Polynomregresjon er instrumentell når det er ikke-linearitet i dataene. Det er to måter å fange ikke-linearitet i dataene.
- Legg til polynomledd
- Brett den kontinuerlige variabelen inn i en kategorisk variabel
Polynomisk term
Fra bildet nedenfor kan du se hva en polynomregresjon er. Det er en ligning med X-variabler med ulik styrke. En andregrads polynomregresjon har to variabler, X og X i annen. Tredje grad har tre variabler, X, X2,og X3

Nedenfor har vi konstruert en graf med to variabler, X og Y. Det er åpenbart at sammenhengen ikke er lineær. Hvis vi legger til en lineær regresjon, kan vi se at modellen ikke klarer å fange mønsteret (bilde til venstre).
Nå, se på det venstre bildet fra bildet nedenfor, vi la til fem-ledd til regresjonen (det vil si y=x+x2+x3+x4+x5. Modellen fanger nå mye bedre mønsteret. Dette er kraften til polynomregresjon.
La oss gå tilbake til vårt eksempel. Alder står ikke i et lineært forhold til inntekt. Tidlig alder kan ha en flat inntekt nær null fordi barn eller unge ikke jobber. Så øker den i yrkesaktiv alder og avtar ved pensjonering. Det er vanligvis en omvendt U-form. En måte å fange dette mønsteret på er å legge til en potens to til regresjonen.
La oss se om det øker nøyaktigheten.
Du må legge til denne nye funksjonen i datasettet og i listen over kontinuerlige funksjoner.
Du legger til den nye variabelen i tog- og testdatasettet, så det er mer praktisk å skrive en funksjon.
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
Funksjonen har 3 argumenter:
- df_t: definer treningssettet
- df_te: definer testsettet
- var_name = 'alder': Definer variabelen som skal transformeres
Du kan bruke objektet pow(2) for å kvadre variabelen alder. Merk at den nye variabelen heter "ny"
Nå som funksjonen square_var er skrevet, kan du opprette de nye datasettene.
df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')
Som du kan se, har det nye datasettet en funksjon til.
print(df_train_new.shape, df_test_new.shape) (32561, 16) (16281, 16)
Den kvadratiske variabelen kalles ny i datasettet. Du må legge den til listen over kontinuerlige funksjoner.
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]
Merknader at du endret katalogen til grafen. Du kan ikke trene forskjellige modeller i samme katalog. Det betyr at du må endre banen til argumentet model_dir. Hvis du ikke gjør det, vil TensorFlow gi en feilmelding.
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)
Nå som klassifikatoren er designet med det nye datasettet, kan du trene og evaluere modellen.
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}
Den kvadratiske variabelen forbedret nøyaktigheten fra 0.76 til 0.79. La oss se om du kan gjøre det bedre ved å kombinere bucketization og interaksjonsterm sammen.
Bøttesetting og interaksjon
Som du så før, er ikke en lineær klassifikator i stand til å fange aldersinntektsmønsteret riktig. Det er fordi den lærer en enkelt vekt for hver funksjon. For å gjøre det enklere for klassifisereren, er en ting du kan gjøre å sette inn funksjonen. Bucking forvandler en numerisk funksjon til flere bestemte basert på området den faller inn i, og hver av disse nye funksjonene indikerer om en persons alder faller innenfor dette området.
Med disse nye funksjonene kan den lineære modellen fange forholdet ved å lære forskjellige vekter for hver bøtte.
I TensorFlow gjøres det med bucketized_column. Du må legge til verdiområdet i grensene.
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])
Du vet allerede at alder er ikke-lineær med inntekt. En annen måte å forbedre modellen på er gjennom interaksjon. Med TensorFlows ord er det funksjonskryss. Funksjonskryss er en måte å lage nye funksjoner på som er kombinasjoner av eksisterende, noe som kan være nyttig for en lineær klassifiserer som ikke kan modellere interaksjoner mellom funksjoner.
Du kan bryte ned alder med en annen funksjon som utdanning. Det vil si at noen grupper sannsynligvis har høy inntekt og andre lav (Tenk på Ph.D.-studenten).
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)]
For å lage en kryssfunksjonskolonne bruker du crossed_column med variablene som skal krysses i en parentes. Hash_bucket_size indikerer maksimale kryssingsmuligheter. For å skape interaksjon mellom variabler (minst én variabel må være kategorisk), kan du bruke tf.feature_column.crossed_column. For å bruke dette objektet må du legge til variabelen for å samhandle i hakeparentes og et andre argument, bøttestørrelsen. Bøttestørrelsen er det maksimale antallet grupper som er mulig innenfor en variabel. Her setter du den til 1000 da du ikke vet nøyaktig antall grupper
age_buckets må være kvadratisk før for å legge det til funksjonskolonnene. Du legger også til de nye funksjonene i funksjonskolonnene og forbereder estimatoren
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)
Produksjon
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)
Du er klar til å anslå den nye modellen og se om den forbedrer nøyaktigheten.
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}
Det nye nøyaktighetsnivået er 83.58 prosent. Det er fire prosent høyere enn forrige modell.
Til slutt kan du legge til en regulariseringsterm for å forhindre overtilpasning.
Trinn 5) Hyperparameter: Lasso & Ridge
Modellen din kan lide av overtilpassing or undermontering.
- Overtilpasning: Modellen er ikke i stand til å generalisere prediksjonen til nye data
- Undertilpasning: Modellen er ikke i stand til å fange opp mønsteret til dataene. dvs. lineær regresjon når dataene er ikke-lineære
Når en modell har mange parametere og en relativt lav mengde data, fører det til dårlige spådommer. Tenk deg at én gruppe bare har tre observasjoner; modellen vil beregne en vekt for denne gruppen. Vekten brukes til å forutsi; hvis observasjonene av testsettet for denne spesielle gruppen er helt forskjellig fra treningssettet, vil modellen gi en feil prediksjon. Under evalueringen med treningssettet er nøyaktigheten god, men ikke bra med testsettet fordi vektene som er beregnet ikke er den sanne for å generalisere mønsteret. I dette tilfellet gir den ikke en rimelig prediksjon om usynlige data.
For å forhindre overtilpasning gir regularisering deg muligheter til å kontrollere for slik kompleksitet og gjøre den mer generaliserbar. Det er to regulariseringsteknikker:
- L1: Lasso
- L2: Ås
I TensorFlow kan du legge til disse to hyperparametrene i optimizeren. For eksempel, jo høyere hyperparameter L2 er, har vekten en tendens til å være veldig lav og nær null. Den tilpassede linjen vil være veldig flat, mens en L2 nær null betyr at vektene er nær den vanlige lineære regresjonen.
Du kan prøve selv de forskjellige verdiene til hyperparametrene og se om du kan øke nøyaktighetsnivået.
Merknader at hvis du endrer hyperparameteren, må du slette mappen ongoing/train4 ellers vil modellen starte med den tidligere trente modellen.
La oss se hvordan nøyaktigheten med hypen er
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))
UTGANG
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)
UTGANG
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)
Produksjon
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}
Med denne hyperparameteren øker du nøyaktighetsmålingene litt. I den neste opplæringen vil du lære hvordan du forbedrer en lineær klassifisering ved hjelp av en kjernemetode.
Sammendrag
For å trene en modell må du:
- Definer funksjonene: Uavhengige variabler: X
- Definer etiketten: Avhengig variabel: y
- Konstruer et tog/testsett
- Definer startvekten
- Definer tapsfunksjonen: MSE
- Optimaliser modellen: Gradientnedstigning
- Definere:
- Læringsfrekvens
- Antall epoker
- Partistørrelse, Gruppestørrelse
- Antall klasse
I denne opplæringen lærte du hvordan du bruker høynivå-API for en lineær regresjonsklassifisering. Du må definere:
- Funksjonskolonner. Hvis kontinuerlig: tf.feature_column.numeric_column(). Du kan fylle ut en liste med python-listeforståelse
- Estimatoren: tf.estimator.LinearClassifier(feature_columns, model_dir, n_classes = 2)
- En funksjon for å importere dataene, batchstørrelsen og epoken: input_fn()
Etter det er du klar til å trene, evaluere og lage en prediksjon med train(), evaluate() og predict()
For å forbedre ytelsen til modellen kan du:
- Bruk polynomregresjon
- Interaksjonsterm: tf.feature_column.crossed_column
- Legg til regulariseringsparameter




