Бінарна класифікація 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: Прогнозовані значення правильно визначені як фактично позитивні
  • FP: Прогнозовані значення неправильно передбачили фактичний позитивний результат. тобто негативні значення прогнозуються як позитивні
  • FN: False Negative: Позитивні значення передбачаються як негативні
  • TN: True Negative: Прогнозовані значення правильно визначені як фактично негативні

З матриці плутанини легко порівняти фактичний клас і прогнозований клас.

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

Матриця плутанини дає хороше уявлення про справжні позитивні та хибні позитивні результати. У деяких випадках краще мати більш стислі показники.

Точність

Показник точності показує точність позитивного класу. Він вимірює, наскільки вірогідним є прогноз позитивного класу.

Точність

Максимальний бал – 1, коли класифікатор ідеально класифікує всі позитивні значення. Сама по собі точність не дуже корисна, оскільки вона ігнорує негативний клас. Метрика зазвичай поєднується з метрикою Recall. Пригадування також називають чутливістю або справжньою позитивною швидкістю.

Чутливість

Чутливість обчислює співвідношення правильно виявлених позитивних класів. Цей показник показує, наскільки добре модель розпізнає позитивний клас.

Чутливість

Лінійний класифікатор із TensorFlow

Для цього підручника ми будемо використовувати набір даних перепису. Мета полягає в тому, щоб використовувати змінні в наборі даних перепису для прогнозування рівня доходу. Зверніть увагу, що дохід є двійковою змінною

  • зі значенням 1, якщо дохід > 50 тис
  • 0, якщо дохід < 50 тис.

Ця змінна є вашою міткою

Цей набір даних включає вісім категоріальних змінних:

  • робоче місце
  • освіту
  • подружній
  • окупація
  • відносини
  • гонки
  • секс
  • Батьківщина

крім того, шість неперервних змінних:

  • вік
  • fnlwgt
  • номер_освіти
  • приріст капіталу
  • капітал_збиток
  • години_тиждень

Завдяки цьому прикладу класифікації 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 тис. і XNUMX XNUMX вище. Співвідношення майже однакове для тестового набору. Щоб дізнатися більше, зверніться до цього підручника про аспекти.

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. Він призначатиме ідентифікатор для всіх унікальних словникових списків.

Наприклад, якщо змінна status має три різні значення:

  • чоловік
  • Дружина
  • Single

Тоді буде присвоєно три ідентифікатора. Наприклад, чоловік матиме ID 1, дружина ID 2 і так далі.

Для ілюстрації ви можете використовувати цей код для перетворення змінної об’єкта в категорійний стовпець у TensorFlow.

Ознака статі може мати лише два значення: чоловіча чи жіноча. Коли ми будемо перетворювати ознаку статі, Tensorflow створить 2 нові стовпці, один для чоловічої та інший для жіночої статі. Якщо стать дорівнює чоловічій, тоді новий стовпець чоловічий дорівнюватиме 1, а жіночий — 0. Цей приклад показано в таблиці нижче:

рядків секс після перетворення чоловік жінка
1 чоловік => 1 0
2 чоловік => 1 0
3 жінка => 0 1

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

Нижче ми додали 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.

Модель обчислить ваги стовпців, що містяться в безперервних_ознаках і категоричних ознаках.

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. Ви можете оцінити свою модель на тестовому наборі та побачити продуктивність. Щоб оцінити продуктивність вашої моделі, вам потрібно використовувати об’єкт evaluate. Ви заповнюєте модель тестовим набором і встановлюєте кількість епох на 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, X2і X3

Поліноміальна регресія
Що таке поліноміальна регресія

Нижче ми побудували графік із двома змінними, 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 = 'вік': визначте змінну для трансформації

Ви можете використовувати об’єкт pow(2), щоб звести змінну вік у квадрат. Зауважте, що нова змінна називається "нова"

Тепер, коли функція 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]

Примітка: що ви змінили каталог Graph. Ви не можете навчати різні моделі в одному каталозі. Це означає, що вам потрібно змінити шлях до аргументу 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, близький до нуля, означає, що ваги близькі до звичайної лінійної регресії.

Ви можете самостійно спробувати різні значення гіперпараметрів і перевірити, чи зможете ви підвищити рівень точності.

Примітка: що якщо ви змінюєте гіперпараметр, вам потрібно видалити папку ongoing/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(), evaluate() і predict()

Щоб підвищити продуктивність моделі, ви можете:

  • Використовуйте поліноміальну регресію
  • Термін взаємодії: tf.feature_column.crossed_column
  • Додати параметр регулярізації