Лінійна регресія TensorFlow із аспектом і терміном взаємодії

У цьому посібнику ви дізнаєтесь, як перевірити дані та підготувати їх для створення простого завдання лінійної регресії.

Цей підручник складається з двох частин:

  • Шукайте взаємодії
  • Випробуйте модель

У попередній навчальний посібник, ви використовували набір даних Бостона, щоб оцінити середню ціну будинку. Бостонський набір даних має невеликий розмір, лише 506 спостережень. Цей набір даних вважається еталоном для випробування нових алгоритмів лінійної регресії.

Набір даних складається з:

Змінна Опис
zn Частка житлової землі, зонованої для ділянок понад 25,000 XNUMX кв.
інд Частка акрів нероздрібного бізнесу на місто.
nox концентрація оксидів азоту
rm середня кількість кімнат на житло
вік частка квартир, які займають власники, побудованих до 1940 року
відстань зважені відстані до п’яти центрів зайнятості Бостона
податок ставка податку на повну вартість майна за 10,000 XNUMX доларів США
ptratio співвідношення учень/вчитель по місту
медв Середня вартість будинків, які займають власники, у тисячах доларів
крим Рівень злочинності на душу населення по містах
ч Фіктивна змінна Charles River (1, якщо межує річка; 0 інакше)
B частка чорношкірих у місті

У цьому посібнику ми оцінимо середню ціну за допомогою лінійного регресора, але зосередимося на одному конкретному процесі навчання за допомогою машини: «підготовка даних».

Модель узагальнює шаблон у даних. Щоб зафіксувати такий візерунок, його потрібно спочатку знайти. Хорошою практикою є проведення аналізу даних перед запуском будь-якого алгоритму машинного навчання.

Від правильного вибору функцій залежить успіх вашої моделі. Уявіть, що ви намагаєтесь оцінити заробітну плату людей, якщо ви не включите стать як коваріату, ви отримаєте погану оцінку.

Інший спосіб удосконалити модель — поглянути на кореляцію між незалежною змінною. Повернемося до прикладу. Ви можете розглядати освіту як чудовий кандидат для прогнозування заробітної плати, а також професії. Слід чесно сказати, що професія залежить від рівня освіти, а саме вища освіта часто веде до кращої професії. Якщо ми узагальнимо цю ідею, ми можемо сказати, що кореляція між залежною змінною та пояснювальною змінною може бути посилена ще однією пояснювальною змінною.

Щоб охопити обмежений вплив освіти на професію, ми можемо використати термін взаємодії.

Термін взаємодії

Якщо ви подивитеся на рівняння заробітної плати, воно виглядає так:

Термін взаємодії

If Термін взаємодії є позитивним, то це означає, що додатковий рівень освіти дає більший приріст медіанної вартості будинку для високого рівня зайнятості. Іншими словами, існує ефект взаємодії між освітою та професією.

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

Зведена статистика

Перш ніж перейти до моделі, ви можете виконати кілька кроків. Як згадувалося раніше, модель є узагальненням даних. Найкраще зрозуміти дані та зробити прогноз. Якщо ви не знаєте своїх даних, у вас мізерні шанси покращити свою модель.

Як перший крок, завантажте дані як фрейм даних pandas і створіть набір для навчання та набір для тестування.

Поради: для цього підручника вам потрібно встановити matplotlit і seaborn Python. Можна встановлювати Python пакет на льоту с Jupyter. Ви Не слід зробити це

!conda install -- yes matplotlib

але

import sys
!{sys.executable} -m pip install matplotlib # Already installed
!{sys.executable} -m pip install seaborn 

Зауважте, що цей крок необов’язковий, якщо у вас встановлено matplotlib і seaborn.

Matplotlib — це бібліотека для створення графіка Python. Seaborn — це бібліотека статистичної візуалізації, створена на основі matplotlib. Він забезпечує привабливі та красиві ділянки.

