Binär klassificering i TensorFlow: Linjärt klassificeringsexempel

Innehållsförteckning:

Anonim

De två vanligaste övervakade inlärningsuppgifterna är linjär regression och linjär klassificering. Linjär regression förutsäger ett värde medan den linjära klassificeringen förutsäger en klass. Denna handledning fokuserar på Linear Classifier.

Vad är linjär klassificering?

En linjär klassificerare i maskininlärning är en metod för att hitta ett objekts klass baserat på dess egenskaper för statistisk klassificering. Det fattar klassificeringsbeslut baserat på värdet av en linjär kombination av objektets egenskaper. Linjär klassificering används i praktiska problem som dokumentklassificering och problem med många variabler.

Klassificeringsproblem utgör ungefär 80 procent av maskininlärningsuppgiften. Klassificering syftar till att förutsäga sannolikheten för varje klass med en uppsättning ingångar. Etiketten (dvs. den beroende variabeln) är ett diskret värde, kallat en klass.

  1. Om etiketten bara har två klasser är inlärningsalgoritmen en binär klassificerare.
  2. Multiklassklassificering hanterar etiketter med mer än två klasser.

Till exempel är ett typiskt binärt klassificeringsproblem att förutsäga sannolikheten för att en kund gör ett andra köp. Förutse vilken typ av djur som visas på en bild är ett klassificeringsproblem i flera klasser, eftersom det finns mer än två varianter av djur.

Den teoretiska delen av denna handledning sätter primärt fokus på binärklassen. Du kommer att lära dig mer om multiklassutmatningsfunktionen i en framtida handledning.

I den här handledningen lär du dig

  • Vad är linjär klassificering?
  • Hur fungerar binär klassificering?
  • Hur mäter jag prestandan hos Linear Classifier?
  • Noggrannhet
  • Förvirringsmatris
  • Precision och känslighet
  • Linjär klassificerare med TensorFlow
  • Steg 1) Importera data
  • Steg 2) Datakonvertering
  • Steg 3) Träna klassificeraren
  • Steg 4) Förbättra modellen
  • Steg 5) Hyperparameter: Lasso & Ridge

Hur fungerar binär klassificering?

Du lärde dig i föregående handledning att en funktion består av två typer av variabler, en beroende variabel och en uppsättning funktioner (oberoende variabler). I den linjära regressionen är en beroende variabel ett reellt tal utan intervall. Det primära målet är att förutsäga dess värde genom att minimera medelkvadratfelet.

För TensorFlow Binary Classifier kan etiketten ha haft två möjliga heltalsvärden. I de flesta fall är det antingen [0,1] eller [1,2]. Målet är till exempel att förutsäga om en kund kommer att köpa en produkt eller inte. Etiketten definieras enligt följande:

  • Y = 1 (kund köpte produkten)
  • Y = 0 (kunden köper inte produkten)

Modellen använder funktionerna X för att klassificera varje kund i den mest troliga klassen han tillhör, nämligen potentiell köpare eller inte.

Sannolikheten för framgång beräknas med logistisk regression . Algoritmen beräknar en sannolikhet baserat på funktionen X och förutsäger en framgång när denna sannolikhet är över 50 procent. Mer formellt beräknas sannolikheten enligt nedanstående TensorFlow binär klassificeringsexempel:

där 0 är uppsättningen vikter, funktionerna och b-förspänningen.

Funktionen kan sönderdelas i två delar:

  • Den linjära modellen
  • Den logistiska funktionen

Linjär modell

Du är redan bekant med hur vikterna beräknas. Vikt beräknas med hjälp av en punktprodukt: Y är en linjär funktion av alla funktioner x i . Om modellen inte har funktioner är förutsägelsen lika med förspänningen, b.

Vikterna anger riktningen för korrelationen mellan funktionerna x i och etiketten y. En positiv korrelation ökar sannolikheten för den positiva klassen medan en negativ korrelation leder sannolikheten närmare 0, (dvs. negativ klass).

Den linjära modellen returnerar endast reellt tal, vilket är oförenligt med sannolikhetsmåttet för området [0,1]. Den logistiska funktionen krävs för att konvertera den linjära modellutgången till en sannolikhet,

Logistisk funktion

Den logistiska funktionen, eller sigmoidfunktionen, har en S-form och utgången för denna funktion är alltid mellan 0 och 1.

Logistisk funktionsexempel

Det är lätt att ersätta utsignalen från den linjära regressionen till sigmoidfunktionen. Det resulterar i ett nytt nummer med en sannolikhet mellan 0 och 1.

