Бинарная классификация TensorFlow: пример линейного классификатора

Два самых распространенных контролируемое обучение задачами являются линейная регрессия и линейный классификатор. Линейная регрессия прогнозирует значение, а линейный классификатор прогнозирует класс. Этот урок посвящен линейным классификаторам.

Что такое линейный классификатор?

A Линейный классификатор в машинном обучении — это метод определения класса объекта на основе его характеристик для статистической классификации. Он принимает решение о классификации на основе значения линейной комбинации характеристик объекта. Линейный классификатор используется в практических задачах, таких как классификация документов и задачи с множеством переменных.

Проблемы классификации составляют примерно 80 процентов задач машинного обучения. Целью классификации является прогнозирование вероятности каждого класса с учетом набора входных данных. Метка (т. е. зависимая переменная) представляет собой дискретное значение, называемое классом.

  1. Если метка имеет только два класса, алгоритмом обучения является двоичный классификатор.
  2. Мультиклассовый классификатор обрабатывает метки с более чем двумя классами.

Например, типичная задача бинарной классификации состоит в том, чтобы предсказать вероятность того, что покупатель совершит вторую покупку. Предсказать тип животного, изображенного на изображении, является проблемой многоклассовой классификации, поскольку существует более двух разновидностей животных.

В теоретической части этого руководства основное внимание уделяется бинарному классу. Вы узнаете больше о функции вывода мультиклассов в следующем уроке.

Как работает двоичный классификатор?

В предыдущем уроке вы узнали, что функция состоит из двух типов переменных: зависимой переменной и набора функций (независимых переменных). В линейной регрессии зависимая переменная представляет собой действительное число без диапазона. Основная цель — спрогнозировать его значение путем минимизации среднеквадратической ошибки.

Для двоичного классификатора TensorFlow метка могла иметь два возможных целочисленных значения. В большинстве случаев это либо [0,1], либо [1,2]. Например, цель состоит в том, чтобы предсказать, купит ли клиент продукт или нет. Метка определяется следующим образом:

  • Y = 1 (клиент приобрел товар)
  • Y = 0 (клиент не покупает товар)

Модель использует признаки X для отнесения каждого покупателя к наиболее вероятному классу, к которому он принадлежит, а именно к потенциальному покупателю или нет.

Вероятность успеха рассчитывается с помощью логистическая регрессия. Алгоритм вычислит вероятность на основе признака X и предскажет успех, когда эта вероятность превысит 50 процентов. Более формально, вероятность рассчитывается, как показано в примере двоичной классификации TensorFlow ниже:

Пример двоичной классификации

где 0 — набор весов, признаков и b смещение.

Функцию можно разбить на две части:

  • Линейная модель
  • Логистическая функция

Линейная модель

Вы уже знакомы со способом вычисления весов. Веса вычисляются с использованием скалярного произведения:Скалярное произведение Y — линейная функция всех признаков xi. Если модель не имеет особенностей, прогноз равен смещению b.

Веса указывают направление корреляции между признаками xi и метка y. Положительная корреляция увеличивает вероятность положительного класса, тогда как отрицательная корреляция приближает вероятность к 0 (т. е. отрицательному классу).

Линейная модель возвращает только действительное число, которое несовместимо с вероятностной мерой диапазона [0,1]. Логистическая функция необходима для преобразования выходных данных линейной модели в вероятность.

Логистическая функция

Логистическая функция, или сигмовидная функция, имеет S-образную форму, и выходные данные этой функции всегда находятся в диапазоне от 0 до 1.

Пример логистической функции

Пример логистической функции
Пример логистической функции

Выход линейной регрессии легко заменить сигмовидной функцией. В результате получается новое число с вероятностью от 0 до 1.

Классификатор может преобразовать вероятность в класс

  • Значения от 0 до 0.49 переходят в класс 0.
  • Значения от 0.5 до 1 переходят в класс 1.