Наведений нижче код імпортує необхідні бібліотеки.

import pandas as pd
from sklearn import datasets
import tensorflow as tf
from sklearn.datasets import load_boston
import numpy as np

Бібліотека sklearn включає Бостонський набір даних. Ви можете викликати його API, щоб імпортувати дані.

boston = load_boston()
df = pd.DataFrame(boston.data)

Ім'я об'єкта зберігається в об'єкті feature_names в масиві.

boston.feature_names

Вихід

array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')

Ви можете перейменувати стовпці.

df.columns = boston.feature_names
df['PRICE'] = boston.target
df.head(2)

Лінійна регресія з аспектом і терміном взаємодії

Ви перетворюєте змінну CHAS як рядкову змінну та позначаєте її так, якщо CHAS = 1, і ні, якщо CHAS = 0

df['CHAS'] = df['CHAS'].map({1:'yes', 0:'no'})
df['CHAS'].head(5)
0    no
1    no
2    no
3    no
4    no
Name: CHAS, dtype: object

За допомогою pandas розділити набір даних просто. Ви випадковим чином ділите набір даних на 80 відсотків навчального набору та 20 відсотків тестового набору. Панди мають вбудовану функцію витрат для поділу вибірки кадру даних.

Перший параметр frac має значення від 0 до 1. Ви встановлюєте значення 0.8, щоб випадково вибрати 80 відсотків кадру даних.

Random_state дозволяє повертати однаковий кадр даних для всіх.

### Create train/test set
df_train=df.sample(frac=0.8,random_state=200)
df_test=df.drop(df_train.index)

Ви можете отримати форму даних. Вона повинна бути:

  • Набір поїздів: 506*0.8 = 405
  • Тестовий набір: 506*0.2 = 101
print(df_train.shape, df_test.shape)

Вихід

(405, 14) (101, 14)
df_test.head(5)

Вихід

КРИМ ZN ІНДУС ЧАС NOX RM ВІК DIS RAD TAX PTRATIO B LSTAT ЦІНА
0 0.00632 18.0 2.31 немає 0.538 6.575 65.2 4.0900 1.0 296.0 15.3 396.90 4.98 24.0
1 0.02731 0.0 7.07 немає 0.469 6.421 78.9 4.9671 2.0 242.0 17.8 396.90 9.14 21.6
3 0.03237 0.0 2.18 немає 0.458 6.998 45.8 6.0622 3.0 222.0 18.7 394.63 2.94 33.4
6 0.08829 12.5 7.87 немає 0.524 6.012 66.6 5.5605 5.0 311.0 15.2 395.60 12.43 22.9
7 0.14455 12.5 7.87 немає 0.524 6.172 96.1 5.9505 5.0 311.0 15.2 396.90 19.15 27.1

Дані безладні; він часто незбалансований і всипаний викидами значень, які перешкоджають аналізу та навчанню машинного навчання.

Першим кроком до очищення набору даних є розуміння того, де його потрібно очистити. Очищення набору даних може бути складним завданням, особливо будь-яким узагальненим способом

Дослідницька команда Google розробила інструмент для цієї роботи під назвою Грані які допомагають візуалізувати дані та нарізати їх усіма способами. Це хороша відправна точка для розуміння того, як розміщено набір даних.

Фасети дозволяють вам знайти, де дані виглядають не зовсім так, як ви думаєте.

За винятком веб-програми, Google дозволяє легко вставити набір інструментів у Jupyter зошит.

У Facets є дві частини:

  • Огляд аспектів
  • Facets Deep Dive

Огляд аспектів

Facets Overview дає огляд набору даних. Огляд аспектів розбиває стовпці даних на рядки, що показують важливу інформацію

  1. відсоток відсутніх спостережень
  2. мінімальне та максимальне значення
  3. такі статистичні дані, як середнє, медіана та стандартне відхилення.
  4. Він також додає стовпець, який показує відсоток значень, які є нулями, що корисно, коли більшість значень є нулями.
  5. Ці розподіли можна побачити в тестовому наборі даних, а також у навчальному наборі для кожної функції. Це означає, що ви можете ще раз перевірити, чи розподіл тесту подібний до даних навчання.

