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

В этом уроке вы узнаете, как проверить данные и подготовить их для создания простой задачи линейной регрессии.

Этот урок разделен на две части:

  • Ищите взаимодействие
  • Протестируйте модель

В предыдущий учебник, вы использовали набор данных Бостона для оценки средней цены дома. Бостонский набор данных имеет небольшой размер: всего 506 наблюдений. Этот набор данных считается эталоном для опробования новых алгоритмов линейной регрессии.

Набор данных состоит из:

Технология Описание
zn Доля жилых земель, зонированных на участки площадью более 25,000 XNUMX кв. футов.
промышл Доля площадей под неторговую деятельность на город.
оксидов азота концентрация оксидов азота
rm среднее количество комнат в жилище
возраст доля квартир, занимаемых владельцами, построенных до 1940 г.
рас взвешенные расстояния до пяти центров занятости Бостона
налог Полная ставка налога на имущество за 10,000 доллар США XNUMX XNUMX
ptratio соотношение учеников и учителей по городам
медв Средняя стоимость домов, занимаемых владельцами, в тысячах долларов
кричать уровень преступности на душу населения по городам
Час Фиктивная переменная Чарльз-Ривер (1, если ограничивает реку; 0 в противном случае)
B доля чернокожих в городе

В этом уроке мы оценим медианную цену с помощью линейного регрессора, но основное внимание будет уделено одному конкретному процессу: обучение с помощью машины: «подготовка данных».

Модель обобщает закономерность в данных. Чтобы уловить такую ​​закономерность, вам нужно сначала ее найти. Хорошей практикой является проведение анализа данных перед запуском любого алгоритма машинного обучения.

Выбор правильных функций имеет решающее значение для успеха вашей модели. Представьте, что вы пытаетесь оценить заработную плату людей, но если вы не включите пол в качестве ковариаты, вы получите плохую оценку.

Другой способ улучшить модель — посмотреть на корреляцию между независимой переменной. Возвращаясь к примеру, вы можете думать об образовании как об отличном кандидате для прогнозирования заработной платы, а также профессии. Справедливости ради стоит сказать, что профессия зависит от уровня образования, а именно высшее образование часто приводит к лучшей профессии. Если мы обобщим эту идею, мы можем сказать, что корреляция между зависимой переменной и объясняющей переменной может быть увеличена еще одной объясняющей переменной.

Чтобы отразить ограниченное влияние образования на профессию, мы можем использовать термин взаимодействия.

Срок взаимодействия

Если вы посмотрите на уравнение заработной платы, оно будет выглядеть следующим образом:

Срок взаимодействия

If Срок взаимодействия является положительным, то это означает, что дополнительный уровень образования приводит к более высокому увеличению средней стоимости дома для высокого уровня занятости. Другими словами, существует эффект взаимодействия между образованием и профессией.

В этом уроке мы попытаемся увидеть, какие переменные могут быть хорошими кандидатами на роль терминов взаимодействия. Мы проверим, приведет ли добавление такого рода информации к лучшему прогнозированию цен.

Сводные статистические данные

Прежде чем приступить к моделированию, необходимо выполнить несколько шагов. Как упоминалось ранее, модель представляет собой обобщение данных. Лучше всего понять данные и сделать прогноз. Если вы не знаете свои данные, у вас мало шансов улучшить свою модель.

В качестве первого шага загрузите данные в виде кадра данных pandas и создайте обучающий набор и набор для тестирования.

Советы: Для работы с этим руководством вам необходимо, чтобы в Python были установлены matplotlit и seaborn. Вы можете установить пакет 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 — библиотека для создания графиков. Питон. Seaborn — это библиотека статистической визуализации, построенная на основе matplotlib. Он предоставляет привлекательные и красивые участки.

Код ниже импортирует необходимые библиотеки.

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

Библиотека sklearn включает набор данных Бостона. Вы можете вызвать его API для импорта данных.

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

Имя функции хранится в объекте Feature_names в массиве.

boston.feature_names

Результат

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

Вы можете переименовать столбцы.

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

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

Вы преобразуете переменную CHAS как строковую переменную и помечаете ее словом «да», если CHAS = 1, и «нет», если CHAS = 0.

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

