Линейная регрессия TensorFlow с аспектом и взаимодействием
⚡ Умное резюме
Результаты линейной регрессии по данным о рынке жилья в Бостоне улучшаются, если сначала удается найти подходящие члены взаимодействия. Google Функция Facets визуально отображает эти взаимосвязи, а два пересекающихся признака снижают ошибку в тестовом примере TensorFlow с 1650 до 1515.
Линейная регрессия TensorFlow
В этом уроке вы узнаете, как проверить данные и подготовить их для создания простой задачи линейной регрессии.
Этот урок разделен на две части:
- Ищите взаимодействие
- Протестируйте модель
В предыдущий учебник, вы использовали набор данных Бостона для оценки средней цены дома. Бостонский набор данных имеет небольшой размер: всего 506 наблюдений. Этот набор данных считается эталоном для опробования новых алгоритмов линейной регрессии.
Набор данных состоит из:
| Технология | Описание |
|---|---|
| zn | Доля жилых земель, зонированных на участки площадью более 25,000 XNUMX кв. футов. |
| промышл | Доля площадей под неторговую деятельность на город. |
| оксидов азота | концентрация оксидов азота |
| rm | среднее количество комнат в жилище |
| возраст | доля квартир, занимаемых владельцами, построенных до 1940 г. |
| рас | взвешенные расстояния до пяти центров занятости Бостона |
| налог | Полная ставка налога на имущество за 10,000 доллар США XNUMX XNUMX |
| ptratio | соотношение учеников и учителей по городам |
| медв | Средняя стоимость домов, занимаемых владельцами, в тысячах долларов |
| кричать | уровень преступности на душу населения по городам |
| Час | Фиктивная переменная Чарльз-Ривер (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 | НАЛОГОВЫЙ | ПТРАТИО | B | ЛСТАТ | ЦЕНА | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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 Исследовательская группа разработала для этой задачи инструмент под названием... Грани Это помогает визуализировать данные и анализировать их различными способами. Это хорошая отправная точка для понимания структуры набора данных.
Функция Facets позволяет выявить случаи, когда данные не совсем соответствуют вашим ожиданиям.
За исключением их веб-приложения, Google упрощает встраивание инструментария в Jupyter Блокнот.
Фасеты состоят из двух частей:
- Обзор аспектов
- Глубокое погружение в аспекты
Обзор аспектов
Обзор фасетов дает обзор набора данных. Обзор фасетов разделяет столбцы данных на строки с существенной информацией, отображающей
- процент пропущенных наблюдений
- минимальное и максимальное значения
- статистические данные, такие как среднее значение, медиана и стандартное отклонение.
- Он также добавляет столбец, показывающий процент нулевых значений, что полезно, когда большинство значений являются нулями.
- Эти распределения можно увидеть в тестовом наборе данных, а также в обучающем наборе для каждого объекта. Это означает, что вы можете дважды проверить, что тест имеет такое же распределение, что и обучающие данные.
Это как минимум минимум, который необходимо сделать перед выполнением любой задачи машинного обучения. С помощью этого инструмента вы не пропустите этот важный шаг, и он выявляет некоторые отклонения.
Глубокое погружение в аспекты
Функция Facets Deep Dive — это отличный инструмент. Она позволяет получить более четкое представление о вашем наборе данных и детально рассмотреть отдельные элементы данных. Это означает, что вы можете фильтровать данные по строкам и столбцам по любым параметрам набора данных.
Мы будем использовать эти два инструмента с набором данных Бостона.
Внимание: нельзя использовать «Обзор фасетов» и «Глубокое погружение в фасеты» одновременно. Чтобы сменить инструмент, сначала необходимо очистить блокнот.
Перед использованием любого из этих инструментов необходимо установить Facets в среду ноутбука.
Установить Фасет
Вы можете использовать веб-приложение Facet для большей части анализа. В этом уроке вы увидите, как использовать его в Jupyter Блокнот.
Прежде всего вам необходимо установить 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-кода/фасетов и загрузите репозитории.
На странице репозитория выше находится кнопка загрузки, используемая в варианте 2. Если вы выберете первый вариант, файл окажется в вашей папке загрузок. Вы можете либо оставить файл в папке загрузок, либо перетащить его в другое место.
Вы можете проверить, где хранятся Facets, с помощью этой командной строки:
echo `pwd`/`ls facets`
Теперь, когда вы нашли Facets, вам нужно установить его в Jupyter Блокнот. Вам необходимо указать в качестве рабочего каталога путь, по которому расположены фасеты.
Ваш текущий рабочий каталог и расположение zip-архива Facets должны совпадать.
Приведённый выше вывод в терминале подтверждает, что Facets находится в текущем рабочем каталоге. Вам необходимо указать рабочий каталог для Facet:
cd facets
Чтобы установить Facets в Jupyter, у вас есть два варианта. Если вы установили Jupyter с Conda для всех пользователей скопируйте этот код:
jupyter nbextension install facets-dist/
В противном случае используйте:
jupyter nbextension install facets-dist/ --user
Хорошо, все готово. Давайте откроем Обзор аспектов.
Обзор параметров запуска в Jupyter
В обзоре используется Python скрипт для вычисления статистики. Вам нужно импортировать скрипт generic_feature_statistics_generator в Jupyter. Не волнуйся; сценарий находится в файлах фасетов.
Вам нужно найти его путь. Это легко сделать. Вы открываете фасеты, открываете файл 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
Для расчета статистики объекта необходимо использовать функцию GenericFeatureStatistics.Generator(), и вы используете объект 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>
На приведенной выше тепловой карте более темные квадраты обозначают более сильные корреляции. Из матрицы видно:
- ЛСТАТ
- RM
Сильно коррелируют с PRICE. Еще одна интересная особенность — сильная положительная корреляция между NOX и INDUS, что означает, что эти две переменные движутся в одном направлении. Обе также коррелируют с PRICE. DIS также сильно коррелирует с INDUS и NOX.
У вас есть первое предположение, что INDUS и NOX могут быть хорошими кандидатами для термина, обозначающего взаимодействие, и DIS также может представлять интерес для изучения.
Вы можете пойти немного глубже, построив парную сетку. Он более подробно проиллюстрирует карту корреляции, которую вы построили ранее.
Парная сетка формируется следующим образом:
- Верхняя часть: точечная диаграмма с подогнанной линией.
- Диагональ: график плотности ядра
- Нижняя часть: многомерный график плотности ядра.
Вы сосредотачиваетесь на четырех независимых переменных. Выбор соответствует переменным, имеющим сильную корреляцию с ценой.
- ИНДУС
- NOX
- RM
- ЛСТАТ
тем более ЦЕНА.
Внимание что стандартная ошибка по умолчанию добавляется к диаграмме рассеяния.
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 автоматически вычисляет этот показатель.
Данные подготовки
В большинстве случаев вам необходимо преобразовать ваши данные. Именно поэтому обзор аспектов так интересен. Из сводной статистики вы увидели выбросы. Эти значения влияют на оценки, поскольку они не соответствуют анализируемой совокупности. Выбросы обычно искажают результаты. Например, положительный выброс, как правило, завышает коэффициент.
Хорошим решением этой проблемы является стандартизация переменной. Стандартизация означает стандартное отклонение, равное единице, и среднее значение, равное нулю. Процесс стандартизации включает два этапа. Прежде всего, он включает в себя...tracЭто среднее значение переменной. Во-вторых, оно делится на стандартное отклонение, так что распределение имеет единичное стандартное отклонение.
Библиотека 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'])]
Вы создаете модель с помощью линейного регрессора. Вы сохраняете модель в папке 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.
Пришло время обобщить эту идею и посмотреть, можно ли улучшить точность прогнозирования модели.
Необходимо добавить два новых столбца в каждый набор данных: обучающий и тестовый. Для этого создаётся одна функция для вычисления члена взаимодействия и другая для вычисления члена тройного взаимодействия. Каждая функция создаёт один столбец. После создания новых переменных их можно объединить с обучающим и тестовым наборами данных.
Прежде всего вам необходимо создать новую переменную для взаимодействия 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 процентов объясняется исключительно двумя столбцами взаимодействия.