Це принаймні мінімум, який потрібно зробити перед будь-яким завданням машинного навчання. За допомогою цього інструменту ви не пропустите цей важливий крок, і він висвітлює деякі аномалії.

Facets Deep Dive

Facets Deep Dive — класний інструмент. Це дозволяє отримати певну ясність у вашому наборі даних і повністю збільшити масштаб, щоб побачити окрему частину даних. Це означає, що ви можете розділяти дані по рядках і стовпцях по будь-якій функції набору даних.

Ми будемо використовувати ці два інструменти з бостонським набором даних.

Примітка:: Ви не можете використовувати Facets Overview і Facets Deep Dive одночасно. Щоб змінити інструмент, спочатку потрібно очистити блокнот.

Встановити Facet

Ви можете використовувати веб-програму Facet для більшості аналізів. У цьому посібнику ви побачите, як використовувати його в межах a Jupyter Notebook.

Перш за все, вам потрібно встановити nbextensions. Це робиться за допомогою цього коду. Ви скопіюєте та вставите наступний код у термінал своєї машини.

pip install jupyter_contrib_nbextensions

Відразу після цього вам потрібно клонувати репозиторії на вашому комп’ютері. У вас є два варіанти:

Варіант 1) Скопіюйте та вставте цей код у термінал (Рекомендується)

Якщо на вашій машині не встановлено Git, перейдіть за цією URL-адресою https://git-scm.com/download/win і дотримуйтесь інструкції. Закінчивши, ви можете використати команду git у терміналі для користувача Mac або запит Anaconda для Windows користувач

git clone https://github.com/PAIR-code/facets

Варіант 2) Відкрийте https://github.com/PAIR-code/facets і завантажити репозиторії.

Встановити Facet

Якщо ви виберете перший варіант, файл опиниться у файлі завантаження. Ви можете дозволити файлу завантажитися або перетягнути його в інший шлях.

Ви можете перевірити, де зберігаються грані, за допомогою цього командного рядка:

echo `pwd`/`ls facets`

Тепер, коли ви знайшли Facets, вам потрібно встановити його Jupyter Ноутбук. Вам потрібно встановити робочий каталог на шлях, де розташовані грані.

Ваш поточний робочий каталог і розташування файлу Facets zip мають бути такими ж.

Встановити Facet

Вам потрібно вказати робочий каталог на Facet:

cd facets

Щоб установити Facets в Jupyter, у вас є два варіанти. Якщо ви встановили Jupyter з Conda для всіх користувачів, скопіюйте цей код:

можна використовувати jupyter nbextension install facets-dist/

jupyter nbextension install facets-dist/

В іншому випадку використовуйте:

jupyter nbextension install facets-dist/ --user

Гаразд, усе готово. Давайте відкриємо Facet Overview.

огляд

Огляд використовує a Python сценарій для обчислення статистики. Вам потрібно імпортувати сценарій під назвою generic_feature_statistics_generator Jupyter. Не хвилюйтеся; сценарій знаходиться у файлах фасетів.

Вам потрібно знайти його шлях. Це легко робиться. Ви відкриваєте facets, відкриваєте файл facets_overview і потім python. Скопіюйте шлях

Оглядовий аспект

Після цього поверніться до Jupyterі напишіть наступний код. Змініть шлях '/Users/Thomas/facets/facets_overview/python' на свій шлях.

# Add the facets overview python code to the python path# Add t 
import sys
sys.path.append('/Users/Thomas/facets/facets_overview/python')

Ви можете імпортувати сценарій за допомогою наведеного нижче коду.

from generic_feature_statistics_generator import 
GenericFeatureStatisticsGenerator