С помощью pandas разделить набор данных очень просто. Вы случайным образом делите набор данных на 80-процентный обучающий набор и 20-процентный тестовый набор. Панды имеют встроенную функцию стоимости для разделения выборки кадра данных.

Первый параметр frac имеет значение от 0 до 1. Вы устанавливаете его на 0.8, чтобы случайным образом выбрать 80 процентов кадра данных.

Random_state позволяет возвращать один и тот же кадр данных для всех.

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

Вы можете получить форму данных. Должен быть:

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

Результат

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

Результат

ПРЕСТУПНОСТЬ ZN ИНДУС ЧАС NOX RM ВОЗРАСТ DIS RAD НАЛОГОВЫЙ ПТРАТИО 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 Research разработала инструмент для этой работы под названием Грани которые помогают визуализировать данные и нарезать их различными способами. Это хорошая отправная точка для понимания того, как устроен набор данных.

Фасеты позволяют вам обнаружить, где данные выглядят не совсем так, как вы думаете.

За исключением своего веб-приложения, Google позволяет легко встроить этот инструментарий в Jupyter Блокнот.

Фасеты состоят из двух частей:

  • Обзор аспектов
  • Глубокое погружение в аспекты

Обзор аспектов

Обзор фасетов дает обзор набора данных. Обзор фасетов разделяет столбцы данных на строки с важной информацией, отображаемойwing

  1. процент пропущенных наблюдений
  2. минимальное и максимальное значения
  3. статистические данные, такие как среднее значение, медиана и стандартное отклонение.
  4. Он также добавляет столбец, показывающий процент нулевых значений, что полезно, когда большинство значений являются нулями.
  5. Эти распределения можно увидеть в тестовом наборе данных, а также в обучающем наборе для каждого объекта. Это означает, что вы можете дважды проверить, что тест имеет такое же распределение, что и обучающие данные.

Это как минимум минимум, который необходимо сделать перед выполнением любой задачи машинного обучения. С помощью этого инструмента вы не пропустите этот важный шаг, и он выявляет некоторые отклонения.

Глубокое погружение в аспекты

Facets Deep Dive — классный инструмент. Это позволяет внести некоторую ясность в ваш набор данных и zoom полностью, чтобы увидеть отдельный фрагмент данных. Это означает, что вы можете фасетировать данные по строкам и столбцам по любому признаку набора данных.

Мы будем использовать эти два инструмента с набором данных Бостона.

Внимание: нельзя использовать «Обзор фасетов» и «Глубокое погружение в фасеты» одновременно. Чтобы сменить инструмент, сначала необходимо очистить блокнот.

Установить Фасет

Вы можете использовать веб-приложение Facet для большей части анализа. В этом уроке вы увидите, как использовать его в Jupyter Блокнот.

Прежде всего вам необходимо установить nbextensions. Это делается с помощью этого кода. Вы копируете и вставляете следующееwing код в терминале вашей машины.

pip install jupyter_contrib_nbextensions

Сразу после этого вам необходимо клонировать репозитории на вашем компьютере. У вас есть два варианта:

Вариант 1) Скопируйте и вставьте этот код в терминал (Рекомендуется)

Если на вашем компьютере не установлен Git, перейдите по этому URL-адресу. https://git-scm.com/download/win и следуйте инструкциям. Когда вы закончите, вы можете использовать команду git в терминале для пользователя Mac или командную строку Anaconda для пользователя Windows.

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

Вариант 2) Перейдите на https://github.com/PAIR-code/facets и загрузите репозитории.

Установить Фасет

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

Вы можете проверить, где хранятся Facets, с помощью этой командной строки:

echo `pwd`/`ls facets`

Теперь, когда вы нашли Facets, вам нужно установить его в Jupyter Блокнот. Вам необходимо указать в качестве рабочего каталога путь, по которому расположены фасеты.

Ваш текущий рабочий каталог и расположение zip-архива Facets должны совпадать.

Установить Фасет

Вам нужно указать рабочий каталог Facet:

cd facets

Чтобы установить Facets в Jupyter, у вас есть два варианта. Если вы установили Jupyter с Conda для всех пользователей скопируйте этот код:

могут воспользоваться jupyter nbextension установить facets-dist/

jupyter nbextension install facets-dist/