Klassificeraren kan förvandla sannolikheten till en klass

  • Värden mellan 0 och 0,49 blir klass 0
  • Värden mellan 0,5 och 1 blir klass 1

Hur mäter jag prestandan hos Linear Classifier?

Noggrannhet

En klassificerings totala prestanda mäts med noggrannhetsmåttet. Noggrannhet samlar in alla korrekta värden dividerat med det totala antalet observationer. Exempelvis betyder ett noggrannhetsvärde på 80 procent att modellen är korrekt i 80 procent av fallen.

Mät prestanda för linjär klassificering med hjälp av noggrannhet

Du kan notera en brist med detta mått, särskilt för obalansklassen. En obalansuppsättning uppstår när antalet observationer per grupp inte är lika. Låt oss säga; du försöker klassificera en sällsynt händelse med en logistisk funktion. Föreställ dig att klassificatorn försöker uppskatta en patients död efter en sjukdom. I uppgifterna går 5 procent av patienterna bort. Du kan träna en klassificerare för att förutsäga antalet dödsfall och använda noggrannhetsmätet för att utvärdera föreställningarna. Om klassificatorn förutsäger 0 dödsfall för hela datasetet kommer det att vara korrekt i 95 procent av fallet.

Förvirringsmatris

Ett bättre sätt att bedöma prestandan hos en klassificerare är att titta på förvirringsmatrisen.

Mät prestanda för Linear Classifier med Confusion matrix

Förvirringsmatrisen visualiserar noggrannheten för en klassificerare genom att jämföra de faktiska och förutsagda klasserna som visas i ovanstående exempel på linjär klassificering. Den binära förvirringsmatrisen består av rutor:

  • TP: True Positive: Förutspådda värden förutses korrekt som faktiska positiva
  • FP: Förutspådda värden förutsagde felaktigt ett faktiskt positivt. dvs negativa värden förutsagda som positiva
  • FN: Falskt negativt: Positiva värden förutsagda som negativa
  • TN: True Negative: Förutsägda värden förutses korrekt som faktiska negativa

Från förvirringsmatrisen är det enkelt att jämföra den aktuella klassen och den förutsagda klassen.

Precision och känslighet

Förvirringsmatrisen ger en god inblick i det verkliga positiva och falska positiva. I vissa fall är det att föredra att ha en mer kortfattad statistik.

Precision

Precisionsmätvärdet visar noggrannheten i den positiva klassen. Den mäter hur sannolikt förutsägelsen av den positiva klassen är korrekt.

Den maximala poängen är 1 när klassificatorn klassificerar alla positiva värden perfekt. Precision ensam är inte särskilt bra eftersom den ignorerar den negativa klassen. Mätvärdet är vanligtvis ihopkopplat med minnet. Recall kallas också känslighet eller sann positiv hastighet.

Känslighet

Känslighet beräknar förhållandet mellan positiva klasser som detekterats korrekt. Denna mätning ger hur bra modellen är att känna igen en positiv klass.

Linjär klassificerare med TensorFlow

För den här handledningen använder vi folkräkningsdataset. Syftet är att använda variablerna i folkräkningsdatasetet för att förutsäga inkomstnivån. Observera att inkomsten är en binär variabel

  • med värdet 1 om inkomsten> 50k
  • 0 om inkomst <50k.

Denna variabel är din etikett

Denna dataset innehåller åtta kategoriska variabler:

  • arbetsplats
  • utbildning
  • äktenskaplig
  • ockupation
  • relation
  • lopp
  • sex
  • hemland

dessutom sex kontinuerliga variabler:

  • ålder
  • fnlwgt
  • utbildning_num
  • kapitalvinsten
  • kapitalförlust
  • timmar_vecka

Genom detta TensorFlow-klassificeringsexempel kommer du att förstå hur du tränar linjära TensorFlow-klassificerare med TensorFlow-beräknaren och hur du kan förbättra noggrannhetsmätvärdet.

Vi fortsätter enligt följande:

  • Steg 1) Importera data
  • Steg 2) Datakonvertering
  • Steg 3) Träna klassificeraren
  • Steg 4) Förbättra modellen
  • Steg 5) Hyperparameter: Lasso & Ridge

Steg 1) Importera data

Du importerar först biblioteken som användes under självstudien.

import tensorflow as tfimport pandas as pd 

Därefter importerar du data från UCI-arkivet och definierar kolumnnamnen. Du använder COLUMNS för att namnge kolumnerna i en pandadataram.