У windows такий самий код стає

import sys
sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python")

from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator

Щоб обчислити статистику функції, потрібно використовувати функцію GenericFeatureStatisticsGenerator(), і ви використовуєте об’єкт ProtoFromDataFrames. Ви можете передати кадр даних у словник. Наприклад, якщо ми хочемо створити підсумкову статистику для набору поїздів, ми можемо зберегти інформацію в словнику та використовувати її в об’єкті «ProtoFromDataFrames».

  • 'name': 'train', 'table': df_train

Ім’я – це ім’я таблиці, що відображається, і ви використовуєте ім’я таблиці, для якої хочете обчислити зведення. У вашому прикладі таблиця, що містить дані, є df_train

# Calculate the feature statistics proto from the datasets and stringify it for use in facets overview
import base64

gfsg = GenericFeatureStatisticsGenerator()

proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train},
                                  {'name': 'test', 'table': df_test}])

#proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train}])
protostr = base64.b64encode(proto.SerializeToString()).decode("utf-8")

Нарешті, ви просто скопіюєте та вставите код нижче. Код надходить безпосередньо з GitHub. Ви повинні побачити це:

Оглядовий аспект

# Display the facets overview visualization for this data# Displ 
from IPython.core.display import display, HTML

HTML_TEMPLATE = """<link rel="import" href="/uk/nbextensions/facets-dist/facets-jupyter.html" >
        <facets-overview id="elem"></facets-overview>
        <script>
          document.querySelector("#elem").protoInput = "{protostr}";
        </script>"""
html = HTML_TEMPLATE.format(protostr=protostr)
display(HTML(html))

Графік

Перевіривши дані та їх розподіл, можна побудувати кореляційну матрицю. Кореляційна матриця обчислює коефіцієнт Пірсона. Цей коефіцієнт пов’язаний між -1 і 1, причому позитивне значення вказує на позитивну кореляцію, а негативне значення – на негативну кореляцію.

Вам цікаво дізнатися, які змінні можуть бути хорошими кандидатами на умови взаємодії.

## Choose important feature and further check with Dive
%matplotlib inline  
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="ticks")
# Compute the correlation matrix
corr = df.corr('pearson')
# Generate a mask for the upper triangle
mask = np.zeros_like(corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(11, 9))

# Generate a custom diverging colormap
cmap = sns.diverging_palette(220, 10, as_cmap=True)

# Draw the heatmap with the mask and correct aspect ratio
sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,annot=True,
            square=True, linewidths=.5, cbar_kws={"shrink": .5})

Вихід

<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518>

PNG

Фасетний графік

З матриці можна побачити:

  • LSTAT
  • RM

Тісно корелюють із ЦІНОЮ. Іншою цікавою особливістю є сильна позитивна кореляція між NOX та INDUS, що означає, що ці дві змінні рухаються в одному напрямку. Крім того, є також кореляція з ЦІНОЮ. DIS також сильно корелює з IND та NOX.

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

Ви можете піти трохи глибше, побудувавши парну сітку. Це більш детально проілюструє карту кореляції, яку ви побудували раніше.

Парну сітку ми складаємо наступним чином:

  • Верхня частина: точкова діаграма з підігнаною лінією
  • Діагональ: графік щільності ядра
  • Нижня частина: багатовимірний графік щільності ядра

Ви обираєте фокус на чотирьох незалежних змінних. Вибір відповідає змінним із сильною кореляцією з ЦІНОЮ

  • ІНДУС
  • NOX
  • RM
  • LSTAT

до того ж ЦІНА.

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

attributes = ["PRICE", "INDUS", "NOX", "RM", "LSTAT"]

g = sns.PairGrid(df[attributes])
g = g.map_upper(sns.regplot, color="g")
g = g.map_lower(sns.kdeplot,cmap="Reds", shade=True, shade_lowest=False)
g = g.map_diag(sns.kdeplot)

