Zobacz na TensorFlow.org | Uruchom w Google Colab | Wyświetl źródło na GitHub | Pobierz notatnik |
Przegląd
Ten kompleksowy przewodnik szkoli model regresji logistycznej przy użyciu interfejsu API tf.estimator
. Model jest często używany jako punkt odniesienia dla innych, bardziej złożonych algorytmów.
Ustawiać
pip install sklearn
import os
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import clear_output
from six.moves import urllib
Załaduj tytaniczny zbiór danych
Użyjesz zestawu danych Titanica w (raczej chorobliwym) celu przewidywania przeżycia pasażerów, z uwzględnieniem określonych cech, takich jak płeć, wiek, klasa itp.
import tensorflow.compat.v2.feature_column as fc
import tensorflow as tf
# Load dataset.
dftrain = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/train.csv')
dfeval = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/eval.csv')
y_train = dftrain.pop('survived')
y_eval = dfeval.pop('survived')
Przeglądaj dane
Zbiór danych zawiera następujące funkcje
dftrain.head()
dftrain.describe()
W zestawach szkoleniowych i ewaluacyjnych znajduje się odpowiednio 627 i 264 przykładów.
dftrain.shape[0], dfeval.shape[0]
(627, 264)
Większość pasażerów ma 20 i 30 lat.
dftrain.age.hist(bins=20)
<AxesSubplot:>
Na pokładzie jest około dwa razy więcej pasażerów płci męskiej niż kobiet.
dftrain.sex.value_counts().plot(kind='barh')
<AxesSubplot:>
Większość pasażerów znajdowała się w „trzeciej” klasie.
dftrain['class'].value_counts().plot(kind='barh')
<AxesSubplot:>
Kobiety mają znacznie większą szansę na przeżycie niż mężczyźni. Jest to wyraźnie funkcja predykcyjna modelu.
pd.concat([dftrain, y_train], axis=1).groupby('sex').survived.mean().plot(kind='barh').set_xlabel('% survive')
Text(0.5, 0, '% survive')
Inżynieria funkcji dla modelu
Estymatory używają systemu zwanego kolumnami funkcji, aby opisać, jak model powinien interpretować każdą z surowych funkcji wejściowych. Estymator oczekuje wektora danych wejściowych liczbowych, a kolumny funkcji opisują, jak model powinien konwertować każdą funkcję.
Wybór i tworzenie odpowiedniego zestawu kolumn funkcji jest kluczem do nauki skutecznego modelu. Kolumna elementów może być albo jednym z nieprzetworzonych danych wejściowych w oryginalnych dict
( kolumna elementów podstawowych ), albo dowolnymi nowymi kolumnami utworzonymi przy użyciu przekształceń zdefiniowanych w jednej lub wielu kolumnach podstawowych (kolumny elementów pochodnych ).
Estymator liniowy wykorzystuje zarówno cechy liczbowe, jak i kategoryczne. Kolumny funkcji współpracują ze wszystkimi estymatorami TensorFlow, a ich celem jest zdefiniowanie funkcji używanych do modelowania. Ponadto zapewniają one pewne możliwości inżynierii funkcji, takie jak jednokrotne kodowanie, normalizacja i zasobniki.
Kolumny funkcji podstawowych
CATEGORICAL_COLUMNS = ['sex', 'n_siblings_spouses', 'parch', 'class', 'deck',
'embark_town', 'alone']
NUMERIC_COLUMNS = ['age', 'fare']
feature_columns = []
for feature_name in CATEGORICAL_COLUMNS:
vocabulary = dftrain[feature_name].unique()
feature_columns.append(tf.feature_column.categorical_column_with_vocabulary_list(feature_name, vocabulary))
for feature_name in NUMERIC_COLUMNS:
feature_columns.append(tf.feature_column.numeric_column(feature_name, dtype=tf.float32))
Funkcja input_function
określa sposób konwersji danych do tf.data.Dataset
, który zasila potok wejściowy w sposób przesyłania strumieniowego. tf.data.Dataset
może przyjmować wiele źródeł, takich jak dataframe, plik w formacie csv i inne.
def make_input_fn(data_df, label_df, num_epochs=10, shuffle=True, batch_size=32):
def input_function():
ds = tf.data.Dataset.from_tensor_slices((dict(data_df), label_df))
if shuffle:
ds = ds.shuffle(1000)
ds = ds.batch(batch_size).repeat(num_epochs)
return ds
return input_function
train_input_fn = make_input_fn(dftrain, y_train)
eval_input_fn = make_input_fn(dfeval, y_eval, num_epochs=1, shuffle=False)
Możesz sprawdzić zbiór danych:
ds = make_input_fn(dftrain, y_train, batch_size=10)()
for feature_batch, label_batch in ds.take(1):
print('Some feature keys:', list(feature_batch.keys()))
print()
print('A batch of class:', feature_batch['class'].numpy())
print()
print('A batch of Labels:', label_batch.numpy())
Some feature keys: ['sex', 'age', 'n_siblings_spouses', 'parch', 'fare', 'class', 'deck', 'embark_town', 'alone'] A batch of class: [b'Third' b'Third' b'Third' b'Third' b'Third' b'First' b'Second' b'First' b'First' b'Third'] A batch of Labels: [0 1 1 0 0 1 0 1 1 0]
Możesz również sprawdzić wynik określonej kolumny funkcji, korzystając z warstwy tf.keras.layers.DenseFeatures
:
age_column = feature_columns[7]
tf.keras.layers.DenseFeatures([age_column])(feature_batch).numpy()
array([[35.], [14.], [28.], [19.], [28.], [35.], [60.], [63.], [45.], [21.]], dtype=float32)
DenseFeatures
akceptuje tylko gęste tensory, aby sprawdzić kolumnę kategorii, musisz najpierw przekształcić ją w kolumnę wskaźnika:
gender_column = feature_columns[0]
tf.keras.layers.DenseFeatures([tf.feature_column.indicator_column(gender_column)])(feature_batch).numpy()
array([[1., 0.], [0., 1.], [0., 1.], [1., 0.], [1., 0.], [1., 0.], [1., 0.], [0., 1.], [0., 1.], [0., 1.]], dtype=float32)
Po dodaniu wszystkich podstawowych funkcji do modelu, przeszkolmy model. Trenowanie modelu to tylko jedno polecenie przy użyciu API tf.estimator
:
linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns)
linear_est.train(train_input_fn)
result = linear_est.evaluate(eval_input_fn)
clear_output()
print(result)
{'accuracy': 0.7537879, 'accuracy_baseline': 0.625, 'auc': 0.8060607, 'auc_precision_recall': 0.7480768, 'average_loss': 0.5639972, 'label/mean': 0.375, 'loss': 0.5542658, 'precision': 0.7741935, 'prediction/mean': 0.25232768, 'recall': 0.4848485, 'global_step': 200}
Kolumny funkcji pochodnych
Teraz osiągnąłeś dokładność 75%. Użycie każdej kolumny cech podstawowych oddzielnie może nie wystarczyć do wyjaśnienia danych. Na przykład korelacja między wiekiem a etykietą może być różna dla różnych płci. Dlatego, jeśli poznasz tylko jedną wagę modelu dla gender="Male"
i gender="Female"
, nie uchwycisz wszystkich kombinacji wiek-płeć (np. rozróżniając gender="Male"
AND age="30"
AND gender="Male"
ORAZ age="40"
).
Aby poznać różnice między różnymi kombinacjami funkcji, możesz dodać do modelu kolumny funkcji krzyżujących się (możesz także podzielić kolumnę wieku przed kolumną krzyżową):
age_x_gender = tf.feature_column.crossed_column(['age', 'sex'], hash_bucket_size=100)
Po dodaniu funkcji kombinacji do modelu, przeszkolmy model ponownie:
derived_feature_columns = [age_x_gender]
linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns+derived_feature_columns)
linear_est.train(train_input_fn)
result = linear_est.evaluate(eval_input_fn)
clear_output()
print(result)
{'accuracy': 0.7462121, 'accuracy_baseline': 0.625, 'auc': 0.845577, 'auc_precision_recall': 0.7873878, 'average_loss': 0.47313985, 'label/mean': 0.375, 'loss': 0.46722567, 'precision': 0.6509434, 'prediction/mean': 0.41550797, 'recall': 0.6969697, 'global_step': 200}
Osiąga teraz dokładność 77,6%, co jest nieco lepszą wartością niż tylko wytrenowana w podstawowych funkcjach. Możesz spróbować użyć większej liczby funkcji i przekształceń, aby zobaczyć, czy możesz zrobić to lepiej!
Teraz możesz użyć modelu pociągu do prognozowania pasażera z zestawu ewaluacyjnego. Modele TensorFlow są zoptymalizowane pod kątem prognozowania partii lub kolekcji przykładów naraz. Wcześniej eval_input_fn
został zdefiniowany przy użyciu całego zestawu ewaluacyjnego.
pred_dicts = list(linear_est.predict(eval_input_fn))
probs = pd.Series([pred['probabilities'][1] for pred in pred_dicts])
probs.plot(kind='hist', bins=20, title='predicted probabilities')
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from /tmp/tmpe5vngw46/model.ckpt-200 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. <AxesSubplot:title={'center':'predicted probabilities'}, ylabel='Frequency'>
Na koniec spójrz na charakterystykę działania odbiornika (ROC) wyników, która da nam lepsze wyobrażenie o kompromisie między stawką prawdziwie pozytywnych a stawką fałszywie pozytywnych.
from sklearn.metrics import roc_curve
from matplotlib import pyplot as plt
fpr, tpr, _ = roc_curve(y_eval, probs)
plt.plot(fpr, tpr)
plt.title('ROC curve')
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.xlim(0,)
plt.ylim(0,)
(0.0, 1.05)