Как измерить производительность линейного классификатора?

точность

Общая производительность классификатора измеряется показателем точности. Точность собирает все правильные значения, деленные на общее количество наблюдений. Например, значение точности 80 процентов означает, что модель верна в 80 процентах случаев.

Метрика точности
Измерьте производительность линейного классификатора с помощью метрики точности.

Можно отметить недостаток этой метрики, особенно для класса дисбаланса. Набор данных дисбаланса возникает, когда количество наблюдений на группу не равно. Скажем так; вы пытаетесь классифицировать редкое событие с помощью логистической функции. Представьте себе, что классификатор пытается оценить смерть пациента от заболевания. По данным, 5 процентов пациентов умирают. Вы можете обучить классификатор прогнозировать количество смертей и использовать показатель точности для оценки производительности. Если классификатор прогнозирует 0 смертей для всего набора данных, это будет верно в 95 процентах случаев.

Матрица путаницы

Лучший способ оценить эффективность классификатора — посмотреть на матрицу путаницы.

Матрица путаницы
Измерьте производительность линейного классификатора с помощью матрицы путаницы

Наша команда матрица путаницы визуализирует точность классификатора путем сравнения фактических и прогнозируемых классов, как показано в приведенном выше примере линейного классификатора. Матрица двоичной путаницы состоит из квадратов:

  • TP: True Positive: прогнозируемые значения правильно прогнозируются как фактические положительные значения.
  • ФП: Прогнозируемые значения неверно предсказывали фактический положительный результат. т. е. отрицательные значения прогнозируются как положительные
  • FN: ложноотрицательный результат: положительные значения прогнозируются как отрицательные.
  • TN: True Negative: прогнозируемые значения правильно прогнозируются как фактические отрицательные.

Из матрицы путаницы легко сравнить фактический класс и прогнозируемый класс.

Точность и чувствительность

Матрица путаницы дает хорошее представление об истинно положительных и ложноположительных результатах. В некоторых случаях предпочтительнее иметь более краткую метрику.

Точность

Метрика точности показывает точность положительного класса. Он измеряет, насколько вероятен прогноз положительного класса.

Точность

Максимальный балл равен 1, если классификатор идеально классифицирует все положительные значения. Сама по себе точность не очень полезна, поскольку она игнорирует отрицательный класс. Метрика обычно сочетается с метрикой отзыва. Воспоминание также называют чувствительностью или истинно положительным уровнем.

чувствительность

Чувствительность вычисляет соотношение правильно обнаруженных положительных классов. Эта метрика показывает, насколько хорошо модель распознает положительный класс.

чувствительность

Линейный классификатор с TensorFlow

В этом уроке мы будем использовать набор данных переписи населения. Цель состоит в том, чтобы использовать переменные в наборе данных переписи для прогнозирования уровня дохода. Обратите внимание, что доход — это бинарная переменная.

  • со значением 1, если доход > 50 тыс.
  • 0, если доход < 50 тыс.

Эта переменная — ваш ярлык

Этот набор данных включает восемь категориальных переменных:

  • рабочее место
  • образование
  • брачный
  • оккупация
  • отношения
  • раса
  • секс
  • родная страна

причем шесть непрерывных переменных:

  • возраст
  • фнлвгт
  • образование_номер
  • прирост капитала
  • капитал_убыток
  • часы_неделя

Из этого примера классификации TensorFlow вы поймете, как обучать линейные классификаторы TensorFlow с помощью средства оценки TensorFlow и как улучшить показатель точности.

Мы будем действовать следующим образом:

  • Шаг 1) Импортируйте данные
  • Шаг 2) Преобразование данных
  • Шаг 3) Обучите классификатор
  • Шаг 4) Улучшите модель
  • Шаг 5) Гиперпараметр: Лассо и хребет

Шаг 1) Импортируйте данные

Сначала вы импортируете библиотеки, используемые в этом руководстве.

import tensorflow as tf
import pandas as pd

