Линейная регрессия TensorFlow с аспектом и взаимодействием
В этом уроке вы узнаете, как проверить данные и подготовить их для создания простой задачи линейной регрессии.
Этот урок разделен на две части:
- Ищите взаимодействие
- Протестируйте модель
В предыдущий учебник, вы использовали набор данных Бостона для оценки средней цены дома. Бостонский набор данных имеет небольшой размер: всего 506 наблюдений. Этот набор данных считается эталоном для опробования новых алгоритмов линейной регрессии.
Набор данных состоит из:
Технология | Описание |
---|---|
zn | Доля жилых земель, зонированных на участки площадью более 25,000 XNUMX кв. футов. |
промышл | Доля площадей под неторговую деятельность на город. |
оксидов азота | концентрация оксидов азота |
rm | среднее количество комнат в жилище |
возраст | доля квартир, занимаемых владельцами, построенных до 1940 г. |
рас | взвешенные расстояния до пяти центров занятости Бостона |
налог | Полная ставка налога на имущество за 10,000 доллар США XNUMX XNUMX |
ptratio | соотношение учеников и учителей по городам |
медв | Средняя стоимость домов, занимаемых владельцами, в тысячах долларов |
кричать | уровень преступности на душу населения по городам |
Час | Фиктивная переменная Чарльз-Ривер (1, если ограничивает реку; 0 в противном случае) |
B | доля чернокожих в городе |
В этом уроке мы оценим медианную цену с помощью линейного регрессора, но основное внимание будет уделено одному конкретному процессу: обучение с помощью машины: «подготовка данных».
Модель обобщает закономерность в данных. Чтобы уловить такую закономерность, вам нужно сначала ее найти. Хорошей практикой является проведение анализа данных перед запуском любого алгоритма машинного обучения.
Выбор правильных функций имеет решающее значение для успеха вашей модели. Представьте, что вы пытаетесь оценить заработную плату людей, но если вы не включите пол в качестве ковариаты, вы получите плохую оценку.
Другой способ улучшить модель — посмотреть на корреляцию между независимой переменной. Возвращаясь к примеру, вы можете думать об образовании как об отличном кандидате для прогнозирования заработной платы, а также профессии. Справедливости ради стоит сказать, что профессия зависит от уровня образования, а именно высшее образование часто приводит к лучшей профессии. Если мы обобщим эту идею, мы можем сказать, что корреляция между зависимой переменной и объясняющей переменной может быть увеличена еще одной объясняющей переменной.
Чтобы отразить ограниченное влияние образования на профессию, мы можем использовать термин взаимодействия.
Если вы посмотрите на уравнение заработной платы, оно будет выглядеть следующим образом:
If является положительным, то это означает, что дополнительный уровень образования приводит к более высокому увеличению средней стоимости дома для высокого уровня занятости. Другими словами, существует эффект взаимодействия между образованием и профессией.
В этом уроке мы попытаемся увидеть, какие переменные могут быть хорошими кандидатами на роль терминов взаимодействия. Мы проверим, приведет ли добавление такого рода информации к лучшему прогнозированию цен.
Сводные статистические данные
Прежде чем приступить к моделированию, необходимо выполнить несколько шагов. Как упоминалось ранее, модель представляет собой обобщение данных. Лучше всего понять данные и сделать прогноз. Если вы не знаете свои данные, у вас мало шансов улучшить свою модель.
В качестве первого шага загрузите данные в виде кадра данных pandas и создайте обучающий набор и набор для тестирования.
Советы: Для работы с этим руководством вам необходимо, чтобы в вашем компьютере были установлены matplotlit и seaborn. Python. Вы можете установить Python пакет на лету с Jupyter. Вы Не следует сделать это
!conda install -- yes matplotlib
но
import sys !{sys.executable} -m pip install matplotlib # Already installed !{sys.executable} -m pip install seaborn
Обратите внимание: этот шаг не обязателен, если у вас установлены matplotlib и seaborn.
Matplotlib — библиотека для создания графиков. Python. Seaborn — это библиотека статистической визуализации, построенная на основе matplotlib. Он предоставляет привлекательные и красивые участки.
Код ниже импортирует необходимые библиотеки.
import pandas as pd from sklearn import datasets import tensorflow as tf from sklearn.datasets import load_boston import numpy as np
Библиотека sklearn включает набор данных Бостона. Вы можете вызвать его API для импорта данных.
boston = load_boston() df = pd.DataFrame(boston.data)
Имя функции хранится в объекте Feature_names в массиве.
boston.feature_names
Результат
array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')
Вы можете переименовать столбцы.
df.columns = boston.feature_names df['PRICE'] = boston.target df.head(2)
Вы преобразуете переменную CHAS как строковую переменную и помечаете ее словом «да», если CHAS = 1, и «нет», если CHAS = 0.
df['CHAS'] = df['CHAS'].map({1:'yes', 0:'no'}) df['CHAS'].head(5) 0 no 1 no 2 no 3 no 4 no Name: CHAS, dtype: object
С помощью pandas разделить набор данных очень просто. Вы случайным образом делите набор данных на 80-процентный обучающий набор и 20-процентный тестовый набор. Панды имеют встроенную функцию стоимости для разделения выборки кадра данных.
Первый параметр frac имеет значение от 0 до 1. Вы устанавливаете его на 0.8, чтобы случайным образом выбрать 80 процентов кадра данных.
Random_state позволяет возвращать один и тот же кадр данных для всех.
### Create train/test set df_train=df.sample(frac=0.8,random_state=200) df_test=df.drop(df_train.index)
Вы можете получить форму данных. Должен быть:
- Набор поездов: 506*0.8 = 405
- Тестовый набор: 506*0.2 = 101
print(df_train.shape, df_test.shape)
Результат
(405, 14) (101, 14)
df_test.head(5)
Результат
ПРЕСТУПНОСТЬ | ZN | ИНДУС | ЧАС | NOX | RM | ВОЗРАСТ | DIS | RAD | НАЛОГОВЫЙ | ПТРАТИО | 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 Блокнот.
Фасеты состоят из двух частей:
- Обзор аспектов
- Глубокое погружение в аспекты
Обзор аспектов
Обзор фасетов дает обзор набора данных. Обзор фасетов разделяет столбцы данных на строки с существенной информацией, отображающей
- процент пропущенных наблюдений
- минимальное и максимальное значения
- статистические данные, такие как среднее значение, медиана и стандартное отклонение.
- Он также добавляет столбец, показывающий процент нулевых значений, что полезно, когда большинство значений являются нулями.
- Эти распределения можно увидеть в тестовом наборе данных, а также в обучающем наборе для каждого объекта. Это означает, что вы можете дважды проверить, что тест имеет такое же распределение, что и обучающие данные.
Это как минимум минимум, который необходимо сделать перед выполнением любой задачи машинного обучения. С помощью этого инструмента вы не пропустите этот важный шаг, и он выявляет некоторые отклонения.
Глубокое погружение в аспекты
Facets Deep Dive — классный инструмент. Это позволяет внести некоторую ясность в ваш набор данных и полностью увеличить масштаб, чтобы увидеть отдельный фрагмент данных. Это означает, что вы можете фасетировать данные по строкам и столбцам по любому признаку набора данных.
Мы будем использовать эти два инструмента с набором данных Бостона.
Внимание: нельзя использовать «Обзор фасетов» и «Глубокое погружение в фасеты» одновременно. Чтобы сменить инструмент, сначала необходимо очистить блокнот.
Установить Фасет
Вы можете использовать веб-приложение Facet для большей части анализа. В этом уроке вы увидите, как использовать его в Jupyter Блокнот.
Прежде всего вам необходимо установить nbextensions. Это делается с помощью этого кода. Вы копируете и вставляете следующий код в терминал вашего компьютера.
pip install jupyter_contrib_nbextensions
Сразу после этого вам необходимо клонировать репозитории на вашем компьютере. У вас есть два варианта:
Вариант 1) Скопируйте и вставьте этот код в терминал (Рекомендуется)
Если на вашем компьютере не установлен Git, перейдите по этому URL-адресу. https://git-scm.com/download/win и следуйте инструкциям. Когда вы закончите, вы можете использовать команду git в терминале для пользователя Mac или приглашение Anaconda для Windows пользователь
git clone https://github.com/PAIR-code/facets
Вариант 2) Перейдите на https://github.com/PAIR-code/facets и загрузите репозитории.
Если вы выберете первый вариант, файл окажется в вашем загружаемом файле. Вы можете либо разрешить загрузку файла, либо перетащить его по другому пути.
Вы можете проверить, где хранятся Facets, с помощью этой командной строки:
echo `pwd`/`ls facets`
Теперь, когда вы нашли Facets, вам нужно установить его в Jupyter Блокнот. Вам необходимо указать в качестве рабочего каталога путь, по которому расположены фасеты.
Ваш текущий рабочий каталог и расположение zip-архива Facets должны совпадать.
Вам нужно указать рабочий каталог Facet:
cd facets
Чтобы установить Facets в Jupyter, у вас есть два варианта. Если вы установили Jupyter с Conda для всех пользователей скопируйте этот код:
можно использовать jupyter nbextension install facets-dist/
jupyter nbextension install facets-dist/
В противном случае используйте:
jupyter nbextension install facets-dist/ --user
Хорошо, все готово. Давайте откроем Обзор аспектов.
Обзор
В обзоре используется 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="/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. Интерфейс разделен на четыре основных раздела. Центральная область в центре представляет собой масштабируемое отображение данных. В верхней части панели находится раскрывающееся меню, в котором вы можете изменить расположение данных, чтобы управлять фасетированием, расположением и цветом. Справа находится детальное представление конкретной строки данных. Это означает, что вы можете щелкнуть любую точку данных в центральной визуализации, чтобы просмотреть подробную информацию об этой конкретной точке данных.
На этапе визуализации данных вас интересует поиск парной корреляции между независимой переменной ценой дома. Однако он включает как минимум три переменные, а с трехмерными графиками сложно работать.
Одним из способов решения этой проблемы является создание категориальной переменной. То есть мы можем создать 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 и увеличить левый нижний угол, вы сможете увидеть, какой это тип цены.
У вас есть еще один намек на то, что взаимодействие между 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. Всего лишь добавив две новые переменные, вы смогли уменьшить убыток. Это означает, что вы можете сделать лучший прогноз, чем с помощью эталонной модели.