Observera att du tränar klassificeraren med en Pandas-dataram.

## Define path dataCOLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital','occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss','hours_week', 'native_country', 'label']PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"PATH_test = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test"

De data som lagras online är redan uppdelade mellan en tågsats och testuppsättning.

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)

Tågset innehåller 32 561 observationer och testset 16 281

print(df_train.shape, df_test.shape)print(df_train.dtypes)(32561, 15) (16281, 15)age int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel objectdtype: object

Tensorflow kräver ett booleskt värde för att träna klassificeraren. Du måste kasta värdena från sträng till heltal. Etiketten lagras som ett objekt, men du måste konvertera den till ett numeriskt värde. Koden nedan skapar en ordlista med värdena som ska konverteras och slingras över kolumnobjektet. Observera att du utför denna operation två gånger, en för tågtestet, en för testuppsättningen

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 tågdata finns 24720 inkomster lägre än 50 000 och 7841 ovan. Förhållandet är nästan detsamma för testuppsättningen. Se denna handledning om Facetter för mer.

print(df_train["label"].value_counts())### The model will be correct in atleast 70% of the caseprint(df_test["label"].value_counts())## Unbalanced labelprint(df_train.dtypes)0 247201 7841Name: label, dtype: int640 124351 3846Name: label, dtype: int64age int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel int64dtype: object

Steg 2) Datakonvertering

Några steg krävs innan du tränar en linjär klassificering med Tensorflow. Du måste förbereda de funktioner som ska inkluderas i modellen. I benchmark-regressionen kommer du att använda originaldata utan att använda någon transformation.

Uppskattaren måste ha en lista över funktioner för att träna modellen. Därför kräver kolonnens data att konverteras till en tensor.

En bra praxis är att definiera två listor med funktioner baserat på deras typ och sedan skicka dem i funktionskolumnerna i uppskattaren.

Du börjar med att konvertera kontinuerliga funktioner och definiera sedan en hink med kategoriska data.

Datafunktionens funktioner har två format:

  • Heltal
  • Objekt

Varje funktion listas i de två följande variablerna enligt deras typer.

## Add features to the bucket:### Define continuous listCONTI_FEATURES = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']### Define the categorical listCATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']

Funktionskolumnen är utrustad med ett objekt numerisk_kolumn som hjälper till att omvandla de kontinuerliga variablerna till tensor. I koden nedan konverterar du alla variabler från CONTI_FEATURES till en tensor med ett numeriskt värde. Detta är obligatoriskt för att konstruera modellen. Alla oberoende variabler måste konverteras till rätt typ av tensor.

Nedan skriver vi en kod så att du kan se vad som händer bakom feature_column.numeric_column. Vi kommer att skriva ut det konverterade värdet för ålder Det är för förklarande ändamål, det finns därför inget behov av att förstå pythonkoden. Du kan hänvisa till den officiella dokumentationen för att förstå koderna.

def print_transformation(feature = "age", continuous = True, size = 2):#X = fc.numeric_column(feature)## Create feature namefeature_names = [feature]## Create dict with the datad = dict(zip(feature_names, [df_train[feature]]))## Convert ageif continuous == True:c = tf.feature_column.numeric_column(feature)feature_columns = [c]else:c = tf.feature_column.categorical_column_with_hash_bucket(feature, hash_bucket_size=size)c_indicator = tf.feature_column.indicator_column(c)feature_columns = [c_indicator]## Use input_layer to print the valueinput_layer = tf.feature_column.input_layer(features=d,feature_columns=feature_columns)## Create lookup tablezero = tf.constant(0, dtype=tf.float32)where = tf.not_equal(input_layer, zero)## Return lookup tbleindices = tf.where(where)values = tf.gather_nd(input_layer, indices)## Initiate graphsess = tf.Session()## Print valueprint(sess.run(input_layer))print_transformation(feature = "age", continuous = True)[[39.][50.][38.]… [58.][22.][52.]]

Värdena är exakt samma som i df_train

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

Enligt TensorFlow-dokumentationen finns det olika sätt att konvertera kategoriska data. Om ordlistan för en funktion är känd och inte har många värden är det möjligt att skapa den kategoriska kolumnen med categorical_column_with_vocabulary_list. Den tilldelar alla unika ordförrådslistor ett ID.

Till exempel, om en variabelstatus har tre distinkta värden:

  • Make
  • Fru
  • Enda

Då tilldelas tre ID. Till exempel kommer Make att ha ID 1, Wife ID 2 och så vidare.