Вихід

Фасетний графік

Почнемо з верхньої частини:

  • Ціна негативно корелює з INDUS, NOX і LSTAT; позитивно корелює з RM.
  • Існує невелика нелінійність LSTAT і PRICE
  • Існує пряма лінія, коли ціна дорівнює 50. З опису набору даних PRICE було скорочено до значення 50

Діагональ

  • Здається, що NOX має два кластери: один близько 0.5 і один близько 0.85.

Щоб дізнатися більше про це, ви можете подивитися на нижню частину. Багатовимірна щільність ядра цікава в певному сенсі, оскільки вона забарвлює там, де знаходиться більшість точок. Різниця з діаграмою розсіювання малює щільність ймовірності, навіть якщо в наборі даних немає точки для даної координати. Коли колір сильніший, це вказує на високу концентрацію точки навколо цієї області.

Якщо ви перевірите багатовимірну щільність для INDUS та NOX, ви побачите позитивну кореляцію та два кластери. Коли частка промисловості вище 18, концентрація оксидів азоту вище 0.6.

Ви можете подумати про те, щоб додати взаємодію між INDUS і NOX у лінійну залежність.

Нарешті, ви можете використовувати другий інструмент, створений Google, Facets Deep Dive. Інтерфейс розділений на чотири основні розділи. Центральна область у центрі — це масштабоване відображення даних. У верхній частині панелі є спадне меню, у якому ви можете змінити розташування даних, керуючи огранюванням, розташуванням і кольором. Праворуч є детальний перегляд певного рядка даних. Це означає, що ви можете клацнути будь-яку точку даних у центральній візуалізації, щоб побачити деталі про цю конкретну точку даних.

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

Одним із способів вирішення цієї проблеми є створення категоріальної змінної. Тобто ми можемо створити двовимірний графік із кольоровою точкою. Ви можете розділити змінну PRICE на чотири категорії, кожна з яких є квартилем (тобто 2, 0.25, 0.5). Ви називаєте цю нову змінну Q_PRICE.

## Check non linearity with important features
df['Q_PRICE'] =  pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"])
## Show non linearity between RM and LSTAT
ax = sns.lmplot(x="DIS", y="INDUS", hue="Q_PRICE", data=df, fit_reg = False,palette="Set3")

Фасетний графік

Facets Deep Dive

Щоб відкрити Deep Dive, вам потрібно перетворити дані у формат json. Панди як об’єкт для цього. Ви можете використовувати to_json після набору даних Pandas.

Перший рядок коду визначає розмір набору даних.

df['Q_PRICE'] =  pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"])
sprite_size = 32 if len(df.index)>50000 else 64
jsonstr = df.to_json(orient='records')

Наведений нижче код походить від Google GitHub. Після запуску коду ви зможете побачити це:

Facets Deep Dive

# Display thde Dive visualization for this data
from IPython.core.display import display, HTML

# Create Facets template  
HTML_TEMPLATE = """<link rel="import" href="/uk/nbextensions/facets-dist/facets-jupyter.html">
        <facets-dive sprite-image-width="{sprite_size}" sprite-image-height="{sprite_size}" id="elem" height="600"></facets-dive>
        <script>
          document.querySelector("#elem").data = {jsonstr};
        </script>"""

# Load the json dataset and the sprite_size into the template
html = HTML_TEMPLATE.format(jsonstr=jsonstr, sprite_size=sprite_size)

# Display the template
display(HTML(html))

Вас цікавить, чи існує зв’язок між галузевим курсом, концентрацією оксиду, відстанню до центру зайнятості та ціною будинку.

Для цього ви спочатку розділяєте дані за галузевим діапазоном і кольором за допомогою квартиля ціни:

  • Виберіть огранювання X і виберіть INDUS.
  • Виберіть Дисплей і виберіть DIS. Він розфарбує крапки квартилем ціни будинку

