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

⚡ Розумний підсумок

Лінійна регресія для даних про житло в Бостоні покращується, коли спочатку знаходяться правильні умови взаємодії. Google Фасети візуально демонструють ці зв'язки, а дві перехрещені ознаки скоротили втрати тесту TensorFlow з 1650 до 1515.

  • 🔘 Спочатку дані: Розуміння розподілів та викидів передує будь-якій моделі, оскільки модель лише узагальнює вже виявлену закономірність.
  • ☑️ Огляд аспектів: Статистика для кожної ознаки відображає відсутні значення, стовпці з нульовою складністю та дрейф розподілу «навчання проти тестування» в одній таблиці.
  • Глибоке занурення в аспекти: Огранювання за допомогою X та Y перетворює тристоронні залежності на читабельний 2D-графік, забарвлений ціновим квартилем.
  • 🧪 Кореляційне читання: Теплова карта та парна сітка позначають INDUS з NOX та DIS з обома як кандидати на взаємодію.
  • 🛠️ Стандартизація: preprocessing.scale центрує дванадцять безперервних стовпців до того, як оцінювач їх побачить, залишаючи CHAS та PRICE недоторканими.
  • 📈 Виміряний коефіцієнт посилення: Додавання INDUS_NOS та INDUS_NOS_DIS зміщує середні втрати з 86.89361 до 79.78876 на тестовому спліті.

Лінійна регресія TensorFlow з фасетом та взаємодійним членом

Лінійна регресія TensorFlow

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

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

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

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

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

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

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

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

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

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

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

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

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

Рівняння заробітної плати, розширене членом взаємодії освіти та професії

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

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

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

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

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

Поради: Для цього посібника вам потрібно встановити matplotlib та 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 — це бібліотека для створення графіка PythonSeaborn — це бібліотека статистичної візуалізації, побудована на базі matplotlib. Вона надає такі послуги:tracпривабливі та красиві сюжети.

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

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

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

Примітка до версії: load_boston було застарілим у scikit-learn 1.0 та видалено у scikit-learn 1.2 оскільки набір даних кодує расово завантажену функцію. У поточній інсталяції використовуйте fetch_california_housing або завантажте необроблений файл самостійно. Робочий процес, показаний нижче, не змінився; відрізняється лише завантажувач.

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)

Перші два рядки Boston DataFrame після перейменування стовпців

Ви перетворюєте змінну 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 одночасно. Щоб змінити інструмент, спочатку потрібно очистити блокнот.

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

Встановити Facet

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

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

pip install jupyter_contrib_nbextensions

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

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

Якщо у вас не встановлено Git на вашому комп'ютері, будь ласка, перейдіть за цим посиланням URL Git для Windows скачати сторінку і дотримуйтесь інструкції. Закінчивши, ви можете використати команду git у терміналі для користувача Mac або запит Anaconda для Windows користувач

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

Варіант 2) Перейдіть до репозиторій PAIR-code/facets і завантажити репозиторії.

Сторінка репозиторію аспектів PAIR-code на GitHub

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

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

echo `pwd`/`ls facets`

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

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

Термінал, що показує папку facets у поточному робочому каталозі

Наведений вище список терміналу підтверджує, що facet знаходиться в поточному робочому каталозі. Вам потрібно вказати робочий каталог на Facet:

cd facets

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

jupyter nbextension install facets-dist/

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

jupyter nbextension install facets-dist/ --user

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

Огляд виконання аспектів у Jupyter

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

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

Шлях до файлу папки 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="/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, де додатне значення вказує на позитивну кореляцію, а від'ємне значення – на негативну.

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

Примітка до версії: маска нижче викликає np.bool, псевдонім, який був застарілим у NumPy 1.20 та видалено в NumPy 1.24У нещодавньому NumPy той самий рядок викликає AttributeError: module 'numpy' has no attribute 'bool'вбудований bool є заміною, що підпадає під дію.

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

Теплова карта кореляції Сіборна для бостонських змінних

На тепловій карті вище темніші квадрати позначають сильніші кореляції. З матриці можна побачити:

  • LSTAT
  • RM