Далее вы импортируете данные из архива UCI и определяете имена столбцов. Вы будете использовать COLUMNS для именования столбцов во фрейме данных pandas.

Обратите внимание, что вы будете обучать классификатор, используя фрейм данных Pandas.

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

Данные, хранящиеся в Интернете, уже разделены между набором поездов и набором тестов.

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)

Набор поездов содержит 32,561 16,281 наблюдение, а тестовый набор — XNUMX XNUMX.

print(df_train.shape, df_test.shape)
print(df_train.dtypes)
(32561, 15) (16281, 15)
age                int64
workclass         object
fnlwgt             int64
education         object
education_num      int64
marital           object
occupation        object
relationship      object
race              object
sex               object
capital_gain       int64
capital_loss       int64
hours_week         int64
native_country    object
label             object
dtype: object

Tensorflow требует логического значения для обучения классификатора. Вам нужно преобразовать значения из строки в целое число. Метка хранится как объект, однако вам необходимо преобразовать ее в числовое значение. Код ниже создает словарь со значениями для преобразования и циклического перебора элемента столбца. Обратите внимание, что вы выполняете эту операцию дважды: один для теста поезда, другой для тестового набора.

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]

В данных поезда 24,720 доходов ниже 50к и 7841 выше. Соотношение практически одинаковое для тестового набора. Дополнительную информацию см. в этом руководстве по аспектам.

print(df_train["label"].value_counts())
### The model will be correct in atleast 70% of the case
print(df_test["label"].value_counts())
## Unbalanced label
print(df_train.dtypes)
0    24720
1     7841
Name: label, dtype: int64
0    12435
1     3846
Name: label, dtype: int64
age                int64
workclass         object
fnlwgt             int64
education         object
education_num      int64
marital           object
occupation        object
relationship      object
race              object
sex               object
capital_gain       int64
capital_loss       int64
hours_week         int64
native_country    object
label              int64
dtype: object

Шаг 2) Преобразование данных

Прежде чем обучать линейный классификатор с помощью Tensorflow, необходимо выполнить несколько шагов. Вам необходимо подготовить функции для включения в модель. В эталонной регрессии вы будете использовать исходные данные без применения каких-либо преобразований.

Оценщику необходим список функций для обучения модели. Следовательно, данные столбца необходимо преобразовать в тензор.

Хорошей практикой является определение двух списков объектов в зависимости от их типа, а затем передача их в Feature_columns средства оценки.

Вы начнете с преобразования непрерывных объектов, а затем определите сегмент с категориальными данными.

Характеристики набора данных имеют два формата:

  • Целое
  • объект

Каждая функция указана в следующих двух переменных в соответствии с ее типом.

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

Feature_column оснащен объектом numeric_column, который помогает преобразовать непрерывные переменные в тензорные. В приведенном ниже коде вы конвертируете все переменные из CONTI_FEATURES в тензор с числовым значением. Это обязательное условие для построения модели. Все независимые переменные необходимо преобразовать в тензор соответствующего типа.

Ниже мы напишем код, который позволит вам увидеть, что происходит за Feature_column.numeric_column. Мы напечатаем преобразованное значение возраста. Это сделано для пояснительных целей, поэтому нет необходимости разбираться в коде Python. Вы можете обратиться к официальной документации, чтобы понять коды.

def print_transformation(feature = "age", continuous = True, size = 2): 
    #X = fc.numeric_column(feature)
    ## Create feature name
    feature_names = [
    feature]

    ## Create dict with the data
    d = dict(zip(feature_names, [df_train[feature]]))

    ## Convert age
    if continuous == True:
        c = tf.feature_column.numeric_column(feature)
        feature_columns = [c]
    else: 
        c = tf.feature_column.categorical_column_with_hash_bucket(feature, hash_bucket_size=size) 
        c_indicator = tf.feature_column.indicator_column(c)
        feature_columns = [c_indicator]
    