I illustrationssyfte kan du använda den här koden för att konvertera en objektvariabel till en kategorisk kolumn i TensorFlow.

Funktionskön kan bara ha två värden: man eller kvinna. När vi konverterar funktionen kön skapar Tensorflow två nya kolumner, en för man och en för kvinna. Om könen är lika med hane kommer den nya kolumnen hane att vara lika med 1 och kvinna till 0. Detta exempel visas i tabellen nedan:

rader

sex

efter transformation

manlig

kvinna

1

manlig

=>

1

0

2

manlig

=>

1

0

3

kvinna

=>

0

1

I tensorflöde:

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

Nedan har vi lagt till Python-kod för att skriva ut kodningen. Återigen behöver du inte förstå koden, syftet är att se omvandlingen

Ett snabbare sätt att transformera data är dock att använda metoden categorical_column_with_hash_bucket. Det är användbart att ändra strängvariabler i en gles matris. En gles matris är en matris med mestadels noll. Metoden tar hand om allt. Du behöver bara ange antalet skopor och nyckelkolumnen. Antalet hinkar är det maximala antalet grupper som Tensorflow kan skapa. Nyckelkolumnen är helt enkelt namnet på den kolumn som ska konverteras.

I koden nedan skapar du en slinga över alla kategoriska funktioner.

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

Steg 3) Träna klassificeraren

TensorFlow tillhandahåller för närvarande en estimator för linjär regression och linjär klassificering.

  • Linjär regression: LinearRegressor
  • Linjär klassificering: LinearClassifier

Syntaxen för den linjära klassificeraren är densamma som i handledningen om linjär regression förutom ett argument, n_class. Du måste definiera funktionskolumnen, modellkatalogen och jämföra med linjär regressor; du har definierat antalet klasser. För en logit-regression är antalet klasser lika med 2.

Modellen beräknar vikterna för kolumnerna i kontinuerliga_funktioner och kategoriska_funktioner.

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':, '_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 när klassificeraren är definierad kan du skapa inmatningsfunktionen. Metoden är densamma som i linjär regressorhandledning. Här använder du en batchstorlek på 128 och du blandar data.

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 skapar en funktion med de argument som krävs av den linjära uppskattaren, dvs antal epoker, antal satser och blandar datauppsättningen eller anteckningen. Eftersom du använder Pandas-metoden för att skicka data till modellen måste du definiera X-variablerna som en pandadataram. Observera att du slingrar över all data som är lagrad i FUNKTIONER.

Låt oss träna modellen med objektmodellen. Train. Du använder den tidigare definierade funktionen för att mata modellen med lämpliga värden. Observera att du ställer in batchstorleken till 128 och antalet epoker till None. Modellen kommer att utbildas i tusen steg.