тут темніші кольори означають, що відстань до першого центру зайнятості велика.

Поки що це знову показує те, що ви знаєте, нижча галузева ставка, вища ціна. Тепер можна подивитися розбивку по INDUX, по NOX.

  • Виберіть огранювання Y і виберіть NOX.

Тепер ви бачите, що будинок далеко від першого центру зайнятості має найнижчу частку промисловості, а отже, і найнижчу концентрацію оксиду. Якщо ви вирішите відобразити тип із Q_PRICE і збільшити нижній лівий кут, ви зможете побачити, який це тип ціни.

У вас є ще одна підказка, що взаємодія між IND, NOX і DIS може бути хорошими кандидатами для вдосконалення моделі.

TensorFlow

У цьому розділі ви оціните лінійний класифікатор за допомогою API оцінок TensorFlow. Ви будете діяти наступним чином:

  • Підготуйте дані
  • Оцініть порівняльну модель: немає взаємодії
  • Оцініть модель із взаємодією

Пам’ятайте, що метою машинного навчання є мінімізація помилок. У цьому випадку виграє модель з найменшою середньоквадратичною помилкою. Оцінювач TensorFlow автоматично обчислює цей показник.

Дані про підготовку

У більшості випадків вам потрібно трансформувати дані. Ось чому Facets Overview захоплює. З підсумкової статистики ви побачили, що є викиди. Ці значення впливають на оцінки, оскільки вони не схожі на сукупність, яку ви аналізуєте. Викиди зазвичай зміщували результати. Наприклад, позитивний викид має тенденцію переоцінювати коефіцієнт.

Хорошим рішенням для вирішення цієї проблеми є стандартизація змінної. Стандартизація означає стандартне відхилення одиниці та середнє значення нуля. Процес стандартизації складається з двох етапів. Перш за все, він віднімає середнє значення змінної. По-друге, він ділить на стандартне відхилення, щоб розподіл мав одиничне стандартне відхилення.

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

Ви можете використовувати наведену нижче функцію, щоб масштабувати набір даних. Зверніть увагу, що ви не масштабуєте стовпець міток і категоричні змінні.

from sklearn import preprocessing
def standardize_data(df): 
    X_scaled = preprocessing.scale(df[['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
       'TAX', 'PTRATIO', 'B', 'LSTAT']])
    X_scaled_df = pd.DataFrame(X_scaled, columns = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
       'TAX', 'PTRATIO', 'B', 'LSTAT'])
    df_scale = pd.concat([X_scaled_df,
                       df['CHAS'],
                       df['PRICE']],axis=1, join='inner')
    return df_scale

Ви можете використовувати цю функцію для створення масштабованого набору поїздів/тестів.

df_train_scale = standardize_data(df_train)
df_test_scale = standardize_data(df_test)

Базова регресія: тест

Перш за все, ви тренуєте та тестуєте модель без взаємодії. Мета полягає в тому, щоб побачити показник продуктивності моделі.

Спосіб навчання моделі точно такий же, як у посібнику API високого рівня. Ви будете використовувати інструмент оцінки TensorFlow LinearRegressor.

Нагадуємо, що вам потрібно вибрати:

  • функції, які потрібно додати в модель
  • трансформувати особливості
  • побудувати лінійний регресор
  • побудувати функцію input_fn
  • тренувати модель
  • протестувати модель

Ви використовуєте всі змінні в наборі даних для навчання моделі. Загалом є безперервні змінні рівня та одна категоріальна змінна

## Add features to the bucket: 
### Define continuous list
CONTI_FEATURES  = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT']
CATE_FEATURES = ['CHAS']

Ви перетворюєте функції в числовий стовпець або категорійний стовпець

continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]
#categorical_features = tf.feature_column.categorical_column_with_hash_bucket(CATE_FEATURES, hash_bucket_size=1000)
categorical_features = [tf.feature_column.categorical_column_with_vocabulary_list('CHAS', ['yes','no'])]