В противном случае используйте:

jupyter nbextension install facets-dist/ --user

Хорошо, все готово. Давайте откроем Обзор аспектов.

Обзор

Обзор использует скрипт Python для вычисления статистики. Вам необходимо импортировать скрипт под названием generic_feature_statistics_.generator в Jupyter. Не волнуйся; сценарий находится в файлах фасетов.

Вам нужно найти его путь. Это легко сделать. Вы открываете фасеты, открываете файл facets_overview, а затем python. Скопируйте путь

Обзор Фасет

После этого вернитесь к Jupyterи напиши следующееwing код. Измените путь «/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="/ru/nbextensions/facets-dist/facets-jupyter.html" >
        <facets-overview id="elem"></facets-overview>
        <script>
          document.querySelector("#elem").protoInput = "{protostr}";
        </script>"""
html = HTML_TEMPLATE.format(protostr=protostr)
display(HTML(html))

График

После проверки данных и их распределения можно построить корреляционную матрицу. Корреляционная матрица вычисляет коэффициент Пирсона. Этот коэффициент связан между -1 и 1, положительное значение указывает на положительную корреляцию, а отрицательное значение - на отрицательную корреляцию.

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

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

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

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

Результат

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

PNG

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

Из матрицы можно увидеть:

  • ЛСТАТ
  • RM

Сильно коррелируют с ЦЕНОЙ. Еще одна интересная особенность — сильная положительная корреляция между NOX и INDUS, что означает, что эти две переменные движутся в одном направлении. Кроме того, есть еще и корреляция с ЦЕНОЙ. DIS также тесно коррелирует с IND и NOX.

У вас есть первый намек на то, что IND и 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, Facets Deep Dive. Интерфейс разделен на четыре основных раздела. Центральная часть в центре представляет собой zoomвозможность отображения данных. В верхней части панели находится раскрывающееся меню, в котором вы можете изменить расположение данных, чтобы управлять фасетированием, расположением и цветом. Справа находится детальное представление конкретной строки данных. Это означает, что вы можете щелкнуть любую точку данных в центральной визуализации, чтобы просмотреть подробную информацию об этой конкретной точке данных.

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

Одним из способов решения этой проблемы является создание категориальной переменной. То есть мы можем создать 2D-график, раскрасив точку. Вы можете разделить переменную ЦЕНА на четыре категории, каждая из которых представляет собой квартиль (т. е. 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")

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

Глубокое погружение в аспекты

Чтобы открыть Deep Dive, вам необходимо преобразовать данные в формат json. Панды как объект для этого. Вы можете использовать to_json после набора данных Pandas.

Первая строка кода обрабатывает размер набора данных.

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

Код ниже взят из Google GitHub. После запуска кода вы увидите следующее:

Глубокое погружение в аспекты

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

# Create Facets template  
HTML_TEMPLATE = """<link rel="import" href="/ru/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 и zoom В левом нижнем углу вы можете увидеть, какая это цена.

У вас есть еще один намек на то, что взаимодействие между IND, NOX и DIS может стать хорошим кандидатом на улучшение модели.

TensorFlow

В этом разделе вы оцените линейный классификатор с помощью API оценщиков TensorFlow. Вы будете действовать следующим образом:

  • Подготовьте данные
  • Оценка эталонной модели: отсутствие взаимодействия
  • Оцените модель с взаимодействием

Помните, цель машинного обучения — минимизировать ошибку. В этом случае победит модель с наименьшей среднеквадратической ошибкой. Оценщик TensorFlow автоматически вычисляет эту метрику.

Данные подготовки

В большинстве случаев вам необходимо преобразовать данные. Вот почему Обзор Facets увлекателен. Из сводной статистики вы увидели, что есть выбросы. Эти значения влияют на оценки, поскольку они не похожи на совокупность, которую вы анализируете. Выбросы обычно искажали результаты. Например, положительный выброс имеет тенденцию переоценивать коэффициент.

Хорошим решением этой проблемы является стандартизация переменной. Стандартизация означает стандартное отклонение, равное единице, и среднее значение, равное нулю. Процесс стандартизации включает в себя два этапа. Прежде всего, он вычитает среднее значение переменной. Во-вторых, оно делится на стандартное отклонение, так что распределение имеет единичное стандартное отклонение.