model.train(input_fn=get_input_fn(df_train,num_epochs=None,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Create CheckpointSaverHook.INFO:tensorflow: Graph was finalized.INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Saving checkpoints for 1 into ongoing/train/model.ckpt.INFO:tensorflow:loss = 88.722855, step = 1INFO:tensorflow:global_step/sec: 65.8282INFO:tensorflow:loss = 52583.64, step = 101 (1.528 sec)INFO:tensorflow:global_step/sec: 118.386INFO:tensorflow:loss = 25203.816, step = 201 (0.837 sec)INFO:tensorflow:global_step/sec: 110.542INFO:tensorflow:loss = 54924.312, step = 301 (0.905 sec)INFO:tensorflow:global_step/sec: 199.03INFO:tensorflow:loss = 68509.31, step = 401 (0.502 sec)INFO:tensorflow:global_step/sec: 167.488INFO:tensorflow:loss = 9151.754, step = 501 (0.599 sec)INFO:tensorflow:global_step/sec: 220.155INFO:tensorflow:loss = 34576.06, step = 601 (0.453 sec)INFO:tensorflow:global_step/sec: 199.016INFO:tensorflow:loss = 36047.117, step = 701 (0.503 sec)INFO:tensorflow:global_step/sec: 197.531INFO:tensorflow:loss = 22608.148, step = 801 (0.505 sec)INFO:tensorflow:global_step/sec: 208.479INFO:tensorflow:loss = 22201.918, step = 901 (0.479 sec)INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train/model.ckpt.INFO:tensorflow:Loss for final step: 5444.363.

Observera att förlusten därefter minskade under de senaste 100 stegen, dvs. från 901 till 1000.

Den slutliga förlusten efter tusen iterationer är 5444. Du kan uppskatta din modell på testuppsättningen och se prestandan. För att utvärdera din modells prestanda måste du använda objektet utvärdera. Du matar modellen med testuppsättningen och ställer in antalet epoker till 1, dvs. data kommer bara att gå till modellen en gång.

model.evaluate(input_fn=get_input_fn(df_test,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:22INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train/model.ckpt-1000INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Evaluation [100/1000]INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:23INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7615626, accuracy_baseline = 0.76377374, auc = 0.63300294, auc_precision_recall = 0.50891197, average_loss = 47.12155, global_step = 1000, label/mean = 0.23622628, loss = 5993.6406, precision = 0.49401596, prediction/mean = 0.18454961, recall = 0.38637546{'accuracy': 0.7615626,'accuracy_baseline': 0.76377374,'auc': 0.63300294,'auc_precision_recall': 0.50891197,'average_loss': 47.12155,'global_step': 1000,'label/mean': 0.23622628,'loss': 5993.6406,'precision': 0.49401596,'prediction/mean': 0.18454961,'recall': 0.38637546}

TensorFlow returnerar alla mätvärden du lärde dig i den teoretiska delen. Utan överraskning är noggrannheten stor på grund av den obalanserade etiketten. Egentligen presterar modellen lite bättre än en slumpmässig gissning. Föreställ dig att modellen förutsäger alla hushåll med en inkomst som är lägre än 50 000, då har modellen en noggrannhet på 70 procent. Vid en närmare analys kan du se att förutsägelsen och återkallelsen är ganska låga.

Steg 4) Förbättra modellen

Nu när du har en standardmodell kan du försöka förbättra den, det vill säga öka noggrannheten. I föregående handledning lärde du dig hur du kan förbättra förutsägelsekraften med en interaktionsterm. I den här självstudien kommer du att återvända till denna idé genom att lägga till en polynomterm i regressionen.

Polynomregression är avgörande när det finns icke-linjäritet i data. Det finns två sätt att fånga icke-linjäritet i data.

  • Lägg till polynom
  • Bucketize den kontinuerliga variabeln till en kategorisk variabel

Polynom

Från bilden nedan kan du se vad en polynomregression är. Det är en ekvation med X-variabler med olika effekt. En andra graders polynomregression har två variabler, X och X i kvadrat. Tredje graden har tre variabler, X, X 2 och X 3

Vad är polynomregression

Nedan konstruerade vi en graf med två variabler, X och Y. Det är uppenbart att förhållandet inte är linjärt. Om vi ​​lägger till en linjär regression kan vi se att modellen inte kan fånga mönstret (vänster bild).

Titta nu på den vänstra bilden från bilden nedan, vi lade till fem-term till regressionen (det vill säga y = x + x 2 + x 3 + x 4 + x 5. Modellen fångar nu mönstret bättre. Detta är kraften i polynomregression.

Låt oss gå tillbaka till vårt exempel. Ålder står inte i linjär relation med inkomst. Tidig ålder kan ha en platt inkomst nära noll eftersom barn eller ungdomar inte arbetar. Då ökar den i arbetsåldern och minskar under pensionen. Det är vanligtvis en Inversed-U-form. Ett sätt att fånga detta mönster är att lägga till en kraft två till regressionen.

Låt oss se om det ökar noggrannheten.

Du måste lägga till den här nya funktionen i datasetet och i listan över kontinuerliga funktioner.

Du lägger till den nya variabeln i tåg- och testdatasetet, så det är bekvämare att skriva 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 tre argument:

  • df_t: definiera träningsuppsättningen
  • df_te: definiera testuppsättningen
  • var_name = 'age': Definiera variabeln som ska transformeras

Du kan använda objektet pow (2) för att kvadrera variabelåldern. Observera att den nya variabeln heter 'ny'

Nu när funktionen square_var är skriven kan du skapa de nya datamängderna.

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

Som du kan se har den nya datasetet en funktion till.

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

Den kvadratiska variabeln kallas ny i datasetet. Du måste lägga till den i listan över kontinuerliga 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]

Observera att du ändrade katalogen för diagrammet. Du kan inte träna olika modeller i samma katalog. Det betyder att du måste ändra sökvägen till argumentet model_dir. Om du inte gör det kommer TensorFlow att kasta ett fel.

model_1 = tf.estimator.LinearClassifier(model_dir="ongoing/train1",feature_columns=categorical_features+ continuous_features_new)
INFO:tensorflow:Using default config.INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec':, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}FEATURES_NEW = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country', 'new']def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):return tf.estimator.inputs.pandas_input_fn(x=pd.DataFrame({k: data_set[k].values for k in FEATURES_NEW}),y = pd.Series(data_set[LABEL].values),batch_size=n_batch,num_epochs=num_epochs,shuffle=shuffle)

Nu när klassificeraren är utformad med den nya datasetet kan du träna och utvärdera 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 = 1INFO:tensorflow:global_step/sec: 81.487INFO:tensorflow:loss = 70077.66, step = 101 (1.228 sec)INFO:tensorflow:global_step/sec: 111.169INFO:tensorflow:loss = 49522.082, step = 201 (0.899 sec)INFO:tensorflow:global_step/sec: 128.91INFO:tensorflow:loss = 107120.57, step = 301 (0.776 sec)INFO:tensorflow:global_step/sec: 132.546INFO:tensorflow:loss = 12814.152, step = 401 (0.755 sec)INFO:tensorflow:global_step/sec: 162.194INFO:tensorflow:loss = 19573.898, step = 501 (0.617 sec)INFO:tensorflow:global_step/sec: 204.852INFO:tensorflow:loss = 26381.986, step = 601 (0.488 sec)INFO:tensorflow:global_step/sec: 188.923INFO:tensorflow:loss = 23417.719, step = 701 (0.529 sec)INFO:tensorflow:global_step/sec: 192.041INFO:tensorflow:loss = 23946.049, step = 801 (0.521 sec)INFO:tensorflow:global_step/sec: 197.025INFO:tensorflow:loss = 3309.5786, step = 901 (0.507 sec)INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train1/model.ckpt.INFO:tensorflow:Loss for final step: 28861.898.
model_1.evaluate(input_fn=get_input_fn(df_test_new,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:37INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train1/model.ckpt-1000INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Evaluation [100/1000]INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:39INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7944229, accuracy_baseline = 0.76377374, auc = 0.6093755, auc_precision_recall = 0.54885805, average_loss = 111.0046, global_step = 1000, label/mean = 0.23622628, loss = 14119.265, precision = 0.6682401, prediction/mean = 0.09116262, recall = 0.2576703{'accuracy': 0.7944229,'accuracy_baseline': 0.76377374,'auc': 0.6093755,'auc_precision_recall': 0.54885805,'average_loss': 111.0046,'global_step': 1000,'label/mean': 0.23622628,'loss': 14119.265,'precision': 0.6682401,'prediction/mean': 0.09116262,'recall': 0.2576703}

Den kvadrerade variabeln förbättrade noggrannheten från 0,76 till 0,79. Låt oss se om du kan göra bättre genom att kombinera bucketization och interaktionsterm tillsammans.

Bucketization och interaktion

Som du såg tidigare kan en linjär klassificering inte fånga åldersinkomstmönstret korrekt. Det beror på att det lär sig en enda vikt för varje funktion. För att göra det enklare för klassificeraren är en sak du kan göra att skopa funktionen. Bucketing förvandlar en numerisk funktion till flera vissa baserat på det intervall den faller inom, och var och en av dessa nya funktioner indikerar om en persons ålder faller inom det intervallet.

Med dessa nya funktioner kan den linjära modellen fånga förhållandet genom att lära sig olika vikter för varje hink.

I TensorFlow görs det med bucketized_column. Du måste lägga till värdet i gränserna.

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 redan att ålder är icke-linjär med inkomst. Ett annat sätt att förbättra modellen är genom interaktion. I ordet TensorFlow är det funktionsövergång. Funktionskorsning är ett sätt att skapa nya funktioner som är kombinationer av befintliga, vilket kan vara till hjälp för en linjär klassificering som inte kan modellera interaktioner mellan funktioner.

Du kan bryta ner åldern med en annan funktion som utbildning. Det vill säga, vissa grupper kommer sannolikt att ha hög inkomst och andra låga (tänk på doktorandstudenten).

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

För att skapa en korsfunktionskolumn använder du korsad kolumn med variablerna för att korsa inom en parentes. Hash_bucket_size indikerar de maximala korsningsmöjligheterna. För att skapa interaktion mellan variabler (minst en variabel måste vara kategorisk) kan du använda tf.feature_column.crossed_column. För att använda det här objektet måste du lägga till variabeln som ska interagera i ett hakparentes och ett andra argument, skopstorleken. Skopstorleken är det maximala antalet grupper som är möjligt inom en variabel. Här ställer du in det på 1000 eftersom du inte vet det exakta antalet grupper

age_buckets måste kvadreras innan det läggs till i funktionskolumnerna. Du lägger också till de nya funktionerna i funktionskolumnerna och förbereder uppskattaren

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': , '_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 är redo att uppskatta den nya modellen och se om den förbättrar noggrannheten.

model_imp.train(input_fn=get_input_fn(df_train_new,num_epochs=None,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Create CheckpointSaverHook.INFO:tensorflow:Graph was finalized.INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Saving checkpoints for 1 into ongoing/train3/model.ckpt.INFO:tensorflow:loss = 88.722855, step = 1INFO:tensorflow:global_step/sec: 94.969INFO:tensorflow:loss = 50.334488, step = 101 (1.054 sec)INFO:tensorflow:global_step/sec: 242.342INFO:tensorflow:loss = 56.153225, step = 201 (0.414 sec)INFO:tensorflow:global_step/sec: 213.686INFO:tensorflow:loss = 45.792007, step = 301 (0.470 sec)INFO:tensorflow:global_step/sec: 174.084INFO:tensorflow:loss = 37.485672, step = 401 (0.572 sec)INFO:tensorflow:global_step/sec: 191.78INFO:tensorflow:loss = 56.48449, step = 501 (0.524 sec)INFO:tensorflow:global_step/sec: 163.436INFO:tensorflow:loss = 32.528934, step = 601 (0.612 sec)INFO:tensorflow:global_step/sec: 164.347INFO:tensorflow:loss = 37.438057, step = 701 (0.607 sec)INFO:tensorflow:global_step/sec: 154.274INFO:tensorflow:loss = 61.1075, step = 801 (0.647 sec)INFO:tensorflow:global_step/sec: 189.14INFO:tensorflow:loss = 44.69645, step = 901 (0.531 sec)INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train3/model.ckpt.INFO:tensorflow:Loss for final step: 44.18133.
model_imp.evaluate(input_fn=get_input_fn(df_test_new,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:52INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train3/model.ckpt-1000INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Evaluation [100/1000]INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:54INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.8358209, accuracy_baseline = 0.76377374, auc = 0.88401634, auc_precision_recall = 0.69599575, average_loss = 0.35122654, global_step = 1000, label/mean = 0.23622628, loss = 44.67437, precision = 0.68986726, prediction/mean = 0.23320661, recall = 0.55408216{'accuracy': 0.8358209,'accuracy_baseline': 0.76377374,'auc': 0.88401634,'auc_precision_recall': 0.69599575,'average_loss': 0.35122654,'global_step': 1000,'label/mean': 0.23622628,'loss': 44.67437,'precision': 0.68986726,'prediction/mean': 0.23320661,'recall': 0.55408216}

Den nya noggrannhetsnivån är 83,58 procent. Det är fyra procent högre än den tidigare modellen.

Slutligen kan du lägga till en ordning för att förhindra överanpassning.

Steg 5) Hyperparameter: Lasso & Ridge

Din modell kan drabbas av över- eller underutrustning .

  • Övermontering: Modellen kan inte generalisera förutsägelsen till nya data
  • Underfitting: Modellen kan inte fånga datamönstret. dvs. linjär regression när data är icke-linjära

När en modell har många parametrar och en relativt låg datamängd leder det till dåliga förutsägelser. Tänk dig att en grupp bara har tre observationer; modellen beräknar en vikt för denna grupp. Vikten används för att göra en förutsägelse; om observationerna av testuppsättningen för denna speciella grupp skiljer sig helt från träningsuppsättningen, kommer modellen att göra en fel förutsägelse. Under utvärderingen med träningssatsen är noggrannheten bra, men inte bra med testuppsättningen, eftersom de beräknade vikterna inte är sanna för att generalisera mönstret. I det här fallet gör det inte en rimlig förutsägelse på osedda data.

För att förhindra övermontering ger regularisering dig möjligheten att kontrollera för sådan komplexitet och göra den mer generaliserad. Det finns två regleringstekniker:

  • L1: Lasso
  • L2: ås

I TensorFlow kan du lägga till dessa två hyperparametrar i optimeraren. Till exempel, ju högre hyperparameter L2 tenderar vikten att vara mycket låg och nära noll. Den monterade linjen kommer att vara väldigt plan, medan en L2 nära noll innebär att vikterna ligger nära den vanliga linjära regressionen.

Du kan själv pröva hyperparametrarnas olika värde och se om du kan öka noggrannhetsnivån.

Observera att om du byter hyperparameter måste du ta bort mappen pågående / train4 annars kommer modellen att börja med den tidigare utbildade modellen.

Låt oss se hur är noggrannheten med hype

model_regu = tf.estimator.LinearClassifier(model_dir="ongoing/train4", feature_columns=categorical_features+base_columns+education_x_occupation+age_buckets_x_education_x_occupation,optimizer=tf.train.FtrlOptimizer(learning_rate=0.1,l1_regularization_strength=0.9,l2_regularization_strength=5))

OUPUT

INFO:tensorflow:Using default config.INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train4', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': , '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
model_regu.train(input_fn=get_input_fn(df_train_new,num_epochs=None,n_batch = 128,shuffle=False),steps=1000)

OUPUT

INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Create CheckpointSaverHook.INFO:tensorflow:Graph was finalized.INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Saving checkpoints for 1 into ongoing/train4/model.ckpt.INFO:tensorflow:loss = 88.722855, step = 1INFO:tensorflow:global_step/sec: 77.4165INFO:tensorflow:loss = 50.38778, step = 101 (1.294 sec)INFO:tensorflow:global_step/sec: 187.889INFO:tensorflow:loss = 55.38014, step = 201 (0.535 sec)INFO:tensorflow:global_step/sec: 201.895INFO:tensorflow:loss = 46.806694, step = 301 (0.491 sec)INFO:tensorflow:global_step/sec: 217.992INFO:tensorflow:loss = 38.68271, step = 401 (0.460 sec)INFO:tensorflow:global_step/sec: 193.676INFO:tensorflow:loss = 56.99398, step = 501 (0.516 sec)INFO:tensorflow:global_step/sec: 202.195INFO:tensorflow:loss = 33.263622, step = 601 (0.497 sec)INFO:tensorflow:global_step/sec: 216.756INFO:tensorflow:loss = 37.7902, step = 701 (0.459 sec)INFO:tensorflow:global_step/sec: 240.215INFO:tensorflow:loss = 61.732605, step = 801 (0.416 sec)INFO:tensorflow:global_step/sec: 220.336INFO:tensorflow:loss = 46.938225, step = 901 (0.456 sec)INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train4/model.ckpt.INFO:tensorflow:Loss for final step: 43.4942.
model_regu.evaluate(input_fn=get_input_fn(df_test_new,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)

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:07INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train4/model.ckpt-1000INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Evaluation [100/1000]INFO:tensorflow:Finished evaluation at 2018-06-02-08:29:09INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.83833915, accuracy_baseline = 0.76377374, auc = 0.8869794, auc_precision_recall = 0.7014905, average_loss = 0.34691378, global_step = 1000, label/mean = 0.23622628, loss = 44.12581, precision = 0.69720596, prediction/mean = 0.23662092, recall = 0.5579823{'accuracy': 0.83833915,'accuracy_baseline': 0.76377374,'auc': 0.8869794,'auc_precision_recall': 0.7014905,'average_loss': 0.34691378,'global_step': 1000,'label/mean': 0.23622628,'loss': 44.12581,'precision': 0.69720596,'prediction/mean': 0.23662092,'recall': 0.5579823}

Med den här hyperparametern ökar du noggrannhetsmätvärdena. I nästa handledning lär du dig hur du förbättrar en linjär klassificering med en kärnmetod.

Sammanfattning

För att träna en modell måste du:

  • Definiera funktioner: Oberoende variabler: X
  • Definiera etiketten: Beroende variabel: y
  • Konstruera ett tåg / testuppsättning
  • Definiera den ursprungliga vikten
  • Definiera förlustfunktionen: MSE
  • Optimera modellen: Gradient nedstigning
  • Definiera:
    • Inlärningshastighet
    • Antal epoker
    • Satsstorlek
    • Antal klasser

I den här självstudien lärde du dig hur du använder API på hög nivå för en linjär regressionsklassificerare. Du måste definiera:

  1. Funktionskolumner. Om kontinuerlig: tf.feature_column.numeric_column (). Du kan fylla i en lista med pythonlistförståelse
  2. Uppskattaren: tf.estimator.LinearClassifier (feature_column, model_dir, n_classes = 2)
  3. En funktion för att importera data, batchstorlek och epok: input_fn ()

Efter det är du redo att träna, utvärdera och göra en förutsägelse med train (), utvärdera () och förutsäga ()

För att förbättra modellens prestanda kan du:

  • Använd polynomregression
  • Interaktionsterm: tf.feature_column.crossed_column
  • Lägg till normaliseringsparameter