Ви створюєте модель за допомогою linearRegressor. Ви зберігаєте модель у папці train_Boston

model = tf.estimator.LinearRegressor(    
	model_dir="train_Boston",     
    feature_columns=categorical_features + continuous_features)

Вихід

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train_Boston', '_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 0x1a19e76ac8>, '_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}

Кожен стовпець у даних поїзда або тесту перетворюється на тензор за допомогою функції get_input_fn

FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT', 'CHAS']
LABEL= 'PRICE'
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)

Ви оцінюєте модель за даними поїзда.

model.train(input_fn=get_input_fn(df_train_scale, 
                                      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 train_Boston/model.ckpt.
INFO:tensorflow:loss = 56417.703, step = 1
INFO:tensorflow:global_step/sec: 144.457
INFO:tensorflow:loss = 76982.734, step = 101 (0.697 sec)
INFO:tensorflow:global_step/sec: 258.392
INFO:tensorflow:loss = 21246.334, step = 201 (0.383 sec)
INFO:tensorflow:global_step/sec: 227.998
INFO:tensorflow:loss = 30534.78, step = 301 (0.439 sec)
INFO:tensorflow:global_step/sec: 210.739
INFO:tensorflow:loss = 36794.5, step = 401 (0.477 sec)
INFO:tensorflow:global_step/sec: 234.237
INFO:tensorflow:loss = 8562.981, step = 501 (0.425 sec)
INFO:tensorflow:global_step/sec: 238.1
INFO:tensorflow:loss = 34465.08, step = 601 (0.420 sec)
INFO:tensorflow:global_step/sec: 237.934
INFO:tensorflow:loss = 12241.709, step = 701 (0.420 sec)
INFO:tensorflow:global_step/sec: 220.687
INFO:tensorflow:loss = 11019.228, step = 801 (0.453 sec)
INFO:tensorflow:global_step/sec: 232.702
INFO:tensorflow:loss = 24049.678, step = 901 (0.432 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train_Boston/model.ckpt.
INFO:tensorflow:Loss for final step: 23228.568.


<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a19e76320>

Нарешті, ви оцінюєте продуктивність моделі на тестовому наборі

model.evaluate(input_fn=get_input_fn(df_test_scale, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Вихід

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-29-02:40:43
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train_Boston/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-29-02:40:43
INFO:tensorflow:Saving dict for global step 1000: average_loss = 86.89361, global_step = 1000, loss = 1650.9785


{'average_loss': 86.89361, 'global_step': 1000, 'loss': 1650.9785}

Втрата моделі становить 1650. Це показник, який потрібно перевершити в наступному розділі

Удосконалити модель: термін взаємодії

Під час першої частини підручника ви побачили цікавий зв’язок між змінними. Різні методи візуалізації показали, що INDUS і NOS пов’язані між собою і, навпаки, посилюють вплив на ціну. Не тільки взаємодія між INDUS і NOS впливає на ціну, але також цей ефект сильніший, коли він взаємодіє з DIS.

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

Вам потрібно додати два нові стовпці до кожного набору даних: навчання + тест. Для цього ви створюєте одну функцію для обчислення члена взаємодії та іншу для обчислення члена потрійної взаємодії. Кожна функція створює один стовпець. Після створення нових змінних ви можете об’єднати їх із навчальним набором і тестовим набором даних.

Перш за все, вам потрібно створити нову змінну для взаємодії між INDUS і NOX.

Наведена нижче функція повертає два кадри даних, тренування та тестування, із взаємодією між var_1 і var_2, у вашому випадку INDUS і NOX.

def interaction_term(var_1, var_2, name):
    t_train = df_train_scale[var_1]*df_train_scale[var_2]
    train = t_train.rename(name)
    t_test = df_test_scale[var_1]*df_test_scale[var_2]
    test = t_test.rename(name)
    return train, test

Ви зберігаєте два нових стовпці

interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS')
interation_ind_ns_train.shape
(325,)

По-друге, ви створюєте другу функцію для обчислення члена потрійної взаємодії.

def triple_interaction_term(var_1, var_2,var_3, name):
    t_train = df_train_scale[var_1]*df_train_scale[var_2]*df_train_scale[var_3]
    train = t_train.rename(name)
    t_test = df_test_scale[var_1]*df_test_scale[var_2]*df_test_scale[var_3]
    test = t_test.rename(name)
    return train, test
interation_ind_ns_dis_train, interation_ind_ns_dis_test= triple_interaction_term('INDUS', 'NOX', 'DIS','INDUS_NOS_DIS')

Тепер, коли у вас є всі необхідні стовпці, ви можете додати їх до набору даних для навчання та тестування. Ви називаєте ці два нові кадри даних:

  • df_train_new
  • df_test_new
df_train_new = pd.concat([df_train_scale,
                          interation_ind_ns_train,
                          interation_ind_ns_dis_train],
                         axis=1, join='inner')
df_test_new = pd.concat([df_test_scale,
                         interation_ind_ns_test,
                         interation_ind_ns_dis_test],
                         axis=1, join='inner')
df_train_new.head(5)

Вихід

Покращення терміну взаємодії моделі

Це все; ви можете оцінити нову модель за умовами взаємодії та побачити, як працює показник ефективності.

CONTI_FEATURES_NEW  = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT',
                       'INDUS_NOS', 'INDUS_NOS_DIS']
### Define categorical list
continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW]
model = tf.estimator.LinearRegressor(
    model_dir="train_Boston_1", 
    feature_columns= categorical_features + continuous_features_new)

Вихід

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train_Boston_1', '_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 0x1a1a5d5860>, '_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 = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT','INDUS_NOS', 'INDUS_NOS_DIS','CHAS']
LABEL= 'PRICE'
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)
model.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 train_Boston_1/model.ckpt.
INFO:tensorflow:loss = 56417.703, step = 1
INFO:tensorflow:global_step/sec: 124.844
INFO:tensorflow:loss = 65522.3, step = 101 (0.803 sec)
INFO:tensorflow:global_step/sec: 182.704
INFO:tensorflow:loss = 15384.148, step = 201 (0.549 sec)
INFO:tensorflow:global_step/sec: 208.189
INFO:tensorflow:loss = 22020.305, step = 301 (0.482 sec)
INFO:tensorflow:global_step/sec: 213.855
INFO:tensorflow:loss = 28208.812, step = 401 (0.468 sec)
INFO:tensorflow:global_step/sec: 209.758
INFO:tensorflow:loss = 7606.877, step = 501 (0.473 sec)
INFO:tensorflow:global_step/sec: 196.618
INFO:tensorflow:loss = 26679.76, step = 601 (0.514 sec)
INFO:tensorflow:global_step/sec: 196.472
INFO:tensorflow:loss = 11377.163, step = 701 (0.504 sec)
INFO:tensorflow:global_step/sec: 172.82
INFO:tensorflow:loss = 8592.07, step = 801 (0.578 sec)
INFO:tensorflow:global_step/sec: 168.916
INFO:tensorflow:loss = 19878.56, step = 901 (0.592 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train_Boston_1/model.ckpt.
INFO:tensorflow:Loss for final step: 19598.387.


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

Вихід

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-29-02:41:14
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train_Boston_1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-29-02:41:14
INFO:tensorflow:Saving dict for global step 1000: average_loss = 79.78876, global_step = 1000, loss = 1515.9863


{'average_loss': 79.78876, 'global_step': 1000, 'loss': 1515.9863}

Нова втрата дорівнює 1515. Просто додавши дві нові змінні, ви змогли зменшити втрату. Це означає, що ви можете зробити кращий прогноз, ніж за допомогою еталонної моделі.