具有方面和交互项的 TensorFlow 线性回归

在本教程中,您将学习如何检查数据并准备数据以创建简单的线性回归任务。

本教程分为两部分:

  • 寻找互动
  • 测试模型

先前的教程中,您使用波士顿数据集估算了房屋的中位数价格。波士顿数据集规模较小,只有 506 个观测值。该数据集被视为尝试新线性回归算法的基准。

数据集由以下部分组成:

请按需咨询 描述
zn 面积超过 25,000 平方英尺的住宅用地比例。
梧桐 每个城镇非零售商业用地面积的比例。
氮氧化物 一氧化氮浓度
rm 每套住房的平均房间数
年龄 1940 年之前建造的自住房比例
DIS 到波士顿五个就业中心的加权距离
税务 每 10,000 美元全值房产税率
比例 城镇师生比例
医疗病毒 自住房屋的平均价值(千美元)
犯罪 城镇人均犯罪率
CHAS 查尔斯河虚拟变量(如果边界河流则为 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库中包含了Boston数据集,可以调用其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 印度 查斯 氮氧化物 RM 年龄 DIS RAD TAX 比例 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 研究团队为这项工作开发了一个名为 这有助于将数据可视化并以各种方式对其进行切片。这是理解数据集布局方式的一个很好的起点。

通过方面,您可以找到数据与您想象的不符之处。

除了网页应用之外,谷歌还可以轻松地将该工具包嵌入到 Jupyter 笔记本电脑。

Facets 分为两个部分:

  • 方面概述
  • 深入探究各个方面

方面概述

Facets 概览提供了数据集的概览。Facets 概览将数据的列拆分为行,显示重要信息

  1. 缺失观测值的百分比
  2. 最小值和最大值
  3. 平均值、中位数和标准差等统计数据。
  4. 它还添加了一列,显示零值的百分比,当大多数值为零时这很有帮助。
  5. 可以在测试数据集以及每个特征的训练集上看到这些分布。这意味着您可以仔细检查测试是否具有与训练数据相似的分布。

这至少是任何机器学习任务之前要做的最低限度的事情。有了这个工具,你就不会错过这个关键步骤,而且它会突出显示一些异常情况。

深入探究各个方面

Facets Deep Dive 是一款很酷的工具。它可以让您清晰地了解数据集,并可以放大查看单个数据。这意味着您可以根据数据集的任何特征按行和列对数据进行分面。

我们将使用这两个工具和波士顿数据集。

备注:您不能同时使用 Facets Overview 和 Facets Deep Dive。您需要先清除笔记本才能更改工具。

安装 Facet

您可以使用 Facet Web 应用程序进行大部分分析。在本教程中,您将了解如何在 Jupyter 笔记本电脑。

首先,您需要安装 nbextensions。此代码可完成此操作。您将以下代码复制并粘贴到您的机器的终端中。

pip install jupyter_contrib_nbextensions

此后,您需要克隆计算机中的存储库。您有两个选择:

选项1) 复制并粘贴此代码到终端 (推荐的)

如果你的机器上没有安装 Git,请访问此 URL https://git-scm.com/download/win 并按照说明操作。完成后,您可以使用 Mac 用户终端中的 git 命令或 Anaconda 提示符 Windows 用户

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

选项2) 在MyCAD中点击 软件更新 https://github.com/PAIR-code/facets 并下载存储库。

安装 Facet

如果您选择第一个选项,文件将出现在您的下载文件中。您可以让文件继续下载,也可以将其拖到另一个路径。

您可以使用以下命令行检查 Facets 的存储位置:

echo `pwd`/`ls facets`

现在您已经找到 Facets,您需要将其安装在 Jupyter 笔记本。需要将工作目录设置为 facets 所在的路径。

您当前的工作目录和 Facets zip 的位置应该相同。

安装 Facet

您需要将工作目录指向 Facet:

cd facets

安装 Facets Jupyter,您有两个选择。如果您安装了 Jupyter 使用 Conda 为所有用户复制此代码:

可以使用 jupyter nbextension 安装 facets-dist/

jupyter nbextension install facets-dist/

否则,请使用:

jupyter nbextension install facets-dist/ --user

好了,一切就绪。让我们打开 Facet Overview。

概述

概述使用 Python 脚本来计算统计数据。您需要导入名为 generic_feature_statistics_generator 的脚本来 Jupyter。不要担心;脚本位于 facets 文件中。

您需要找到它的路径。这很容易做到。打开 facets,打开文件 facets_overview,然后打开 python。复制路径

概述方面

之后,回到 Jupyter,并写入以下代码。将路径 '/Users/Thomas/facets/facets_overview/python' 更改为您的路径。

# Add the facets overview python code to the python path# Add t 
import sys
sys.path.append('/Users/Thomas/facets/facets_overview/python')

您可以使用以下代码导入脚本。

from generic_feature_statistics_generator import 
GenericFeatureStatisticsGenerator

在 Windows 中,相同的代码变为

import sys
sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python")

from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator

要计算特征统计数据,需要使用函数 GenericFeatureStatisticsGenerator(),并使用对象 ProtoFromDataFrames。您可以在字典中传递数据框。例如,如果我们想为训练集创建摘要统计数据,我们可以将信息存储在字典中并在对象“ProtoFromDataFrames”中使用它

  • 'name': 'train', 'table': df_train

Name 是显示的表的名称,您使用要计算摘要的表的名称。在您的示例中,包含数据的表是 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="/zh-CN/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

与 PRICE 密切相关。另一个令人兴奋的特点是 NOX 和 INDUS 之间存在很强的正相关性,这意味着这两个变量朝同一方向移动。此外,它们还与 PRICE 相关。DIS 也与 IND 和 NOX 高度相关。

您首先得到的提示是 IND 和 NOX 可以作为截距项的良好候选,而 DIS 也可能值得关注。

您可以通过绘制成对网格来更深入地了解。它将更详细地说明您之前绘制的关联图。

我们的配对网格组成如下:

  • 上部:带拟合线的散点图
  • 对角线:核密度图
  • 下部:多元核密度图

您选择关注四个独立变量。该选择对应于与 PRICE 具有强相关性的变量

  • 印度
  • 氮氧化物
  • 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。界面分为四个主要部分。中间的中央区域是可缩放的数据显示。面板顶部有一个下拉菜单,您可以在其中更改数据的排列以控制分面、定位和颜色。右侧是特定数据行的详细视图。这意味着您可以单击中心可视化中的任意数据点来查看有关该特定数据点的详细信息。

在数据可视化步骤中,您感兴趣的是寻找独立变量与房价之间的成对相关性。然而,它涉及至少三个变量,并且 3D 绘图处理起来很复杂。

解决这个问题的一种方法是创建一个分类变量。也就是说,我们可以创建一个 2D 图,用颜色标记点。您可以将变量 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")

刻面图

深入探究各个方面

要打开 Deep Dive,您需要将数据转换为 json 格式。Pandas 作为此操作的对象。您可以在 Pandas 数据集后使用 to_json。

第一行代码处理数据集的大小。

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="/zh-CN/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 估算线性分类器。您将按以下步骤操作:

  • 准备数据
  • 估计基准模型:无相互作用
  • 估计具有交互作用的模型

请记住,机器学习的目标是最小化误差。在这种情况下,均方误差最小的模型将获胜。TensorFlow 估算器会自动计算此指标。

制备数据

在大多数情况下,您需要转换数据。这就是 Facets 概览如此吸引人的原因。从汇总统计数据中,您看到存在异常值。这些值会影响估计值,因为它们看起来不像您正在分析的总体。异常值通常会使结果产生偏差。例如,正异常值往往会高估系数。

解决这个问题的一个好办法是将变量标准化。标准化意味着标准差为 1,均值为 0。标准化过程包括两个步骤。首先,它减去变量的平均值。其次,它除以标准差,这样分布就有了单位标准差。

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'])]

使用 linearRegressor 创建模型。将模型存储在 train_Boston 文件夹中

model = tf.estimator.LinearRegressor(    
	model_dir="train_Boston",     
    feature_columns=categorical_features + continuous_features)

输出

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

使用函数 get_input_fn 将训练或测试数据中的每一列转换为张量

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

您根据训练数据估计模型。

model.train(input_fn=get_input_fn(df_train_scale, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train_Boston/model.ckpt.
INFO:tensorflow:loss = 56417.703, step = 1
INFO:tensorflow:global_step/sec: 144.457
INFO:tensorflow:loss = 76982.734, step = 101 (0.697 sec)
INFO:tensorflow:global_step/sec: 258.392
INFO:tensorflow:loss = 21246.334, step = 201 (0.383 sec)
INFO:tensorflow:global_step/sec: 227.998
INFO:tensorflow:loss = 30534.78, step = 301 (0.439 sec)
INFO:tensorflow:global_step/sec: 210.739
INFO:tensorflow:loss = 36794.5, step = 401 (0.477 sec)
INFO:tensorflow:global_step/sec: 234.237
INFO:tensorflow:loss = 8562.981, step = 501 (0.425 sec)
INFO:tensorflow:global_step/sec: 238.1
INFO:tensorflow:loss = 34465.08, step = 601 (0.420 sec)
INFO:tensorflow:global_step/sec: 237.934
INFO:tensorflow:loss = 12241.709, step = 701 (0.420 sec)
INFO:tensorflow:global_step/sec: 220.687
INFO:tensorflow:loss = 11019.228, step = 801 (0.453 sec)
INFO:tensorflow:global_step/sec: 232.702
INFO:tensorflow:loss = 24049.678, step = 901 (0.432 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train_Boston/model.ckpt.
INFO:tensorflow:Loss for final step: 23228.568.


<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a19e76320>

最后,评估模型在测试集上的表现

model.evaluate(input_fn=get_input_fn(df_test_scale, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

输出

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


{'average_loss': 86.89361, 'global_step': 1000, 'loss': 1650.9785}

该模型的损失为 1650。这是下一节要克服的指标

改进模型:交互项

在本教程的第一部分中,您看到了变量之间的有趣关系。不同的可视化技术表明,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。只需添加两个新变量,就可以减少损失。这意味着您可以做出比基准模型更好的预测。