## Use input_layer to print the value
    input_layer = tf.feature_column.input_layer(
        features=d,
        feature_columns=feature_columns
        )
    ## Create lookup table
    zero = tf.constant(0, dtype=tf.float32)
    where = tf.not_equal(input_layer, zero)
    ## Return lookup tble
    indices = tf.where(where)
    values = tf.gather_nd(input_layer, indices)
    ## Initiate graph
    sess = tf.Session()
    ## Print value
    print(sess.run(input_layer))
print_transformation(feature = "age", continuous = True) 
[[39.]
 [50.]
 [38.]
 ...
 [58.]
 [22.]
 [52.]]

Значения точно такие же, как в df_train.

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

Согласно документации TensorFlow, существуют разные способы преобразования категориальных данных. Если список словаря функции известен и не имеет большого количества значений, можно создать категориальный столбец с помощью categorical_column_with_vocabulary_list. Каждому уникальному словарному списку будет присвоен идентификатор.

Например, если статус переменной имеет три различных значения:

  • Муж
  • Жена
  • Один

Тогда будут присвоены три идентификатора. Например, у мужа будет идентификатор 1, у жены — идентификатор 2 и так далее.

В целях иллюстрации вы можете использовать этот код для преобразования объектной переменной в категориальный столбец в TensorFlow.

Признак пола может иметь только два значения: мужское или женское. Когда мы преобразуем пол объекта, Tensorflow создаст 2 новых столбца: один для мужчин и один для женщин. Если пол равен мужскому, то новый столбец «мужской» будет равен 1, а женский — 0. Этот пример показан в таблице ниже:

строки секс после трансформации мужского женский пол
1 мужского => 1 0
2 мужского => 1 0
3 женский пол => 0 1

В тензорном потоке:

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

Ниже мы добавили Python код для печати кодировки. Опять же, вам не нужно разбираться в коде, цель — увидеть трансформацию

Однако более быстрый способ преобразования данных — использовать метод categorical_column_with_hash_bucket. Изменение строковых переменных в разреженной матрице будет полезно. Разреженная матрица — это матрица, состоящая преимущественно из нуля. Этот метод позаботится обо всем. Вам нужно только указать количество сегментов и ключевой столбец. Количество сегментов — это максимальное количество групп, которые может создать Tensorflow. Ключевой столбец — это просто имя столбца, который нужно преобразовать.

В приведенном ниже коде вы создаете цикл по всем категориальным признакам.

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

Шаг 3) Обучите классификатор

TensorFlow в настоящее время предоставляет средство оценки линейной регрессии и линейной классификации.

  • Линейная регрессия: LinearRegressor
  • Линейная классификация: LinearClassifier

Синтаксис линейного классификатора такой же, как в уроке по линейная регрессия за исключением одного аргумента, n_class. Вам необходимо определить столбец функции, каталог модели и сравнить с линейным регрессором; у вас есть определение номера класса. Для логит-регрессии номер класса равен 2.

Модель вычислит веса столбцов, содержащихся в Continuous_features и categorical_features.

model = tf.estimator.LinearClassifier(
    n_classes = 2,
    model_dir="ongoing/train", 
    feature_columns=categorical_features+ continuous_features)

Результат

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': 
<tensorflow.python.training.server_lib.ClusterSpec object at 0x181f24c898>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

Теперь, когда классификатор определен, вы можете создать функцию ввода. Метод тот же, что и в уроке по линейному регрессору. Здесь вы используете размер пакета 128 и перемешиваете данные.

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)

Вы создаете функцию с аргументами, необходимыми для линейной оценки, т. е. количеством эпох, количеством пакетов, и перетасовываете набор данных или заметку. Поскольку вы используете Панды Чтобы передать данные в модель, вам необходимо определить переменные X как фрейм данных pandas. Обратите внимание, что вы перебираете все данные, хранящиеся в FEATURES.