Сильно корелюють з PRICE. Ще однією цікавою особливістю є сильна позитивна кореляція між NOX та INDUS, що означає, що ці дві змінні рухаються в одному напрямку. Обидві також корелюють з PRICE. DIS також сильно корелює з INDUS та NOX.

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

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

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

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

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

  • ІНДУС
  • 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)

Вихід

Парна сітка Seaborn: PRICE, INDUS, NOX, RM та LSTAT

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

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

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

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

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

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

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

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

Один зі способів вирішення цієї проблеми – створити категоріальну змінну. Тобто, ми можемо створити двовимірний графік і розфарбувати точки. Ви можете розділити змінну PRICE на чотири категорії, де кожна категорія буде квартилем (тобто 0.25, 0.5, 0.75). Ви називаєте цю нову змінну 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")

Точкова діаграма DIS проти INDUS, розфарбована за ціновим квартилем

Використання Facets Deep Dive

Щоб відкрити Deep Dive, вам потрібно перетворити дані у формат JSON. У Pandas є метод для цього: викликати to_json на DataFrame.

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

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. Після запуску коду ви маєте побачити це:

Глибоке занурення у фасетний розсіювальний вигляд набору даних Boston

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

# Create Facets template  
HTML_TEMPLATE = """<link rel="import" href="/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

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

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

Примітка до версії: tf-estimator Пакет постачався у своєму фінальному випуску з TensorFlow 2.15 і відсутній у TensorFlow 2.16 і наступних версіях, тому tf.estimator.LinearRegressor працює лише на TensorFlow 1.x, якщо ви не перенесете його на лінійну модель Keras.

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

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

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

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

Бібліотека scikit-вчитися корисно для стандартизації змінних. Для цієї мети можна використовувати попередню обробку модулів зі шкалою об'єктів.

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

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.9785. Це показник, який потрібно перевершити в наступному розділі

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

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

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

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

Перш за все, вам потрібно створити нову змінну для взаємодії між 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)

Вихід

Навчальний DataFrame з доданими стовпцями INDUS_NOS та INDUS_NOS_DIS

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

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}

Code

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

Модель Набір функцій Каталог моделей середні_втрати від
еталонний тест 12 стандартизованих безперервних колон плюс CHAS поїзд_Бостон 86.89361 1650.9785
З взаємодією Бенчмарк плюс INDUS_NOS та INDUS_NOS_DIS поїзд_Бостон_1 79.78876 1515.9863

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

Поширені запитання

Його було вилучено з scikit-learn версії 1.0 та видалено з версії 1.2. Набір даних містить функцію, побудовану на припущенні про расову самосегрегацію та ціни на житло, і оригінальне дослідження ніколи не підтверджувало його передумову щодо якості повітря. Звичайними замінниками є житло в Каліфорнії або Еймсі.

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

Шукайте пари, які корелюють між собою та з цільовою групою. Теплова карта Пірсона та парна сітка роблять це візуально; тут INDUS та NOX кластеруються разом, і обидва track ЦІНА, що є сигналом, що виправдовує їх перетин.

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

Copilot добре справляється з повторюваним побудовою шаблонів — парними сітками, маскованими тепловими картами, HTML-шаблонами для Facets. Перевірте аргументи, які він пропонує, адже Seaborn перейменував кілька з них, і Copilot із задоволенням поєднує старі та поточні сигнатури.

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

Маска використовує np.bool, псевдонім, застарілий у NumPy 1.20 та видалений у 1.24. Нещодавні встановлення викликають AttributeError. Підміна вбудованого bool залишає поведінку ідентичною; np.bool_ також працює, якщо вам потрібен скалярний тип NumPy.

CHAS – це категоричний прапорець «так» чи «ні», а PRICE – це мітка. Центрування та масштабування фіктивної моделі ускладнює читання її коефіцієнта без зміни наближення, а масштабування мітки просто змінить масштаб зареєстрованих втрат. Стандартизовано лише дванадцять безперервних предикторів.

Підсумуйте цей пост за допомогою: