Лінійна регресія TensorFlow із аспектом і терміном взаємодії
⚡ Розумний підсумок
Лінійна регресія для даних про житло в Бостоні покращується, коли спочатку знаходяться правильні умови взаємодії. Google Фасети візуально демонструють ці зв'язки, а дві перехрещені ознаки скоротили втрати тесту TensorFlow з 1650 до 1515.
Лінійна регресія 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)
Ви перетворюєте змінну 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 дає огляд набору даних. Огляд аспектів розбиває стовпці даних на рядки, що показують важливу інформацію
- відсоток відсутніх спостережень
- мінімальне та максимальне значення
- такі статистичні дані, як середнє, медіана та стандартне відхилення.
- Він також додає стовпець, який показує відсоток значень, які є нулями, що корисно, коли більшість значень є нулями.
- Ці розподіли можна побачити в тестовому наборі даних, а також у навчальному наборі для кожної функції. Це означає, що ви можете ще раз перевірити, чи розподіл тесту подібний до даних навчання.
Це принаймні мінімум, який потрібно зробити перед будь-яким завданням машинного навчання. За допомогою цього інструменту ви не пропустите цей важливий крок, і він висвітлює деякі аномалії.
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 і завантажити репозиторії.
На сторінці сховища вище знаходиться кнопка завантаження, яка використовується для опції 2. Якщо ви оберете першу опцію, файл опиниться у вашій папці завантажень. Ви можете або дозволити файлу завантажитися, або перетягнути його в інший шлях.
Ви можете перевірити, де зберігаються грані, за допомогою цього командного рядка:
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/ --user
Гаразд, усе готово. Давайте відкриємо Facet Overview.
Огляд виконання аспектів у Jupyter
Огляд використовує 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="/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)
Вихід
Почнемо з верхньої частини:
- Ціна негативно корелює з 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")
Використання 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. Після запуску коду ви маєте побачити це:
# 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)
Вихід
Ось і все: ви можете оцінити нову модель з умовами взаємодії та побачити, як виглядає метрика продуктивності.
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 відсотків пояснюється лише двома стовпцями взаємодії.