Давайте обучим модель с помощью объекта model.train. Вы используете ранее определенную функцию, чтобы передать в модель соответствующие значения. Обратите внимание, что вы установили размер пакета на 128, а количество эпох — на «Нет». Модель будет обучена более чем тысяче шагов.

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

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0x181f223630>

Обратите внимание, что потери впоследствии уменьшались на протяжении последних 100 шагов, т. е. с 901 до 1000.

Итоговая потеря после тысячи итераций равна 5444. Вы можете оценить свою модель на тестовом наборе и посмотреть производительность. Чтобы оценить производительность вашей модели, вам необходимо использовать объект Assessment. Вы загружаете модель тестовым набором и устанавливаете количество эпох равным 1, т. е. данные поступают в модель только один раз.

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

{'accuracy': 0.7615626,
 'accuracy_baseline': 0.76377374,
 'auc': 0.63300294,
 'auc_precision_recall': 0.50891197,
 'average_loss': 47.12155,
 'global_step': 1000,
 'label/mean': 0.23622628,
 'loss': 5993.6406,
 'precision': 0.49401596,
 'prediction/mean': 0.18454961,
 'recall': 0.38637546}

TensorFlow возвращает все метрики, которые вы изучили в теоретической части. Неудивительно, что точность высокая из-за несбалансированной метки. На самом деле модель работает немного лучше, чем случайное предположение. Представьте, что модель прогнозирует все домохозяйства с доходом ниже 50 тысяч, тогда точность модели составит 70 процентов. При более внимательном анализе можно увидеть, что прогнозирование и отзыв довольно низкие.

Шаг 4) Улучшите модель

Теперь, когда у вас есть эталонная модель, вы можете попытаться улучшить ее, то есть повысить точность. В предыдущем уроке вы узнали, как повысить точность прогнозирования с помощью термина взаимодействия. В этом уроке вы вернетесь к этой идее, добавив в регрессию полиномиальный член.

Полиномиальная регрессия полезна, когда данные нелинейны. Существует два способа уловить нелинейность данных.

  • Добавить полиномиальный член
  • Превратите непрерывную переменную в категориальную переменную.

Полиномиальный член

На рисунке ниже вы можете увидеть, что такое полиномиальная регрессия. Это уравнение с X переменными разной степени. Полиномиальная регрессия второй степени имеет две переменные: X и X в квадрате. Третья степень имеет три переменные: X, X.2, и Х3

Полиномиальная регрессия
Что такое полиномиальная регрессия

Ниже мы построили график с двумя переменными X и Y. Очевидно, что связь не является линейной. Если мы добавим линейную регрессию, мы увидим, что модель не может уловить закономерность (изображение слева).

Теперь посмотрите на левую картинку с рисунка ниже: мы добавили к регрессии пять членов (то есть y=x+x2+x3+x4+x5. Модель теперь лучше отражает узор. В этом сила полиномиальной регрессии.

Полиномиальная регрессия

Вернемся к нашему примеру. Возраст не находится в линейной зависимости от дохода. Ранний возраст может иметь фиксированный доход, близкий к нулю, поскольку дети или молодые люди не работают. Затем он увеличивается в трудоспособном возрасте и снижается при выходе на пенсию. Обычно это форма перевернутой буквы U. Один из способов уловить эту закономерность — добавить к регрессии степень двойки.

Посмотрим, повысит ли это точность.

Вам необходимо добавить этот новый объект в набор данных и в список непрерывных объектов.

Вы добавляете новую переменную в набор обучающих и тестовых данных, поэтому удобнее писать функцию.

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

Функция имеет 3 аргумента:

  • df_t: определить обучающий набор
  • df_te: определить набор тестов
  • var_name = 'age': Определите переменную для преобразования.

Вы можете использовать объект pow(2) для возведения переменной age в квадрат. Обратите внимание, что новая переменная называется «новая».

Теперь, когда функция Square_var написана, вы можете создавать новые наборы данных.

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

Как видите, у нового набора данных есть еще одна особенность.

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

Квадратная переменная называется новой в наборе данных. Вам необходимо добавить его в список непрерывных функций.

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]

Внимание что вы изменили каталог Графа. Вы не можете обучать разные модели в одном каталоге. Это означает, что вам нужно изменить путь аргумента model_dir. Если вы этого не сделаете, TensorFlow выдаст ошибку.

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

Теперь, когда классификатор разработан с использованием нового набора данных, вы можете обучать и оценивать модель.

model_1.train(input_fn=get_input_fn(df_train, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into ongoing/train1/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 81.487
INFO:tensorflow:loss = 70077.66, step = 101 (1.228 sec)
INFO:tensorflow:global_step/sec: 111.169
INFO:tensorflow:loss = 49522.082, step = 201 (0.899 sec)
INFO:tensorflow:global_step/sec: 128.91
INFO:tensorflow:loss = 107120.57, step = 301 (0.776 sec)
INFO:tensorflow:global_step/sec: 132.546
INFO:tensorflow:loss = 12814.152, step = 401 (0.755 sec)
INFO:tensorflow:global_step/sec: 162.194
INFO:tensorflow:loss = 19573.898, step = 501 (0.617 sec)
INFO:tensorflow:global_step/sec: 204.852
INFO:tensorflow:loss = 26381.986, step = 601 (0.488 sec)
INFO:tensorflow:global_step/sec: 188.923
INFO:tensorflow:loss = 23417.719, step = 701 (0.529 sec)
INFO:tensorflow:global_step/sec: 192.041
INFO:tensorflow:loss = 23946.049, step = 801 (0.521 sec)
INFO:tensorflow:global_step/sec: 197.025
INFO:tensorflow:loss = 3309.5786, step = 901 (0.507 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train1/model.ckpt.
INFO:tensorflow:Loss for final step: 28861.898.

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0x1820f04c88>
model_1.evaluate(input_fn=get_input_fn(df_test_new, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:37
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:39
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7944229, accuracy_baseline = 0.76377374, auc = 0.6093755, auc_precision_recall = 0.54885805, average_loss = 111.0046, global_step = 1000, label/mean = 0.23622628, loss = 14119.265, precision = 0.6682401, prediction/mean = 0.09116262, recall = 0.2576703

{'accuracy': 0.7944229,
 'accuracy_baseline': 0.76377374,
 'auc': 0.6093755,
 'auc_precision_recall': 0.54885805,
 'average_loss': 111.0046,
 'global_step': 1000,
 'label/mean': 0.23622628,
 'loss': 14119.265,
 'precision': 0.6682401,
 'prediction/mean': 0.09116262,
 'recall': 0.2576703}

Квадратная переменная улучшила точность с 0.76 до 0.79. Давайте посмотрим, сможете ли вы добиться большего, объединив термин «группировка» и «взаимодействие».

Бакетизация и взаимодействие

Как вы видели ранее, линейный классификатор не может правильно отразить закономерность возраста и дохода. Это потому, что он изучает один вес для каждой функции. Чтобы упростить работу классификатора, вы можете скопировать функцию. Группирование преобразует числовой признак в несколько определенных в зависимости от диапазона, в который он попадает, и каждый из этих новых признаков указывает, попадает ли возраст человека в этот диапазон.

Благодаря этим новым функциям линейная модель может фиксировать взаимосвязь, изучая разные веса для каждого сегмента.

В TensorFlow это делается с помощью Bucketized_column. Вам нужно добавить диапазон значений в границах.

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

Вы уже знаете, что возраст нелинейно зависит от дохода. Другой способ улучшить модель — через взаимодействие. Говоря словами TensorFlow, это скрещивание функций. Пересечение функций — это способ создания новых функций, которые представляют собой комбинации существующих, что может быть полезно для линейного классификатора, который не может моделировать взаимодействия между функциями.

Вы можете разбить возраст по другому признаку, например по образованию. То есть некоторые группы, вероятно, будут иметь высокий доход, а другие — низкий (подумайте о аспиранте).

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

Чтобы создать столбец перекрестных объектов, вы используете crossed_column с переменными для пересечения в скобках. hash_bucket_size указывает максимальные возможности пересечения. Чтобы создать взаимодействие между переменными (хотя бы одна переменная должна быть категориальной), вы можете использовать tf.feature_column.crossed_column. Чтобы использовать этот объект, вам нужно добавить в квадратные скобки переменную для взаимодействия и второй аргумент — размер сегмента. Размер сегмента — это максимально возможное количество групп внутри переменной. Здесь вы устанавливаете 1000, так как не знаете точное количество групп.

age_buckets необходимо возвести в квадрат, прежде чем добавлять его в столбцы объектов. Вы также добавляете новые функции в столбцы функций и готовите оценщик.

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)

Результат

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train3', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1823021be0>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
FEATURES_imp = ['age','workclass', 'education', 'education_num', 'marital',
                'occupation', 'relationship', 'race', 'sex', 'native_country', 'new']

def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES_imp}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)

Вы готовы оценить новую модель и посмотреть, улучшит ли она точность.

model_imp.train(input_fn=get_input_fn(df_train_new, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
									  
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into ongoing/train3/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 94.969
INFO:tensorflow:loss = 50.334488, step = 101 (1.054 sec)
INFO:tensorflow:global_step/sec: 242.342
INFO:tensorflow:loss = 56.153225, step = 201 (0.414 sec)
INFO:tensorflow:global_step/sec: 213.686
INFO:tensorflow:loss = 45.792007, step = 301 (0.470 sec)
INFO:tensorflow:global_step/sec: 174.084
INFO:tensorflow:loss = 37.485672, step = 401 (0.572 sec)
INFO:tensorflow:global_step/sec: 191.78
INFO:tensorflow:loss = 56.48449, step = 501 (0.524 sec)
INFO:tensorflow:global_step/sec: 163.436
INFO:tensorflow:loss = 32.528934, step = 601 (0.612 sec)
INFO:tensorflow:global_step/sec: 164.347
INFO:tensorflow:loss = 37.438057, step = 701 (0.607 sec)
INFO:tensorflow:global_step/sec: 154.274
INFO:tensorflow:loss = 61.1075, step = 801 (0.647 sec)
INFO:tensorflow:global_step/sec: 189.14
INFO:tensorflow:loss = 44.69645, step = 901 (0.531 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train3/model.ckpt.
INFO:tensorflow:Loss for final step: 44.18133.

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0x1823021cf8>
model_imp.evaluate(input_fn=get_input_fn(df_test_new, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
									  
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:52
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train3/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:54
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.8358209, accuracy_baseline = 0.76377374, auc = 0.88401634, auc_precision_recall = 0.69599575, average_loss = 0.35122654, global_step = 1000, label/mean = 0.23622628, loss = 44.67437, precision = 0.68986726, prediction/mean = 0.23320661, recall = 0.55408216


{'accuracy': 0.8358209,
 'accuracy_baseline': 0.76377374,
 'auc': 0.88401634,
 'auc_precision_recall': 0.69599575,
 'average_loss': 0.35122654,
 'global_step': 1000,
 'label/mean': 0.23622628,
 'loss': 44.67437,
 'precision': 0.68986726,
 'prediction/mean': 0.23320661,
 'recall': 0.55408216}

Новый уровень точности составляет 83.58 процента. Это на четыре процента выше, чем у предыдущей модели.

Наконец, вы можете добавить термин регуляризации, чтобы предотвратить переобучение.

Шаг 5) Гиперпараметр: Лассо и хребет

Ваша модель может пострадать от переобучения or недостаточное оснащение.

  • Переобучение: модель не может обобщить прогноз на новые данные.
  • Недооснащение: модель не может отразить структуру данных. т. е. линейная регрессия, когда данные нелинейны

Когда модель имеет много параметров и относительно небольшой объем данных, это приводит к плохим прогнозам. Представьте себе, что у одной группы всего три наблюдения; модель рассчитает вес для этой группы. Вес используется для прогнозирования; если наблюдения тестового набора для этой конкретной группы полностью отличаются от обучающего набора, то модель сделает неверный прогноз. Во время оценки с использованием обучающего набора точность хорошая, но не очень хорошая для тестового набора, поскольку вычисленные веса не являются истинными для обобщения шаблона. В этом случае он не делает разумного прогноза на основе невидимых данных.

Чтобы предотвратить переобучение, регуляризация дает вам возможность контролировать такую ​​сложность и делать ее более обобщаемой. Существует два метода регуляризации:

  • L1: Лассо
  • L2: хребет

В TensorFlow вы можете добавить эти два гиперпараметра в оптимизаторе. Например, чем выше гиперпараметр L2, тем вес имеет тенденцию быть очень низким и близким к нулю. Подобранная линия будет очень плоской, а значение L2, близкое к нулю, означает, что веса близки к обычной линейной регрессии.

Вы можете самостоятельно попробовать разные значения гиперпараметров и посмотреть, сможете ли вы повысить уровень точности.

Внимание что если вы измените гиперпараметр, вам нужно удалить папку continue/train4, иначе модель запустится с ранее обученной моделью.

Посмотрим как с точностью с хайпом

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

ВЫХОД

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

ВЫХОД

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


<tensorflow.python.estimator.canned.linear.LinearClassifier at 0x181ff39e48>
model_regu.evaluate(input_fn=get_input_fn(df_test_new, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Результат

INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:29:07
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train4/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:29:09
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.83833915, accuracy_baseline = 0.76377374, auc = 0.8869794, auc_precision_recall = 0.7014905, average_loss = 0.34691378, global_step = 1000, label/mean = 0.23622628, loss = 44.12581, precision = 0.69720596, prediction/mean = 0.23662092, recall = 0.5579823





{'accuracy': 0.83833915,
 'accuracy_baseline': 0.76377374,
 'auc': 0.8869794,
 'auc_precision_recall': 0.7014905,
 'average_loss': 0.34691378,
 'global_step': 1000,
 'label/mean': 0.23622628,
 'loss': 44.12581,
 'precision': 0.69720596,
 'prediction/mean': 0.23662092,
 'recall': 0.5579823}

С помощью этого гиперпараметра вы немного увеличиваете показатели точности. В следующем уроке вы узнаете, как улучшить линейный классификатор с помощью метода ядра.

Резюме

Чтобы обучить модель, вам необходимо:

  • Определите характеристики: Независимые переменные: X
  • Определите метку: Зависимая переменная: y
  • Создайте поезд/тестовый набор
  • Определите первоначальный вес
  • Определите функцию потерь: MSE
  • Оптимизация модели: градиентный спуск
  • Определение:
    • Скорость обучения
    • Номер эпохи
    • Размер партии
    • Номер класса

В этом руководстве вы узнали, как использовать высокоуровневый API для классификатора линейной регрессии. Вам необходимо определить:

  1. Функциональные столбцы. Если непрерывно: tf.feature_column.numeric_column(). Вы можете заполнить список с помощью понимания списка Python
  2. Оценщик: tf.estimator.LinearClassifier(feature_columns, model_dir, n_classes = 2)
  3. Функция для импорта данных, размера пакета и эпохи: input_fn()

После этого вы готовы обучаться, оценивать и делать прогнозы с помощью train(), Assessment() и Predict().

Чтобы улучшить производительность модели, вы можете:

  • Используйте полиномиальную регрессию
  • Условия взаимодействия: tf.feature_column.crossed_column
  • Добавить параметр регуляризации