TensorFlow binær klassifikation: Eksempel på lineær klassificering
De to mest almindelige overvåget læring opgaver er lineær regression og lineær klassifikator. Lineær regression forudsiger en værdi, mens den lineære klassifikator forudsiger en klasse. Denne tutorial er fokuseret på lineære klassificeringsapparater.
Hvad er lineær klassificering?
A Lineær klassifikator i Machine Learning er en metode til at finde et objekts klasse baseret på dets karakteristika til statistisk klassificering. Den træffer klassificeringsbeslutning baseret på værdien af en lineær kombination af karakteristika for et objekt. Lineær klassifikator bruges i praktiske problemer som dokumentklassificering og problemer med mange variabler.
Klassificeringsproblemer repræsenterer omkring 80 procent af maskinlæringsopgaven. Klassificering har til formål at forudsige sandsynligheden for hver klasse givet et sæt input. Etiketten (dvs. den afhængige variabel) er en diskret værdi, kaldet en klasse.
- Hvis etiketten kun har to klasser, er indlæringsalgoritmen en binær klassifikator.
- Multiclass classifier tackler etiketter med mere end to klasser.
For eksempel er et typisk binært klassifikationsproblem at forudsige sandsynligheden for, at en kunde foretager et andet køb. Forudsige den type dyr, der vises på et billede, er et multiklasse-klassificeringsproblem, da der findes mere end to dyrevarianter.
Den teoretiske del af denne tutorial sætter primært fokus på den binære klasse. Du vil lære mere om multiclass output-funktionen i en fremtidig vejledning.
Hvordan virker binær klassificering?
Du lærte i den forrige tutorial, at en funktion er sammensat af to slags variable, en afhængig variabel og et sæt funktioner (uafhængige variabler). I den lineære regression er en afhængig variabel et reelt tal uden interval. Det primære formål er at forudsige dens værdi ved at minimere den gennemsnitlige kvadratiske fejl.
For TensorFlow Binary Classifier kan etiketten have haft to mulige heltalsværdier. I de fleste tilfælde er det enten [0,1] eller [1,2]. For eksempel er målet at forudsige, om en kunde vil købe et produkt eller ej. Etiketten er defineret som følger:
- Y = 1 (kunden købte produktet)
- Y = 0 (kunden køber ikke produktet)
Modellen bruger funktionerne X til at klassificere hver kunde i den mest sandsynlige klasse, han tilhører, nemlig potentiel køber eller ej.
Sandsynligheden for succes beregnes med Logistisk regression. Algoritmen vil beregne en sandsynlighed baseret på funktionen X og forudsiger en succes, når denne sandsynlighed er over 50 procent. Mere formelt beregnes sandsynligheden som vist i nedenstående TensorFlow Binary Classification-eksempel:
hvor 0 er mængden af vægte, funktionerne og b bias.
Funktionen kan dekomponeres i to dele:
- Den lineære model
- Den logistiske funktion
Lineær model
Du er allerede bekendt med den måde, vægten beregnes på. Vægte beregnes ved hjælp af et prikprodukt: Y er en lineær funktion af alle træk xi. Hvis modellen ikke har funktioner, er forudsigelsen lig med bias, b.
Vægtene angiver retningen af korrelationen mellem funktionerne xi og etiketten y. En positiv korrelation øger sandsynligheden for den positive klasse, mens en negativ korrelation fører sandsynligheden tættere på 0, (dvs. negativ klasse).
Den lineære model returnerer kun et reelt tal, hvilket er inkonsistent med sandsynlighedsmålet for rækkevidde [0,1]. Den logistiske funktion er påkrævet for at konvertere den lineære modeloutput til en sandsynlighed,
Logistisk funktion
Den logistiske funktion, eller sigmoid-funktionen, har en S-form, og udgangen af denne funktion er altid mellem 0 og 1.
Det er let at erstatte outputtet af den lineære regression med sigmoidfunktionen. Det resulterer i et nyt tal med en sandsynlighed mellem 0 og 1.
Klassifikatoren kan omdanne sandsynligheden til en klasse
- Værdier mellem 0 og 0.49 bliver klasse 0
- Værdier mellem 0.5 og 1 bliver klasse 1
Hvordan måler man ydeevnen af Linear Classifier?
Nøjagtighed
Den samlede ydeevne af en klassifikator måles med nøjagtighedsmetrikken. Nøjagtighed indsamler alle de korrekte værdier divideret med det samlede antal observationer. For eksempel betyder en nøjagtighedsværdi på 80 procent, at modellen er korrekt i 80 procent af tilfældene.
Du kan bemærke en mangel med denne metrik, især for ubalanceklasse. Et ubalancedatasæt opstår, når antallet af observationer pr. gruppe ikke er det samme. Lad os sige; du forsøger at klassificere en sjælden hændelse med en logistisk funktion. Forestil dig, at klassificereren forsøger at estimere en patients død efter en sygdom. I dataene dør 5 procent af patienterne. Du kan træne en klassifikator til at forudsige antallet af dødsfald og bruge nøjagtighedsmetrikken til at evaluere præstationerne. Hvis klassifikatoren forudsiger 0 dødsfald for hele datasættet, vil det være korrekt i 95 procent af tilfældene.
Forvirringsmatrix
En bedre måde at vurdere en klassifikators ydeevne er at se på forvirringsmatricen.
forvirringsmatrix visualiserer nøjagtigheden af en klassifikator ved at sammenligne de faktiske og forudsagte klasser som vist i ovenstående Linear Classifier-eksempel. Den binære forvekslingsmatrix er sammensat af kvadrater:
- TP: Sand positiv: Forudsagte værdier korrekt forudsagt som faktisk positive
- FP: Forudsagte værdier forudsagde forkert en faktisk positiv. dvs. negative værdier forudsagt som positive
- FN: Falsk Negativ: Positive værdier forudsagt som negative
- TN: Sand negativ: Forudsagte værdier korrekt forudsagt som faktisk negative
Fra forvirringsmatricen er det let at sammenligne den faktiske klasse og den forudsagte klasse.
Præcision og følsomhed
Forvirringsmatricen giver et godt indblik i de sande positive og falske positive. I nogle tilfælde er det at foretrække at have en mere kortfattet metrisk.
Precision
Præcisionsmetrikken viser nøjagtigheden af den positive klasse. Det måler, hvor sandsynligt forudsigelsen af den positive klasse er korrekt.
Den maksimale score er 1, når klassificereren perfekt klassificerer alle de positive værdier. Præcision alene er ikke særlig nyttig, fordi den ignorerer den negative klasse. Metrikken er normalt parret med Recall-metrikken. Genkaldelse kaldes også følsomhed eller sand positiv rate.
Følsomhed
Følsomhed beregner forholdet mellem positive klasser korrekt detekteret. Denne metrik viser, hvor god modellen er til at genkende en positiv klasse.
Lineær klassificering med TensorFlow
Til denne vejledning vil vi bruge folketællingsdatasættet. Formålet er at bruge variablerne i tællingsdatasættet til at forudsige indkomstniveauet. Bemærk, at indkomsten er en binær variabel
- med en værdi på 1, hvis indkomsten > 50k
- 0 hvis indkomst < 50k.
Denne variabel er din etiket
Dette datasæt indeholder otte kategoriske variable:
- arbejdsplads
- uddannelse
- ægteskabelig
- besættelse
- forhold
- løb
- køn
- oprindelses land
desuden seks kontinuerte variable:
- alder
- fnlwgt
- uddannelsesnummer
- kapitalgevinst
- kapitaltab
- timer_uge
Gennem dette TensorFlow-klassificeringseksempel vil du forstå, hvordan du træner lineære TensorFlow-klassifikatorer med TensorFlow-estimator, og hvordan du forbedrer nøjagtighedsmetrikken.
Vi fortsætter som følger:
- Trin 1) Importer dataene
- Trin 2) Datakonvertering
- Trin 3) Træn klassificereren
- Trin 4) Forbedre modellen
- Trin 5) Hyperparameter: Lasso & Ridge
Trin 1) Importer dataene
Du importerer først de biblioteker, der blev brugt under selvstudiet.
import tensorflow as tf import pandas as pd
Derefter importerer du dataene fra UCI's arkiv og definerer kolonnenavnene. Du skal bruge KOLONNERNE til at navngive kolonnerne i en panda-dataramme.
Bemærk, at du træner klassificereren ved hjælp af 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"
De data, der er lagret online, er allerede opdelt mellem et togsæt og et testsæt.
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)
Togsættet indeholder 32,561 observationer og testsættet 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 kræver en boolsk værdi for at træne klassifikatoren. Du skal caste værdierne fra streng til heltal. Etiketten gemmes som et objekt, men du skal konvertere den til en numerisk værdi. Koden nedenfor opretter en ordbog med de værdier, der skal konverteres og loop over kolonneelementet. Bemærk, at du udfører denne operation to gange, én til togtesten, én til testsættet
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 der 24,720 indkomster lavere end 50k og 7841 ovenfor. Forholdet er næsten det samme for testsættet. Se venligst denne vejledning om Facets for mere.
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
Trin 2) Datakonvertering
Der kræves et par trin, før du træner en lineær klassifikator med Tensorflow. Du skal forberede de funktioner, der skal inkluderes i modellen. I benchmark-regressionen vil du bruge de originale data uden at anvende nogen transformation.
Estimatoren skal have en liste over funktioner for at træne modellen. Derfor skal kolonnens data konverteres til en tensor.
En god praksis er at definere to lister over funktioner baseret på deres type og derefter sende dem i feature_columns i estimatoren.
Du vil begynde med at konvertere kontinuerlige funktioner og derefter definere en bøtte med de kategoriske data.
Datasættets funktioner har to formater:
- Integer
- Object
Hver funktion er angivet i de næste to variabler i henhold til deres typer.
## 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 udstyret med en objekt numeric_column for at hjælpe med at transformere de kontinuerlige variable til tensor. I koden nedenfor konverterer du alle variablerne fra CONTI_FEATURES til en tensor med en numerisk værdi. Dette er obligatorisk for at konstruere modellen. Alle de uafhængige variabler skal konverteres til den rigtige type tensor.
Nedenfor skriver vi en kode for at lade dig se, hvad der sker bag feature_column.numeric_column. Vi vil udskrive den konverterede værdi for alder. Det er til forklarende formål, så der er ingen grund til at forstå pythonkoden. Du kan henvise til den officielle dokumentation for at forstå koderne.
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.]]
Værdierne er nøjagtig de samme som i df_train
continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]
Ifølge TensorFlow-dokumentationen er der forskellige måder at konvertere kategoriske data på. Hvis ordforrådslisten for en funktion er kendt og ikke har mange værdier, er det muligt at oprette den kategoriske kolonne med kategorisk_kolonne_med_ordforrådsliste. Det vil tildele alle unikke ordforrådslister et ID.
For eksempel, hvis en variabelstatus har tre forskellige værdier:
- mand
- Kone
- Single
Derefter vil tre ID blive tildelt. For eksempel vil Mand have ID 1, Kone ID 2 og så videre.
Til illustrationsformål kan du bruge denne kode til at konvertere en objektvariabel til en kategorisk kolonne i TensorFlow.
Funktionen køn kan kun have to værdier: mand eller kvinde. Når vi konverterer feature-kønnet, vil Tensorflow oprette 2 nye kolonner, en for mand og en for kvinde. Hvis køn er lig med mand, så vil den nye søjle han være lig med 1 og kvindelig til 0. Dette eksempel er vist i tabellen nedenfor:
rækker | køn | efter transformation | mand | kvinde |
---|---|---|---|---|
1 | mand | => | 1 | 0 |
2 | mand | => | 1 | 0 |
3 | kvinde | => | 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 tilføjede vi Python kode for at udskrive kodningen. Igen, du behøver ikke at forstå koden, formålet er at se transformationen
En hurtigere måde at transformere dataene på er dog at bruge metoden categorical_column_with_hash_bucket. Ændring af strengvariabler i en sparsom matrix vil være nyttig. En sparsom matrix er en matrix med for det meste nul. Metoden tager sig af alt. Du behøver kun at angive antallet af spande og nøglekolonnen. Antallet af buckets er det maksimale antal grupper, som Tensorflow kan oprette. Nøglekolonnen er simpelthen navnet på den kolonne, der skal konverteres.
I koden nedenfor opretter du en løkke over alle de kategoriske funktioner.
categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]
Trin 3) Træn klassificereren
TensorFlow giver i øjeblikket en estimator for lineær regression og lineær klassifikation.
- Lineær regression: LineærRegressor
- Lineær klassifikation: LinearClassifier
Syntaksen for den lineære klassifikator er den samme som i vejledningen om lineær regression undtagen et argument, n_class. Du skal definere funktionskolonnen, modelbiblioteket og sammenligne med den lineære regressor; du har defineret antallet af klasse. For en logit-regression er antallet af klasse lig med 2.
Modellen vil beregne vægten af kolonnerne indeholdt i continuous_features og categorical_features.
model = tf.estimator.LinearClassifier( n_classes = 2, model_dir="ongoing/train", feature_columns=categorical_features+ continuous_features)
Produktion
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}
Nu hvor klassificeringen er defineret, kan du oprette inputfunktionen. Metoden er den samme som i den lineære regressor tutorial. Her bruger 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 opretter en funktion med de argumenter, der kræves af den lineære estimator, dvs. antal epoker, antal batches og blander datasættet eller noten. Siden du bruger pandas metode til at sende dataene ind i modellen, skal du definere X-variablerne som en panda-dataramme. Bemærk, at du går over alle data, der er gemt i FEATURES.
Lad os træne modellen med objektet model.train. Du bruger den tidligere definerede funktion til at fodre modellen med de passende værdier. Bemærk, at du indstiller batchstørrelsen til 128 og antallet af epoker til Ingen. Modellen vil blive trænet over tusind trin.
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>
Bemærk, at tabet efterfølgende faldt i løbet af de sidste 100 trin, dvs. fra 901 til 1000.
Det endelige tab efter tusinde iterationer er 5444. Du kan estimere din model på testsættet og se ydeevnen. For at evaluere din models ydeevne skal du bruge objektevalueringen. Du fodrer modellen med testsættet og indstiller antallet af 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 de målinger, du har lært i den teoretiske del. Uden overraskelse er nøjagtigheden stor på grund af den ubalancerede etiket. Faktisk klarer modellen sig lidt bedre end et tilfældigt gæt. Forestil dig, at modellen forudsiger alle husstande med indkomst lavere end 50K, så har modellen en nøjagtighed på 70 procent. Ved en nærmere analyse kan du se forudsigelsen og tilbagekaldelsen er ret lav.
Trin 4) Forbedre modellen
Nu hvor du har en benchmark-model, kan du prøve at forbedre den, det vil sige øge nøjagtigheden. I det forrige selvstudie lærte du, hvordan du forbedrer forudsigelseskraften med et interaktionsudtryk. I denne øvelse vil du gense denne idé ved at tilføje et polynomielt udtryk til regressionen.
Polynomiel regression er medvirkende, når der er ikke-linearitet i dataene. Der er to måder at fange ikke-linearitet i dataene.
- Tilføj polynomieled
- Bucketize den kontinuerlige variabel til en kategorisk variabel
Polynomisk udtryk
Fra billedet nedenfor kan du se, hvad en polynomiel regression er. Det er en ligning med X-variable med forskellig styrke. En andengrads polynomiel regression har to variable, X og X i anden. Tredje grad har tre variabler, X, X2, og X3
Nedenfor har vi konstrueret en graf med to variable, X og Y. Det er indlysende, at sammenhængen ikke er lineær. Hvis vi tilføjer en lineær regression, kan vi se, at modellen ikke er i stand til at fange mønsteret (venstre billede).
Se nu på det venstre billede fra billedet nedenfor, vi tilføjede fem-led til regressionen (det vil sige y=x+x2+x3+x4+x5. Modellen fanger nu mønsteret langt bedre. Dette er kraften i polynomiel regression.
Lad os gå tilbage til vores eksempel. Alder er ikke i et lineært forhold til indkomst. Den tidlige alder kan have en flad indkomst tæt på nul, fordi børn eller unge ikke arbejder. Så stiger den i den erhvervsaktive alder og falder under pensioneringen. Det er typisk en omvendt U-form. En måde at fange dette mønster på er ved at tilføje en potens to til regressionen.
Lad os se, om det øger nøjagtigheden.
Du skal tilføje denne nye funktion til datasættet og på listen over kontinuerlige funktioner.
Du tilføjer den nye variabel i tog- og testdatasættet, så det er mere bekvemt at skrive en funktion.
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
Funktionen har 3 argumenter:
- df_t: definer træningssættet
- df_te: definer testsættet
- var_name = 'alder': Definer den variabel, der skal transformeres
Du kan bruge objektet pow(2) til at kvadre den variable alder. Bemærk, at den nye variabel hedder 'ny'
Nu hvor funktionen square_var er skrevet, kan du oprette de nye datasæt.
df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')
Som du kan se, har det nye datasæt endnu en funktion.
print(df_train_new.shape, df_test_new.shape) (32561, 16) (16281, 16)
Den kvadratiske variabel kaldes ny i datasættet. Du skal tilføje det til listen over kontinuerlige funktioner.
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]
Bemærk at du har ændret mappen til grafen. Du kan ikke træne forskellige modeller i den samme mappe. Det betyder, at du skal ændre stien til argumentet model_dir. Hvis du ikke gør det, vil TensorFlow give en fejl.
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)
Nu hvor klassificereren er designet med det nye datasæt, kan du træne 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 variabel forbedrede nøjagtigheden fra 0.76 til 0.79. Lad os se, om du kan gøre det bedre ved at kombinere bucketization og interaktionsudtryk sammen.
Bucketization og interaktion
Som du så før, er en lineær klassifikator ikke i stand til at fange aldersindkomstmønsteret korrekt. Det er fordi den lærer en enkelt vægt for hver funktion. For at gøre det nemmere for klassificereren er én ting, du kan gøre, at indsætte funktionen. Bucking omdanner en numerisk funktion til flere bestemte, baseret på det interval, den falder ind i, og hver af disse nye funktioner angiver, om en persons alder falder inden for dette interval.
Med disse nye funktioner kan den lineære model fange forholdet ved at lære forskellige vægte for hver spand.
I TensorFlow gøres det med bucketized_column. Du skal tilføje rækken af værdier i grænserne.
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 ved allerede, at alder er ikke-lineær med indkomst. En anden måde at forbedre modellen på er gennem interaktion. Med TensorFlows ord er det funktionskrydsning. Featurekrydsning er en måde at skabe nye funktioner, der er kombinationer af eksisterende, hvilket kan være nyttigt for en lineær klassifikator, der ikke kan modellere interaktioner mellem funktioner.
Du kan nedbryde alder med en anden funktion som uddannelse. Det vil sige, at nogle grupper sandsynligvis har en høj indkomst og andre lav (tænk på den ph.d.-studerende).
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 at oprette en krydselementkolonne bruger du crossed_column med variablerne til at krydse i en parentes. Hash_bucket_size angiver de maksimale krydsningsmuligheder. For at skabe interaktion mellem variabler (mindst én variabel skal være kategorisk), kan du bruge tf.feature_column.crossed_column. For at bruge dette objekt skal du tilføje variablen til at interagere i firkantet parentes og et andet argument, bøttestørrelsen. Spandstørrelsen er det maksimale antal mulige grupper inden for en variabel. Her sætter du den til 1000 da du ikke kender det præcise antal grupper
age_buckets skal kvadreres før for at tilføje det til funktionskolonnerne. Du tilføjer også de nye funktioner til egenskabskolonnerne 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)
Produktion
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 at estimere den nye model og se, om den forbedrer nøjagtigheden.
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øjagtighedsniveau er 83.58 procent. Det er fire procent højere end den tidligere model.
Til sidst kan du tilføje en regulariseringsterm for at forhindre overfitting.
Trin 5) Hyperparameter: Lasso & Ridge
Din model kan lide under overmontering or undertilpasning.
- Overfitting: Modellen er ikke i stand til at generalisere forudsigelsen til nye data
- Undertilpasning: Modellen er ikke i stand til at fange mønsteret af dataene. dvs. lineær regression, når dataene er ikke-lineære
Når en model har mange parametre og en relativt lav mængde data, fører det til dårlige forudsigelser. Forestil dig, at én gruppe kun har tre observationer; modellen vil beregne en vægt for denne gruppe. Vægten bruges til at lave en forudsigelse; hvis observationerne af testsættet for denne særlige gruppe er helt anderledes end træningssættet, vil modellen lave en forkert forudsigelse. Under evalueringen med træningssættet er nøjagtigheden god, men ikke god med testsættet, fordi de beregnede vægte ikke er den rigtige til at generalisere mønsteret. I dette tilfælde giver den ikke en rimelig forudsigelse om usete data.
For at forhindre overfitting giver regularisering dig muligheder for at kontrollere en sådan kompleksitet og gøre den mere generaliserbar. Der er to regulariseringsteknikker:
- L1: Lasso
- L2: Ryg
I TensorFlow kan du tilføje disse to hyperparametre i optimizeren. For eksempel, jo højere hyperparameter L2 er, har vægten en tendens til at være meget lav og tæt på nul. Den tilpassede linje vil være meget flad, mens en L2 tæt på nul betyder, at vægtene er tæt på den regulære lineære regression.
Du kan selv prøve de forskellige værdier af hyperparametrene og se, om du kan øge nøjagtighedsniveauet.
Bemærk at hvis du ændrer hyperparameteren, skal du slette mappen ongoing/train4 ellers starter modellen med den tidligere trænede model.
Lad os se, hvordan er nøjagtigheden med hypen
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))
UDGANG
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)
UDGANG
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)
Produktion
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 hyperparameter øger du nøjagtighedsmålingerne en smule. I den næste tutorial vil du lære, hvordan du forbedrer en lineær klassificering ved hjælp af en kernemetode.
Resumé
For at træne en model skal du:
- Definer funktionerne: Uafhængige variabler: X
- Definer etiketten: Afhængig variabel: y
- Konstruer et tog/testsæt
- Definer startvægten
- Definer tabsfunktionen: MSE
- Optimer modellen: Gradient descent
- Definere:
- Læringsgrad
- Antal epoker
- Batch størrelse
- Antal klasse
I dette selvstudie lærte du, hvordan du bruger API'en på højt niveau til en lineær regressionsklassifikator. Du skal definere:
- Funktionskolonner. Hvis kontinuerlig: tf.feature_column.numeric_column(). Du kan udfylde en liste med python-listeforståelse
- Estimatoren: tf.estimator.LinearClassifier(feature_columns, model_dir, n_classes = 2)
- En funktion til at importere data, batchstørrelse og epoke: input_fn()
Derefter er du klar til at træne, evaluere og lave en forudsigelse med train(), evaluate() og predict()
For at forbedre modellens ydeevne kan du:
- Brug polynomiel regression
- Interaktionsudtryk: tf.feature_column.crossed_column
- Tilføj regulariseringsparameter