De twee meest voorkomende leertaken onder supervisie zijn lineaire regressie en lineaire classificering. Lineaire regressie voorspelt een waarde, terwijl de lineaire classificator een klasse voorspelt. Deze tutorial is gericht op Linear Classifier.
Wat is lineaire classificatie?
Een lineaire classificatie in machine learning is een methode om de klasse van een object te vinden op basis van de kenmerken voor statistische classificatie. Het neemt een classificatiebeslissing op basis van de waarde van een lineaire combinatie van kenmerken van een object. Lineaire classificator wordt gebruikt bij praktische problemen zoals documentclassificatie en problemen met veel variabelen.
Classificatieproblemen vertegenwoordigen ongeveer 80 procent van de machine learning-taak. Classificatie is gericht op het voorspellen van de waarschijnlijkheid van elke klasse op basis van een reeks inputs. Het label (dwz de afhankelijke variabele) is een discrete waarde, een klasse genaamd.
- Als het label slechts twee klassen heeft, is het leeralgoritme een binaire classificatie.
- Multiclass classifier pakt labels aan met meer dan twee klassen.
Een typisch binair classificatieprobleem is bijvoorbeeld het voorspellen van de waarschijnlijkheid dat een klant een tweede aankoop doet. Voorspel het type dier dat op een foto wordt weergegeven, is een classificatieprobleem met meerdere klassen, aangezien er meer dan twee soorten dieren bestaan.
Het theoretische deel van deze tutorial legt de primaire focus op de binaire klasse. In een toekomstige zelfstudie leert u meer over de functie voor uitvoer met meerdere klassen.
In deze tutorial leer je
- Wat is lineaire classificatie?
- Hoe werkt de binaire classificatie?
- Hoe de prestaties van lineaire classificator te meten?
- Nauwkeurigheid
- Verwarring matrix
- Precisie en gevoeligheid
- Lineaire classificatie met TensorFlow
- Stap 1) Importeer de gegevens
- Stap 2) Dataconversie
- Stap 3) Train de classificatie
- Stap 4) Verbeter het model
- Stap 5) Hyperparameter: Lasso & Ridge
Hoe werkt de binaire classificatie?
Je hebt in de vorige tutorial geleerd dat een functie is samengesteld uit twee soorten variabelen, een afhankelijke variabele en een set features (onafhankelijke variabelen). In de lineaire regressie is een afhankelijke variabele een reëel getal zonder bereik. Het primaire doel is om de waarde ervan te voorspellen door de gemiddelde kwadratische fout te minimaliseren.
Voor TensorFlow Binary Classifier kan het label twee mogelijke gehele getallen hebben gehad. In de meeste gevallen is het ofwel [0,1] of [1,2]. Het doel is bijvoorbeeld om te voorspellen of een klant een product zal kopen of niet. Het label is als volgt gedefinieerd:
- Y = 1 (klant heeft het product gekocht)
- Y = 0 (klant koopt het product niet)
Het model gebruikt de kenmerken X om elke klant te classificeren in de meest waarschijnlijke klasse waartoe hij behoort, namelijk potentiële koper of niet.
De kans op succes wordt berekend met logistische regressie . Het algoritme berekent een kans op basis van kenmerk X en voorspelt een succes wanneer deze kans groter is dan 50 procent. Formeler wordt de kans berekend zoals weergegeven in het onderstaande voorbeeld van TensorFlow binaire classificatie:
waarbij 0 de set gewichten is, de kenmerken en b de bias.
De functie kan in twee delen worden opgesplitst:
- Het lineaire model
- De logistieke functie
Lineair model
U bent al bekend met de manier waarop de gewichten worden berekend. Gewichten worden berekend met behulp van een puntproduct: Y is een lineaire functie van alle kenmerken x i . Als het model geen features heeft, is de voorspelling gelijk aan de bias, b.
De gewichten geven de richting van de correlatie tussen de kenmerken x i en het label y aan. Een positieve correlatie verhoogt de kans op de positieve klasse, terwijl een negatieve correlatie de kans dichter bij 0 brengt (dwz een negatieve klasse).
Het lineaire model retourneert alleen een reëel getal, wat niet consistent is met de waarschijnlijkheidsmaat van bereik [0,1]. De logistieke functie is vereist om de uitvoer van het lineaire model om te zetten in een waarschijnlijkheid,
Logistieke functie
De logistieke functie, of sigmoïde functie, heeft een S-vorm en de output van deze functie ligt altijd tussen 0 en 1.
Het is gemakkelijk om de uitvoer van de lineaire regressie te vervangen door de sigmoïde functie. Het resulteert in een nieuw getal met een kans tussen 0 en 1.
De classifier kan de kans omzetten in een klasse
- Waarden tussen 0 en 0,49 worden klasse 0
- Waarden tussen 0,5 en 1 worden klasse 1
Hoe de prestaties van lineaire classificator te meten?
Nauwkeurigheid
De algehele prestaties van een classificator worden gemeten met de nauwkeurigheidsmetriek. Nauwkeurigheid verzamelt alle juiste waarden gedeeld door het totale aantal waarnemingen. Een nauwkeurigheidswaarde van 80 procent betekent bijvoorbeeld dat het model in 80 procent van de gevallen correct is.
U kunt een tekortkoming opmerken met deze statistiek, vooral voor onbalansklasse. Een onbalans dataset treedt op als het aantal waarnemingen per groep niet gelijk is. Laten we zeggen; je probeert een zeldzame gebeurtenis te classificeren met een logistieke functie. Stel je voor dat de classificator probeert de dood van een patiënt na een ziekte in te schatten. In de gegevens overlijdt 5 procent van de patiënten. U kunt een classificator trainen om het aantal doden te voorspellen en de nauwkeurigheidsstatistiek gebruiken om de prestaties te evalueren. Als de classificator 0 sterfgevallen voorspelt voor de hele dataset, zal dit in 95 procent van de gevallen correct zijn.
Verwarring matrix
Een betere manier om de prestaties van een classificator te beoordelen, is door naar de verwarringmatrix te kijken.
De verwarringmatrix visualiseert de nauwkeurigheid van een classificator door de werkelijke en voorspelde klassen te vergelijken, zoals weergegeven in het bovenstaande Lineaire Classificatievoorbeeld. De binaire verwarringmatrix is samengesteld uit vierkanten:
- TP: True Positive: Voorspelde waarden correct voorspeld als werkelijk positief
- FP: Voorspelde waarden voorspelden onjuist een feitelijk positief. dwz negatieve waarden voorspeld als positief
- FN: False Negative: Positieve waarden voorspeld als negatief
- TN: True Negative: voorspelde waarden correct voorspeld als werkelijk negatief
Vanuit de verwarringmatrix is het gemakkelijk om de werkelijke klasse en de voorspelde klasse te vergelijken.
Precisie en gevoeligheid
De verwarringmatrix geeft een goed inzicht in het ware positieve en vals positieve. In sommige gevallen heeft het de voorkeur om een beknoptere metriek te hebben.
Precisie
De precisiemetriek toont de nauwkeurigheid van de positieve klasse. Het meet hoe waarschijnlijk het is dat de voorspelling van de positieve klasse correct is.
De maximale score is 1 wanneer de classificator alle positieve waarden perfect classificeert. Precisie alleen is niet erg nuttig omdat het de negatieve klasse negeert. De metriek wordt meestal gecombineerd met de metriek terugroepen. Terugroepen wordt ook wel gevoeligheid of echt positief tarief genoemd.
Gevoeligheid
Gevoeligheid berekent de verhouding van correct gedetecteerde positieve klassen. Deze statistiek geeft aan hoe goed het model is om een positieve klasse te herkennen.
Lineaire classificatie met TensorFlow
Voor deze tutorial gebruiken we de census-dataset. Het doel is om de variabelen in de census-dataset te gebruiken om het inkomensniveau te voorspellen. Merk op dat het inkomen een binaire variabele is
- met een waarde van 1 als het inkomen> 50k
- 0 als inkomen <50k.
Deze variabele is jouw label
Deze dataset bevat acht categorische variabelen:
- werkplek
- onderwijs
- echtelijk
- bezetting
- relatie
- ras
- seks
- geboorteland
bovendien zes continue variabelen:
- leeftijd
- fnlwgt
- onderwijs_getal
- capital_gain
- capital_loss
- uur_week
Aan de hand van dit TensorFlow-classificatievoorbeeld zult u begrijpen hoe u lineaire TensorFlow-classificatoren kunt trainen met TensorFlow-schatter en hoe u de nauwkeurigheidsmetriek kunt verbeteren.
We gaan als volgt te werk:
- Stap 1) Importeer de gegevens
- Stap 2) Dataconversie
- Stap 3) Train de classifier
- Stap 4) Verbeter het model
- Stap 5) Hyperparameter: Lasso & Ridge
Stap 1) Importeer de gegevens
U importeert eerst de bibliotheken die tijdens de zelfstudie zijn gebruikt.
import tensorflow as tfimport pandas as pd
Vervolgens importeert u de gegevens uit het archief van UCI en definieert u de kolomnamen. U zult de KOLOMMEN gebruiken om de kolommen in een panda's dataframe een naam te geven.
Merk op dat je de classifier gaat trainen met behulp van een Pandas dataframe.
## 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 online opgeslagen gegevens zijn al verdeeld over een treinset en testset.
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)
De treinset bevat 32.561 waarnemingen en de 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 vereist een Booleaanse waarde om de classifier te trainen. U moet de waarden casten van string naar integer. Het label wordt opgeslagen als een object, maar u moet het converteren naar een numerieke waarde. De onderstaande code maakt een woordenboek met de waarden die moeten worden geconverteerd en doorlopen over het kolomitem. Merk op dat u deze handeling twee keer uitvoert, één voor de treintest, één voor de testset
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]
In de treindata zijn er 24.720 inkomens lager dan 50.000 en 7841 hoger. De verhouding is nagenoeg hetzelfde voor de testset. Raadpleeg deze tutorial over Facets voor meer informatie.
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
Stap 2) Dataconversie
Een paar stappen zijn vereist voordat u een lineaire classificator traint met Tensorflow. U moet de functies voorbereiden om in het model op te nemen. Bij de benchmarkregressie gebruikt u de originele gegevens zonder enige transformatie toe te passen.
De schatter heeft een lijst met functies nodig om het model te trainen. Daarom moeten de gegevens van de kolom worden omgezet in een tensor.
Een goede gewoonte is om twee lijsten met objecten te definiëren op basis van hun type en deze vervolgens door te geven in de feature_columns van de schatter.
U begint met het converteren van doorlopende objecten en definieert vervolgens een bucket met de categorische gegevens.
De kenmerken van de dataset hebben twee formaten:
- Geheel getal
- Voorwerp
Elke functie wordt vermeld in de volgende twee variabelen volgens hun typen.
## 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']
De feature_column is uitgerust met een object numeric_column om te helpen bij de transformatie van de continue variabelen in tensor. In de onderstaande code converteer je alle variabelen uit CONTI_FEATURES naar een tensor met een numerieke waarde. Dit is verplicht om het model te construeren. Alle onafhankelijke variabelen moeten worden omgezet in het juiste type tensor.
Hieronder schrijven we een code om u te laten zien wat er achter feature_column.numeric_column gebeurt. We zullen de geconverteerde waarde voor leeftijd afdrukken. Het is ter verduidelijking, daarom is het niet nodig om de python-code te begrijpen. U kunt de officiële documentatie raadplegen om de codes te begrijpen.
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.]]
De waarden zijn precies hetzelfde als in df_train
continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]
Volgens de documentatie van TensorFlow zijn er verschillende manieren om categorische gegevens te converteren. Als de woordenlijst van een feature bekend is en niet veel waarden heeft, is het mogelijk om de categorische kolom te maken met categorical_column_with_vocabulary_list. Het zal aan alle unieke woordenlijsten een ID toewijzen.
Als de status van een variabele bijvoorbeeld drie verschillende waarden heeft:
- Man
- Vrouw
- Single
Vervolgens worden drie ID's toegekend. De man heeft bijvoorbeeld de ID 1, de vrouw de ID 2 enzovoort.
Ter illustratie kunt u deze code gebruiken om een objectvariabele om te zetten in een categorische kolom in TensorFlow.
Het kenmerk geslacht kan maar twee waarden hebben: mannelijk of vrouwelijk. Wanneer we het kenmerk geslacht zullen converteren, zal Tensorflow 2 nieuwe kolommen maken, een voor mannen en een voor vrouwen. Als het geslacht gelijk is aan mannelijk, dan is de nieuwe kolom mannelijk gelijk aan 1 en vrouwelijk aan 0. Dit voorbeeld wordt weergegeven in de onderstaande tabel:
rijen |
seks |
na transformatie |
mannetje |
vrouw |
1 |
mannetje |
|
1 |
0 |
2 |
mannetje |
|
1 |
0 |
3 |
vrouw |
|
0 |
1 |
In 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'])
Hieronder hebben we Python-code toegevoegd om de codering af te drukken. Nogmaals, u hoeft de code niet te begrijpen, het doel is om de transformatie te zien
Een snellere manier om de gegevens te transformeren, is echter door de methode categorical_column_with_hash_bucket te gebruiken. Het is handig om stringvariabelen in een sparse matrix te wijzigen. Een spaarzame matrix is een matrix met meestal nul. De methode zorgt voor alles. U hoeft alleen het aantal emmers en de sleutelkolom op te geven. Het aantal buckets is het maximale aantal groepen dat Tensorflow kan maken. De sleutelkolom is gewoon de naam van de kolom die moet worden geconverteerd.
In de onderstaande code maak je een lus over alle categorische kenmerken.
categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]
Stap 3) Train de classificatie
TensorFlow biedt momenteel een schatter voor de lineaire regressie en lineaire classificatie.
- Lineaire regressie: LinearRegressor
- Lineaire classificatie: LinearClassifier
De syntaxis van de lineaire classifier is hetzelfde als in de tutorial over lineaire regressie, met uitzondering van één argument, n_class. U moet de feature-kolom, de modeldirectory definiëren en vergelijken met de lineaire regressor; je moet het aantal klassen bepalen. Voor een logitregressie is het aantal klassen gelijk aan 2.
Het model berekent de gewichten van de kolommen in continue_features en categorical_features.
model = tf.estimator.LinearClassifier(n_classes = 2,model_dir="ongoing/train",feature_columns=categorical_features+ continuous_features)
UITGANG:
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 de classificatie is gedefinieerd, kunt u de invoerfunctie maken. De methode is hetzelfde als in de tutorial over lineaire regressoren. Hier gebruik je een batchgrootte van 128 en je schudt de gegevens door elkaar.
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)
U maakt een functie met de argumenten die de lineaire schatter nodig heeft, dwz het aantal tijdvakken, het aantal batches en u schudt de dataset of notitie. Omdat u de Pandas-methode gebruikt om de gegevens in het model door te geven, moet u de X-variabelen definiëren als een pandas-dataframe. Merk op dat u alle gegevens die zijn opgeslagen in FUNCTIES doorloopt.
Laten we het model trainen met het object model.train. U gebruikt de eerder gedefinieerde functie om het model van de juiste waarden te voorzien. Merk op dat u de batchgrootte instelt op 128 en het aantal tijdperken op Geen. Het model zal meer dan duizend stappen worden getraind.
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.
Merk op dat het verlies vervolgens afnam tijdens de laatste 100 stappen, dat wil zeggen van 901 naar 1000.
Het uiteindelijke verlies na duizend iteraties is 5444. U kunt uw model op de testset schatten en de prestaties bekijken. Om de prestaties van uw model te evalueren, moet u de objectevaluatie gebruiken. Je voedt het model met de testset en stelt het aantal tijdperken in op 1, dat wil zeggen dat de gegevens maar één keer naar het model gaan.
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 retourneert alle statistieken die u in het theoretische gedeelte hebt geleerd. Het hoeft geen verrassing te zijn dat de nauwkeurigheid groot is vanwege het ongebalanceerde label. Eigenlijk presteert het model iets beter dan een willekeurige gok. Stel je voor dat het model alle huishoudens voorspelt met een inkomen lager dan 50K, dan heeft het model een nauwkeurigheid van 70 procent. Bij een nadere analyse kunt u zien dat de voorspelling en herinnering vrij laag zijn.
Stap 4) Verbeter het model
Nu u een benchmarkmodel heeft, kunt u proberen het te verbeteren, dat wil zeggen de nauwkeurigheid te vergroten. In de vorige tutorial heb je geleerd hoe je het voorspellingsvermogen kunt verbeteren met een interactieterm. In deze tutorial zul je dit idee opnieuw bekijken door een polynoomterm aan de regressie toe te voegen.
Polynoomregressie is instrumenteel wanneer er niet-lineariteit in de gegevens is. Er zijn twee manieren om niet-lineariteit in de gegevens vast te leggen.
- Voeg polynoomterm toe
- Bucketize de continue variabele in een categorische variabele
Polynoom term
Op de onderstaande afbeelding kun je zien wat een polynoomregressie is. Het is een vergelijking met X-variabelen met verschillende vermogens. Een tweedegraads polynoomregressie heeft twee variabelen, X en X in het kwadraat. De derde graad heeft drie variabelen, X, X 2 en X 3
Hieronder hebben we een grafiek gemaakt met twee variabelen, X en Y. Het is duidelijk dat de relatie niet lineair is. Als we een lineaire regressie toevoegen, kunnen we zien dat het model het patroon niet kan vastleggen (linker afbeelding).
Kijk nu naar de linker afbeelding van de onderstaande afbeelding, we hebben vijf termen aan de regressie toegevoegd (dat is y = x + x 2 + x 3 + x 4 + x 5. Het model legt nu veel beter het patroon vast. Dit is de kracht van polynoomregressie.
Laten we teruggaan naar ons voorbeeld. Leeftijd staat niet in een lineaire relatie met inkomen. De vroege leeftijd kan een vast inkomen hebben dat bijna nul is, omdat kinderen of jongeren niet werken. Daarna neemt het toe in de werkende leeftijd en neemt het af tijdens de pensionering. Het is meestal een omgekeerde U-vorm. Een manier om dit patroon vast te leggen, is door een macht twee toe te voegen aan de regressie.
Eens kijken of het de nauwkeurigheid vergroot.
U moet deze nieuwe functie toevoegen aan de dataset en in de lijst met doorlopende functies.
Je voegt de nieuwe variabele toe aan de train and test dataset, dus het is handiger om een functie te schrijven.
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
De functie heeft 3 argumenten:
- df_t: definieer de trainingsset
- df_te: definieer de testset
- var_name = 'age': Definieer de variabele die u wilt transformeren
Je kunt het object pow (2) gebruiken om de variabele leeftijd te kwadrateren. Merk op dat de nieuwe variabele 'nieuw' heet
Nu de functie square_var is geschreven, kun je de nieuwe datasets aanmaken.
df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')
Zoals u kunt zien, heeft de nieuwe dataset nog een functie.
print(df_train_new.shape, df_test_new.shape)(32561, 16) (16281, 16)
De vierkante variabele wordt nieuw genoemd in de dataset. U moet het toevoegen aan de lijst met doorlopende functies.
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]
Merk op dat u de directory van de Graph hebt gewijzigd. U kunt niet verschillende modellen in dezelfde directory trainen. Dit betekent dat u het pad van het argument model_dir moet wijzigen. Als u dat niet doet, zal TensorFlow een foutmelding geven.
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 de classifier is ontworpen met de nieuwe dataset, kunt u het model trainen en evalueren.
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}
De kwadraatvariabele verbeterde de nauwkeurigheid van 0,76 naar 0,79. Laten we eens kijken of u het beter kunt doen door bucketisatie en interactieterm te combineren.
Bucketization en interactie
Zoals je eerder hebt gezien, is een lineaire classificator niet in staat het patroon van het leeftijdsinkomen correct vast te leggen. Dat komt omdat het voor elk kenmerk een enkel gewicht leert. Om het voor de classificator gemakkelijker te maken, kunt u de functie een keer in een bucket plaatsen. Bucketing transformeert een numeriek kenmerk in verschillende bepaalde functies op basis van het bereik waarin het valt, en elk van deze nieuwe kenmerken geeft aan of de leeftijd van een persoon binnen dat bereik valt.
Met deze nieuwe functies kan het lineaire model de relatie vastleggen door verschillende gewichten voor elke bucket te leren.
In TensorFlow wordt dit gedaan met bucketized_column. U moet het bereik van waarden binnen de grenzen toevoegen.
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])
U weet al dat leeftijd niet lineair is met het inkomen. Een andere manier om het model te verbeteren, is door middel van interactie. In de woorden van TensorFlow is het kruising van functies. Het kruisen van objecten is een manier om nieuwe objecten te maken die combinaties zijn van bestaande objecten, wat handig kan zijn voor een lineaire classificatie die geen interacties tussen objecten kan modelleren.
Je kunt leeftijd afbreken met een andere functie, zoals onderwijs. Dat wil zeggen dat sommige groepen waarschijnlijk een hoog inkomen hebben en andere een laag (denk aan de promovendus).
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)]
Om een kolom met kruiselementen te maken, gebruikt u gekruiste_kolom met de variabelen die u in een haakje wilt kruisen. De hash_bucket_size geeft de maximale kruisingsmogelijkheden aan. Om interactie tussen variabelen te creëren (ten minste één variabele moet categorisch zijn), kunt u tf.feature_column.crossed_column gebruiken. Om dit object te gebruiken, moet u tussen vierkante haakjes de variabele toevoegen die moet worden gebruikt en een tweede argument, de bucketgrootte. De bucket size is het maximaal mogelijke aantal groepen binnen een variabele. Hier stelt u het in op 1000 omdat u het exacte aantal groepen niet weet
age_buckets moet eerst worden gekwadrateerd om het aan de feature-kolommen toe te voegen. Je voegt ook de nieuwe features toe aan de features kolommen en bereidt de schatter voor
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)
UITGANG
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)
U bent klaar om het nieuwe model te schatten en te kijken of het de nauwkeurigheid verbetert.
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}
Het nieuwe nauwkeurigheidsniveau is 83,58 procent. Het is vier procent hoger dan het vorige model.
Ten slotte kunt u een regularisatieterm toevoegen om overfitting te voorkomen.
Stap 5) Hyperparameter: Lasso & Ridge
Uw model kan last hebben van overfitting of underfitting .
- Overfitting: het model kan de voorspelling niet generaliseren naar nieuwe gegevens
- Underfitting: het model kan het patroon van de gegevens niet vastleggen. dwz lineaire regressie wanneer de gegevens niet-lineair zijn
Als een model veel parameters en relatief weinig gegevens heeft, leidt dit tot slechte voorspellingen. Stel je voor, één groep heeft maar drie observaties; het model berekent een gewicht voor deze groep. Het gewicht wordt gebruikt om een voorspelling te doen; als de waarnemingen van de testset voor deze specifieke groep totaal anders zijn dan de trainingsset, dan zal het model een verkeerde voorspelling doen. Tijdens de evaluatie met de trainingsset is de nauwkeurigheid goed, maar niet goed met de testset, omdat de berekende gewichten niet de juiste zijn om het patroon te generaliseren. In dit geval doet het geen redelijke voorspelling op basis van ongeziene gegevens.
Om overfitting te voorkomen, biedt regularisatie u de mogelijkheid om op dergelijke complexiteit te controleren en deze meer generaliseerbaar te maken. Er zijn twee regularisatietechnieken:
- L1: Lasso
- L2: Ridge
In TensorFlow kunt u deze twee hyperparameters in de optimizer toevoegen. Hoe hoger de hyperparameter L2, hoe hoger het gewicht bijvoorbeeld erg laag is en bijna nul. De paslijn zal erg vlak zijn, terwijl een L2 dicht bij nul impliceert dat de gewichten dicht bij de reguliere lineaire regressie liggen.
U kunt zelf de verschillende waarden van de hyperparameters uitproberen en kijken of u het nauwkeurigheidsniveau kunt verhogen.
Merk op dat als u de hyperparameter wijzigt, u de map lopende / train4 moet verwijderen, anders begint het model met het eerder getrainde model.
Laten we eens kijken hoe de nauwkeurigheid van de hype is
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))
UITGANG
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)
UITGANG
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)
UITGANG
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}
Met deze hyperparameter verhoogt u de nauwkeurigheidsstatistieken enigszins. In de volgende tutorial leer je hoe je een lineaire classifier kunt verbeteren met behulp van een kernelmethode.
Overzicht
Om een model te trainen, moet u:
- Definieer de kenmerken: Onafhankelijke variabelen: X
- Definieer het label: afhankelijke variabele: y
- Bouw een trein / testset
- Bepaal het begingewicht
- Definieer de verliesfunctie: MSE
- Optimaliseer het model: gradiënt afdaling
- Bepalen:
- Leersnelheid
- Tijdperk
- Seriegrootte
- Aantal klassen
In deze zelfstudie hebt u geleerd hoe u de API op hoog niveau kunt gebruiken voor een lineaire regressieclassificatie. U moet het volgende definiëren:
- Feature kolommen. Indien continu: tf.feature_column.numeric_column (). U kunt een lijst vullen met het begrip Python-lijst
- De schatter: tf.estimator.LinearClassifier (feature_columns, model_dir, n_classes = 2)
- Een functie om de gegevens, de batchgrootte en het epoch te importeren: input_fn ()
Daarna ben je klaar om te trainen, evalueren en een voorspelling te doen met train (), evalu () en voorspel ()
Om de prestaties van het model te verbeteren, kunt u:
- Gebruik polynoomregressie
- Interactieterm: tf.feature_column.crossed_column
- Voeg een regularisatieparameter toe