Библиотека sklearn полезна для стандартизации переменных. Для этой цели можно использовать предобработку модуля с масштабом объекта.

Вы можете использовать функцию ниже для масштабирования набора данных. Обратите внимание, что вы не масштабируете столбец меток и категориальные переменные.

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

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

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

Базовая регрессия: эталонный показатель

Прежде всего, вы обучаете и тестируете модель без взаимодействия. Цель состоит в том, чтобы увидеть метрику производительности модели.

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

Напоминаем, вам необходимо выбрать:

  • функции, которые нужно добавить в модель
  • трансформировать особенности
  • построить линейный регрессор
  • создайте функцию input_fn
  • обучить модель
  • протестировать модель

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

## 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. Это метрика, которую нужно победить в следующем разделе.

Улучшите модель: термин взаимодействия

В первой части урока вы увидели интересную взаимосвязь между переменными. Различные методы визуализации показали, что INDUS и NOS связаны друг с другом и усиливают влияние на цену. На цену влияет не только взаимодействие INDUS и NOS, но и этот эффект сильнее при взаимодействии с DIS.

Пришло время обобщить эту идею и посмотреть, сможете ли вы улучшить предсказанную моделью модель.

Вам нужно добавить два новых столбца в каждый набор данных: обучение + тест. Для этого вы создаете одну функцию для вычисления члена взаимодействия, а другую — для вычисления члена тройного взаимодействия. Каждая функция создает один столбец. После создания новых переменных вы можете объединить их с набором обучающих и тестовых данных.

Прежде всего вам необходимо создать новую переменную для взаимодействия INDUS и NOX.

Функция ниже возвращает два кадра данных, обучающий и тестовый, с взаимодействием между var_1 и var_2, в вашем случае INDUS и NOX.

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

Вы сохраняете два новых столбца

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

Во-вторых, вы создаете вторую функцию для вычисления члена тройного взаимодействия.

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

Теперь, когда у вас есть все необходимые столбцы, вы можете добавить их в набор данных для обучения и тестирования. Вы называете эти два новых фрейма данных:

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

Результат

Улучшите термин взаимодействия модели

Вот и все; вы можете оценить новую модель с учетом условий взаимодействия и посмотреть, каковы показатели производительности.

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

Результат

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train_Boston_1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a1a5d5860>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

КОД

FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT','INDUS_NOS', 'INDUS_NOS_DIS','CHAS']
LABEL= 'PRICE'
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)
model.train(input_fn=get_input_fn(df_train_new, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Результат

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train_Boston_1/model.ckpt.
INFO:tensorflow:loss = 56417.703, step = 1
INFO:tensorflow:global_step/sec: 124.844
INFO:tensorflow:loss = 65522.3, step = 101 (0.803 sec)
INFO:tensorflow:global_step/sec: 182.704
INFO:tensorflow:loss = 15384.148, step = 201 (0.549 sec)
INFO:tensorflow:global_step/sec: 208.189
INFO:tensorflow:loss = 22020.305, step = 301 (0.482 sec)
INFO:tensorflow:global_step/sec: 213.855
INFO:tensorflow:loss = 28208.812, step = 401 (0.468 sec)
INFO:tensorflow:global_step/sec: 209.758
INFO:tensorflow:loss = 7606.877, step = 501 (0.473 sec)
INFO:tensorflow:global_step/sec: 196.618
INFO:tensorflow:loss = 26679.76, step = 601 (0.514 sec)
INFO:tensorflow:global_step/sec: 196.472
INFO:tensorflow:loss = 11377.163, step = 701 (0.504 sec)
INFO:tensorflow:global_step/sec: 172.82
INFO:tensorflow:loss = 8592.07, step = 801 (0.578 sec)
INFO:tensorflow:global_step/sec: 168.916
INFO:tensorflow:loss = 19878.56, step = 901 (0.592 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train_Boston_1/model.ckpt.
INFO:tensorflow:Loss for final step: 19598.387.


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

Результат

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


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

Новый убыток равен 1515. Всего лишь добавив две новые переменные, вы смогли уменьшить убыток. Это означает, что вы можете сделать лучший прогноз, чем с помощью эталонной модели.