机器学习9:使用 TensorFlow 进行特征组合编程实践

news2024/11/17 15:36:21

在【机器学习6】这篇文章中,笔者已经介绍过环境准备相关事项,本文对此不再赘述。本文将通过编程案例来探索特征组合(Feature Crosses)对模型训练的影响,加深对上一篇文章(机器学习8)的理解。

经度和纬度可以作为独立特征训练模型以预测当地房价。同时,我们也可以将经度和纬度进行交叉生成交叉特征,进而训练房价预测模型。那么,那种方式更好呢?更进一步,房价与精确的精度和纬度强相关么?未必,那么直接使用精度和纬度数据是不是不太合适呢?学习本篇文章,我们一起来探索吧。

目录

1.导入依赖

2.加载、缩放和打乱示例

3.将纬度和经度表示为浮点值

4.定义用于创建和训练模型的函数以及打印函数

5.用浮点表示法训练模型

6.完整代码运行

7.以桶表示纬度和经度

7.1 完整代码

7.2 运行结果

8.用特征交叉来表示位置

8.1 完整代码

8.2 运行结果


1.导入依赖

import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from matplotlib import pyplot as plt

2.加载、缩放和打乱示例

既然要训练模型,那就必须要有示例数据,因此,通过如下代码单元加载单独的 .csv 文件并创建两个数据集:

  • train_df,训练数据集
  • test_df,测试数据集

然后,将 median_house_value 缩放到更人性化的范围,然后对示例进行打乱。

# 载入数据集
train_df = pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv")
test_df = pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_test.csv")

# 缩放标签
scale_factor = 1000.0
# 缩放训练集的标签
train_df["median_house_value"] /= scale_factor

# 缩放测试集的标签
test_df["median_house_value"] /= scale_factor

# 打乱示例
train_df = train_df.reindex(np.random.permutation(train_df.index))

3.将纬度和经度表示为浮点值

在【机器学习6】中,我们训练线性回归模型只用到了单一特征。相比之下,这里我们将使用输入层训练两个特征。

社区的位置通常是决定房屋价值的最重要特征。加州住房数据集提供了两个特征,即纬度和经度,用于识别每个社区的位置。

下面的代码单元定义了两个 tf.keras.Input 层,一个表示纬度,另一个表示经度,都是浮点值。这个代码单元指定了用于训练模型的特征,以及这些特征将如何表示。

# 通过 Keras(一个由 Python 编写的开源人工神经网络库)将经度和纬度浮点值的输入张量
inputs = {
    'latitude':
        tf.keras.layers.Input(shape=(1,), dtype=tf.float32,
                              name='latitude'),
    'longitude':
        tf.keras.layers.Input(shape=(1,), dtype=tf.float32,
                              name='longitude')
}

4.定义用于创建和训练模型的函数以及打印函数

以下代码定义了三个功能:

  • create_model,它告诉 TensorFlow 根据提供的输入和输出构建线性回归模型。
  • train_model,它将基于训练集中的示例训练模型。
  • plot_the_loss_curve,生成损失曲线。
# 创建模型
def create_model(my_inputs, my_outputs, my_learning_rate):
    model = tf.keras.Model(inputs=my_inputs, outputs=my_outputs)

    # 将层编译为 TensorFlow 可以执行的模型
    model.compile(optimizer=tf.keras.optimizers.experimental.RMSprop(
        learning_rate=my_learning_rate),
        loss="mean_squared_error",
        metrics=[tf.keras.metrics.RootMeanSquaredError()])

    return model


# 训练模型
def train_model(model, dataset, epochs, batch_size, label_name):
    # 将数据集输入到模型中以便对其进行训练
    features = {name: np.array(value) for name, value in dataset.items()}
    label = np.array(features.pop(label_name))
    history = model.fit(x=features, y=label, batch_size=batch_size,
                        epochs=epochs, shuffle=True)

    # 将轮次列表与历史的其余部分分开存储
    epochs = history.epoch

    # 隔离每一轮训练的平均绝对误差
    hist = pd.DataFrame(history.history)
    rmse = hist["root_mean_squared_error"]

    return epochs, rmse


# 打印损失
def plot_the_loss_curve(epochs, rmse):
    # 绘制损失与训练轮次的曲线
    plt.figure()
    plt.xlabel("Epoch")
    plt.ylabel("Root Mean Squared Error")

    plt.plot(epochs, rmse, label="Loss")
    plt.legend()
    plt.ylim([rmse.min() * 0.94, rmse.max() * 1.05])
    plt.show()

5.用浮点表示法训练模型

执行下面的代码单元来训练、绘制和评估模型。

# 初始化超参数
learning_rate = 0.05
epochs = 30
batch_size = 100
label_name = 'median_house_value'

# 将两个输入层连接在一起,以便将它们作为单个张量传递到密集层
preprocessing_layer = tf.keras.layers.Concatenate()(inputs.values())

dense_output = layers.Dense(
    units=1,
    input_shape=(1,),
    name='dense_layer')(preprocessing_layer)

outputs = {
    'dense_output': dense_output
}

# 创建并编译模型
my_model = create_model(inputs, outputs, learning_rate)

# 基于训练数据集训练模型
epochs, rmse = train_model(my_model, train_df, epochs, batch_size, label_name)

# 打印出模型摘要
my_model.summary(expand_nested=True)

plot_the_loss_curve(epochs, rmse)

print("\n: Evaluate the new model against the test set:")
test_features = {name: np.array(value) for name, value in test_df.items()}
test_label = np.array(test_features.pop(label_name))
my_model.evaluate(x=test_features, y=test_label, batch_size=batch_size)

6.完整代码运行

将上面的代码整合到一起,可以得到如下代码:

import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from matplotlib import pyplot as plt

pd.options.display.max_rows = 10
pd.options.display.float_format = "{:.1f}".format

tf.keras.backend.set_floatx('float32')

print("Imported the modules.")

# 载入数据集(注意:这里已经将谷歌的原始数据文件下载到了本地,因此用的是本地路径)
train_df = pd.read_csv("/Users/jinKwok/Downloads/california_housing_train.csv")
test_df = pd.read_csv("/Users/jinKwok/Downloads/california_housing_test.csv")

# 缩放标签
scale_factor = 1000.0
# 缩放训练集的标签
train_df["median_house_value"] /= scale_factor

# 缩放测试集的标签
test_df["median_house_value"] /= scale_factor

# 打乱示例
train_df = train_df.reindex(np.random.permutation(train_df.index))

# 通过 Keras(一个由 Python 编写的开源人工神经网络库)将经度和纬度浮点值的输入张量
inputs = {
    'latitude':
        tf.keras.layers.Input(shape=(1,), dtype=tf.float32,
                              name='latitude'),
    'longitude':
        tf.keras.layers.Input(shape=(1,), dtype=tf.float32,
                              name='longitude')
}


# 创建模型
def create_model(my_inputs, my_outputs, my_learning_rate):
    model = tf.keras.Model(inputs=my_inputs, outputs=my_outputs)

    # 将层编译为 TensorFlow 可以执行的模型
    model.compile(optimizer=tf.keras.optimizers.experimental.RMSprop(
        learning_rate=my_learning_rate),
        loss="mean_squared_error",
        metrics=[tf.keras.metrics.RootMeanSquaredError()])

    return model


# 训练模型
def train_model(model, dataset, epochs, batch_size, label_name):
    # 将数据集输入到模型中以便对其进行训练
    features = {name: np.array(value) for name, value in dataset.items()}
    label = np.array(features.pop(label_name))
    history = model.fit(x=features, y=label, batch_size=batch_size,
                        epochs=epochs, shuffle=True)

    # 将轮次列表与历史的其余部分分开存储
    epochs = history.epoch

    # 隔离每一轮训练的平均绝对误差
    hist = pd.DataFrame(history.history)
    rmse = hist["root_mean_squared_error"]

    return epochs, rmse


# 打印损失
def plot_the_loss_curve(epochs, rmse):
    # 绘制损失与训练轮次的曲线
    plt.figure()
    plt.xlabel("Epoch")
    plt.ylabel("Root Mean Squared Error")

    plt.plot(epochs, rmse, label="Loss")
    plt.legend()
    plt.ylim([rmse.min() * 0.94, rmse.max() * 1.05])
    plt.show()


print("Defined the create_model, train_model, and plot_the_loss_curve functions.")

# 初始化超参数
learning_rate = 0.05
epochs = 30
batch_size = 100
label_name = 'median_house_value'

# 将两个输入层连接在一起,以便将它们作为单个张量传递到密集层
preprocessing_layer = tf.keras.layers.Concatenate()(inputs.values())

dense_output = layers.Dense(
    units=1,
    input_shape=(1,),
    name='dense_layer')(preprocessing_layer)

outputs = {
    'dense_output': dense_output
}

# 创建并编译模型
my_model = create_model(inputs, outputs, learning_rate)

# 基于训练数据集训练模型
epochs, rmse = train_model(my_model, train_df, epochs, batch_size, label_name)

# 打印出模型摘要
my_model.summary(expand_nested=True)

plot_the_loss_curve(epochs, rmse)

print("\n: Evaluate the new model against the test set:")
test_features = {name: np.array(value) for name, value in test_df.items()}
test_label = np.array(test_features.pop(label_name))
my_model.evaluate(x=test_features, y=test_label, batch_size=batch_size)

运行结果如下所示:

_________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to                     
==================================================================================================
 latitude (InputLayer)          [(None, 1)]          0           []                               
                                                                                                  
 longitude (InputLayer)         [(None, 1)]          0           []                               
                                                                                                  
 concatenate (Concatenate)      (None, 2)            0           ['latitude[0][0]',               
                                                                  'longitude[0][0]']              
                                                                                                  
 dense_layer (Dense)            (None, 1)            3           ['concatenate[0][0]']            
                                                                                                  
==================================================================================================
Total params: 3
Trainable params: 3
Non-trainable params: 0
__________________________________________________________________________________________________

 

从上面的损失曲线来看,训练并没有收敛,这说明用浮点值表示纬度和经度并不合适。鉴于此,我们继续尝试其他方法。

7.以桶表示纬度和经度

以下图所示,我们用 “桶” 来表示经度和纬度。每个 “桶” 表示一个区间内的所有邻域,例如,纬度 32.4 和 32.8 的邻域在同一个桶(LatitudeBin1)中,但纬度 37.4 与 38.2 的邻域在不同的桶中。

模型将学习每个 “桶” 的权重。例如,模型将为 “LatitudeBin1” 桶学习一个权重,为 “LatitudeBin2” 桶学习另一个不同的权重,依此类推,此表示将创建大约 20 个桶。

  • 纬度为 10 个桶
  • 经度为 10 个桶

相关代码如下:

resolution_in_degrees = 1.0

# 创建一个数字列表,用来表示纬度的桶边界,简单理解就是确定纬度分组的数据段
latitude_boundaries = list(np.arange(int(min(train_df['latitude'])),
                                     int(max(train_df['latitude'])),
                                     resolution_in_degrees))
print("latitude boundaries: " + str(latitude_boundaries))

# 创建一个离散化层,将纬度数据分离存储到桶中
latitude = tf.keras.layers.Discretization(
    bin_boundaries=latitude_boundaries,
    name='discretization_latitude')(inputs.get('latitude'))

# 纬度类别数量 = 纬度边界数量 + 1,这很好理解,比如对一根香肠划5刀,可以将其分为6段
latitude = tf.keras.layers.CategoryEncoding(
    num_tokens=len(latitude_boundaries) + 1,
    output_mode='one_hot',
    name='category_encoding_latitude')(latitude)

# 创建一个数字列表,用来表示经度的桶边界
longitude_boundaries = list(np.arange(int(min(train_df['longitude'])),
                                      int(max(train_df['longitude'])),
                                      resolution_in_degrees))

print("longitude boundaries: " + str(longitude_boundaries))

# 创建一个离散化层,将经度数据分离存储到桶中
longitude = tf.keras.layers.Discretization(
    bin_boundaries=longitude_boundaries,
    name='discretization_longitude')(inputs.get('longitude'))

# 经度类别数量 = 经度边界数量 + 1,这很好理解,比如对一根香肠划5刀,可以将其分为6段
longitude = tf.keras.layers.CategoryEncoding(
    num_tokens=len(longitude_boundaries) + 1,
    output_mode='one_hot',
    name='category_encoding_longitude')(longitude)

# 将纬度和经度连接到单个张量中,作为密集层的输入。
concatenate_layer = tf.keras.layers.Concatenate()([latitude, longitude])

dense_output = layers.Dense(
    units=1, input_shape=(2,), name='dense_layer')(concatenate_layer)

# 定义一个输出字典,我们将发送给模型构造函数
outputs = {
    'dense_output': dense_output
}

7.1 完整代码

将上面的代码整合到完整的工程中。需要注意的是:google提供的原始数据地址为:https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv

https://download.mlcc.google.com/mledu-datasets/california_housing_test.csv

为了便于本地执行,我们将数据下载到了本地,读者如果要运行代码,将程序中的数据路径修改为自己的数据路径即可。

import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from matplotlib import pyplot as plt

pd.options.display.max_rows = 10
pd.options.display.float_format = "{:.1f}".format

tf.keras.backend.set_floatx('float32')

print("Imported the modules.")

# 载入数据集,谷歌原始数据访问太慢了,这里我们将数据下载的到本地,因此使用的是本地路径
train_df = pd.read_csv("/Users/jinKwok/Downloads/california_housing_train.csv")
test_df = pd.read_csv("/Users/jinKwok/Downloads/california_housing_test.csv")

# 缩放标签
scale_factor = 1000.0
# 缩放训练集的标签
train_df["median_house_value"] /= scale_factor

# 缩放测试集的标签
test_df["median_house_value"] /= scale_factor

# 打乱示例
train_df = train_df.reindex(np.random.permutation(train_df.index))

# 通过 Keras(一个由 Python 编写的开源人工神经网络库)将经度和纬度浮点值的输入张量
inputs = {
    'latitude':
        tf.keras.layers.Input(shape=(1,), dtype=tf.float32,
                              name='latitude'),
    'longitude':
        tf.keras.layers.Input(shape=(1,), dtype=tf.float32,
                              name='longitude')
}


# 创建模型
def create_model(my_inputs, my_outputs, my_learning_rate):
    model = tf.keras.Model(inputs=my_inputs, outputs=my_outputs)

    # 将层编译为 TensorFlow 可以执行的模型
    model.compile(optimizer=tf.keras.optimizers.experimental.RMSprop(
        learning_rate=my_learning_rate),
        loss="mean_squared_error",
        metrics=[tf.keras.metrics.RootMeanSquaredError()])

    return model


# 训练模型
def train_model(model, dataset, epochs, batch_size, label_name):
    # 将数据集输入到模型中以便对其进行训练
    features = {name: np.array(value) for name, value in dataset.items()}
    label = np.array(features.pop(label_name))
    history = model.fit(x=features, y=label, batch_size=batch_size,
                        epochs=epochs, shuffle=True)

    # 将轮次列表与历史的其余部分分开存储
    epochs = history.epoch

    # 隔离每一轮训练的平均绝对误差
    hist = pd.DataFrame(history.history)
    rmse = hist["root_mean_squared_error"]

    return epochs, rmse


# 打印损失
def plot_the_loss_curve(epochs, rmse):
    # 绘制损失与训练轮次的曲线
    plt.figure()
    plt.xlabel("Epoch")
    plt.ylabel("Root Mean Squared Error")

    plt.plot(epochs, rmse, label="Loss")
    plt.legend()
    plt.ylim([rmse.min() * 0.94, rmse.max() * 1.05])
    plt.show()


print("Defined the create_model, train_model, and plot_the_loss_curve functions.")

# 初始化超参数
learning_rate = 0.05
epochs = 30
batch_size = 100
label_name = 'median_house_value'

#################################
resolution_in_degrees = 1.0

# 创建一个数字列表,用来表示纬度的桶边界,简单理解就是确定纬度分组的数据段
latitude_boundaries = list(np.arange(int(min(train_df['latitude'])),
                                     int(max(train_df['latitude'])),
                                     resolution_in_degrees))
print("latitude boundaries: " + str(latitude_boundaries))

# 创建一个离散化层,将纬度数据分离存储到桶中
latitude = tf.keras.layers.Discretization(
    bin_boundaries=latitude_boundaries,
    name='discretization_latitude')(inputs.get('latitude'))

# 纬度类别数量 = 纬度边界数量 + 1,这很好理解,比如对一根香肠划5刀,可以将其分为6段
latitude = tf.keras.layers.CategoryEncoding(
    num_tokens=len(latitude_boundaries) + 1,
    output_mode='one_hot',
    name='category_encoding_latitude')(latitude)

# 创建一个数字列表,用来表示经度的桶边界
longitude_boundaries = list(np.arange(int(min(train_df['longitude'])),
                                      int(max(train_df['longitude'])),
                                      resolution_in_degrees))

print("longitude boundaries: " + str(longitude_boundaries))

# 创建一个离散化层,将经度数据分离存储到桶中
longitude = tf.keras.layers.Discretization(
    bin_boundaries=longitude_boundaries,
    name='discretization_longitude')(inputs.get('longitude'))

# 经度类别数量 = 经度边界数量 + 1,这很好理解,比如对一根香肠划5刀,可以将其分为6段
longitude = tf.keras.layers.CategoryEncoding(
    num_tokens=len(longitude_boundaries) + 1,
    output_mode='one_hot',
    name='category_encoding_longitude')(longitude)

# 将纬度和经度连接到单个张量中,作为密集层的输入。
concatenate_layer = tf.keras.layers.Concatenate()([latitude, longitude])

dense_output = layers.Dense(
    units=1, input_shape=(2,), name='dense_layer')(concatenate_layer)

# 定义一个输出字典,我们将发送给模型构造函数
outputs = {
    'dense_output': dense_output
}

# 创建并编译模型
my_model = create_model(inputs, outputs, learning_rate)

# 基于训练数据集训练模型
epochs, rmse = train_model(my_model, train_df, epochs, batch_size, label_name)

# 打印出模型摘要
my_model.summary(expand_nested=True)

plot_the_loss_curve(epochs, rmse)

print("\n: Evaluate the new model against the test set:")
test_features = {name: np.array(value) for name, value in test_df.items()}
test_label = np.array(test_features.pop(label_name))
my_model.evaluate(x=test_features, y=test_label, batch_size=batch_size)

7.2 运行结果

__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to                     
==================================================================================================
 latitude (InputLayer)          [(None, 1)]          0           []                               
                                                                                                  
 longitude (InputLayer)         [(None, 1)]          0           []                               
                                                                                                  
 discretization_latitude (Discr  (None, 1)           0           ['latitude[0][0]']               
 etization)                                                                                       
                                                                                                  
 discretization_longitude (Disc  (None, 1)           0           ['longitude[0][0]']              
 retization)                                                                                      
                                                                                                  
 category_encoding_latitude (Ca  (None, 10)          0           ['discretization_latitude[0][0]']
 tegoryEncoding)                                                                                  
                                                                                                  
 category_encoding_longitude (C  (None, 11)          0           ['discretization_longitude[0][0]'
 ategoryEncoding)                                                ]                                
                                                                                                  
 concatenate (Concatenate)      (None, 21)           0           ['category_encoding_latitude[0][0
                                                                 ]',                              
                                                                  'category_encoding_longitude[0][
                                                                 0]']                             
                                                                                                  
 dense_layer (Dense)            (None, 1)            22          ['concatenate[0][0]']            
                                                                                                  
==================================================================================================
Total params: 22
Trainable params: 22
Non-trainable params: 0
__________________________________________________________________________________________________

 从损失曲线来看,相较于用浮点表示法训练模型,用桶表示纬度和经度的收敛效果要好的多。

8.用特征交叉来表示位置

如下代码所示,将位置表示为交叉特征。也就是说,下面的代码单元首先创建 bucket,然后使用HashedCrossing 层交叉纬度和经度特性。

resolution_in_degrees = 1.0

# 创建一个数字列表,用来表示纬度的桶边界,简单理解就是确定纬度分组的数据段
latitude_boundaries = list(np.arange(int(min(train_df['latitude'])),
                                     int(max(train_df['latitude'])),
                                     resolution_in_degrees))
print("latitude boundaries: " + str(latitude_boundaries))

# 创建一个离散化层,将纬度数据分离存储到桶中
latitude = tf.keras.layers.Discretization(
    bin_boundaries=latitude_boundaries,
    name='discretization_latitude')(inputs.get('latitude'))

# 创建一个数字列表,用来表示经度的桶边界
longitude_boundaries = list(np.arange(int(min(train_df['longitude'])),
                                      int(max(train_df['longitude'])),
                                      resolution_in_degrees))

print("longitude boundaries: " + str(longitude_boundaries))

# 创建一个离散化层,将经度数据分离存储到桶中
longitude = tf.keras.layers.Discretization(
    bin_boundaries=longitude_boundaries,
    name='discretization_longitude')(inputs.get('longitude'))

# 将纬度和经度特征交叉成一个单一的热向量
feature_cross = tf.keras.layers.HashedCrossing(
    num_bins=len(latitude_boundaries) * len(longitude_boundaries),
    output_mode='one_hot',
    name='cross_latitude_longitude')([latitude, longitude])

dense_output = layers.Dense(units=1, input_shape=(2,),
                            name='dense_layer')(feature_cross)

# 定义一个输出字典,我们将发送给模型构造函数
outputs = {
    'dense_output': dense_output
}

8.1 完整代码

将上面的代码整合到完整的工程中,得到如下所示的完整代码,读者修改其中的数据文件路径后,可在本地直接运行。

import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from matplotlib import pyplot as plt

pd.options.display.max_rows = 10
pd.options.display.float_format = "{:.1f}".format

tf.keras.backend.set_floatx('float32')

print("Imported the modules.")

# 载入数据集
train_df = pd.read_csv("/Users/jinKwok/Downloads/california_housing_train.csv")
test_df = pd.read_csv("/Users/jinKwok/Downloads/california_housing_test.csv")

# 缩放标签
scale_factor = 1000.0
# 缩放训练集的标签
train_df["median_house_value"] /= scale_factor

# 缩放测试集的标签
test_df["median_house_value"] /= scale_factor

# 打乱示例
train_df = train_df.reindex(np.random.permutation(train_df.index))

# 通过 Keras(一个由 Python 编写的开源人工神经网络库)将经度和纬度浮点值的输入张量
inputs = {
    'latitude':
        tf.keras.layers.Input(shape=(1,), dtype=tf.float32,
                              name='latitude'),
    'longitude':
        tf.keras.layers.Input(shape=(1,), dtype=tf.float32,
                              name='longitude')
}


# 创建模型
def create_model(my_inputs, my_outputs, my_learning_rate):
    model = tf.keras.Model(inputs=my_inputs, outputs=my_outputs)

    # 将层编译为 TensorFlow 可以执行的模型
    model.compile(optimizer=tf.keras.optimizers.experimental.RMSprop(
        learning_rate=my_learning_rate),
        loss="mean_squared_error",
        metrics=[tf.keras.metrics.RootMeanSquaredError()])

    return model


# 训练模型
def train_model(model, dataset, epochs, batch_size, label_name):
    # 将数据集输入到模型中以便对其进行训练
    features = {name: np.array(value) for name, value in dataset.items()}
    label = np.array(features.pop(label_name))
    history = model.fit(x=features, y=label, batch_size=batch_size,
                        epochs=epochs, shuffle=True)

    # 将轮次列表与历史的其余部分分开存储
    epochs = history.epoch

    # 隔离每一轮训练的平均绝对误差
    hist = pd.DataFrame(history.history)
    rmse = hist["root_mean_squared_error"]

    return epochs, rmse


# 打印损失
def plot_the_loss_curve(epochs, rmse):
    # 绘制损失与训练轮次的曲线
    plt.figure()
    plt.xlabel("Epoch")
    plt.ylabel("Root Mean Squared Error")

    plt.plot(epochs, rmse, label="Loss")
    plt.legend()
    plt.ylim([rmse.min() * 0.94, rmse.max() * 1.05])
    plt.show()


print("Defined the create_model, train_model, and plot_the_loss_curve functions.")

# 初始化超参数
learning_rate = 0.04
epochs = 35
batch_size = 100
label_name = 'median_house_value'

#################################
resolution_in_degrees = 1.0

# 创建一个数字列表,用来表示纬度的桶边界,简单理解就是确定纬度分组的数据段
latitude_boundaries = list(np.arange(int(min(train_df['latitude'])),
                                     int(max(train_df['latitude'])),
                                     resolution_in_degrees))
print("latitude boundaries: " + str(latitude_boundaries))

# 创建一个离散化层,将纬度数据分离存储到桶中
latitude = tf.keras.layers.Discretization(
    bin_boundaries=latitude_boundaries,
    name='discretization_latitude')(inputs.get('latitude'))

# 创建一个数字列表,用来表示经度的桶边界
longitude_boundaries = list(np.arange(int(min(train_df['longitude'])),
                                      int(max(train_df['longitude'])),
                                      resolution_in_degrees))

print("longitude boundaries: " + str(longitude_boundaries))

# 创建一个离散化层,将经度数据分离存储到桶中
longitude = tf.keras.layers.Discretization(
    bin_boundaries=longitude_boundaries,
    name='discretization_longitude')(inputs.get('longitude'))

# 将纬度和经度特征交叉成一个单一的热向量
feature_cross = tf.keras.layers.HashedCrossing(
    num_bins=len(latitude_boundaries) * len(longitude_boundaries),
    output_mode='one_hot',
    name='cross_latitude_longitude')([latitude, longitude])

dense_output = layers.Dense(units=1, input_shape=(2,),
                            name='dense_layer')(feature_cross)

# 定义一个输出字典,我们将发送给模型构造函数
outputs = {
    'dense_output': dense_output
}

# 创建并编译模型
my_model = create_model(inputs, outputs, learning_rate)

# 基于训练数据集训练模型
epochs, rmse = train_model(my_model, train_df, epochs, batch_size, label_name)

# 打印出模型摘要
my_model.summary(expand_nested=True)

plot_the_loss_curve(epochs, rmse)

print("\n: Evaluate the new model against the test set:")
test_features = {name: np.array(value) for name, value in test_df.items()}
test_label = np.array(test_features.pop(label_name))
my_model.evaluate(x=test_features, y=test_label, batch_size=batch_size)

8.2 运行结果

__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to                     
==================================================================================================
 latitude (InputLayer)          [(None, 1)]          0           []                               
                                                                                                  
 longitude (InputLayer)         [(None, 1)]          0           []                               
                                                                                                  
 discretization_latitude (Discr  (None, 1)           0           ['latitude[0][0]']               
 etization)                                                                                       
                                                                                                  
 discretization_longitude (Disc  (None, 1)           0           ['longitude[0][0]']              
 retization)                                                                                      
                                                                                                  
 cross_latitude_longitude (Hash  (None, 90)          0           ['discretization_latitude[0][0]',
 edCrossing)                                                      'discretization_longitude[0][0]'
                                                                 ]                                
                                                                                                  
 dense_layer (Dense)            (None, 1)            91          ['cross_latitude_longitude[0][0]'
                                                                 ]                                
                                                                                                  
==================================================================================================
Total params: 91
Trainable params: 91
Non-trainable params: 0
__________________________________________________________________________________________________

从损失曲线来看, 用特征交叉来表示位置训练模型,其 “root_mean_squared_error” 要更小一些,这也说明,在本案例中,交叉特征能够产生更好的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/696126.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ DAY2

1.总结类和结构体的区别 1.结构体是一种值类型,而类是引用类型。值类型用于存储数据的值,引用类型用于存储对实际数据的引用 2.结构体中声明的成员变量无法赋予初值,类可以 3.结构体是值类型,它在栈中分配空间;而类是…

青大数据结构【2018】【算法分析】

关键字: 单链表奇偶数拆分、顺序表交集、二叉排序树 右中左的顺序,找出二叉排序树中值大于等于k的所有结点。

2.位带操作

1.位带操作: 2.位带区与位带别名区地址转换: 外设位带别名区地址:AliasAddr0x42000000(A-0x40000000)*8*4n*4;SRAM位带别名区地址:AliasAddr0x22000000(A-0x20000000)*8*4n*4;IO口操作宏定义:…

【Linux】NoSQL之 Redis配置与优化

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 NoSQL之 Redis配置与优化 关系数据库与非关系型数据库关系型数据库非关系型数据库关系型数据库和非关系型数据库区别数据存储方式不同扩展方式不同对事务性的支持不同 非关系…

多元回归预测 | Matlab麻雀算法(SSA)优化极限学习机ELM回归,SSA-ELM回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab麻雀算法(SSA)优化极限学习机ELM回归,SSA-ELM回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% 清空环境变…

交叉熵损失CrossEntropyLoss

交叉熵损失CrossEntropyLoss 语义分割网络输出tensor的尺寸为【B,C,H,W】,进行多分类,label的尺寸为【B,H,W】。 举例:三分类:output【1, 3,3, 3】,label【1, 3, 3】 验证 import torchoutput torch.tensor([[[[1, 1…

字符集,编码,解码,中文乱码

字符集 ASCII 美国佬用的,1个字节表示那些英文字母啥的就够了 GBK 中国的,两个字节表示2w多汉字也够了 Unicode 万国符,4个字节,用来包含全世界所有的字符。 编码 编码就是将字符集中的数字,如a对应数字97&…

Vue中el与data函数

1、绑定容器&#xff0c;el与$mount的异同 <body><div id"root"><h1>你好&#xff0c;{{name}}</h1></div> </body> <script>const vm new Vue({//el:#root, //第一中写法&#xff0c;new的时候直接写好eldata:{name:…

云 LIS 实验室信息管理系统源码 C#检验系统源码

科技的飞速发展为实验室信息管理带来了新机遇&#xff0c;云计算技术的应用更是为实验室信息管理打开了新的大门。云 LIS 实验室信息管理系统&#xff0c;作为一种新型的信息化管理方案&#xff0c;已经在多个实验室的信息化管理中得到应用&#xff0c;并且具有广阔的应用前景。…

社区团购小程序怎么制作

社区团购小程序开发&#xff0c;有什么功能 商品管理&#xff1a;社区团购小程序提供商品管理功能&#xff0c;可以方便地添加、编辑和删除商品信息。你可以设置商品的价格、库存、规格等&#xff0c;并上传商品的图片和描述&#xff0c;以吸引用户关注。 配送管理&#xff1…

为什么 Midjourney 效果远远好于开源的 Stable Diffusion Model?

midjourney之所以让你觉得效果好&#xff0c;是因为他是一个更接近于应用层的工具&#xff0c;你就聊聊天对对话&#xff0c;他就能给你很好的反馈&#xff0c;内部的调优都封装成黑盒&#xff0c;不太需要你去关心 而stable diffusion更适合爱折腾&#xff0c;懂折腾的专业一…

抖音团购服务商贴牌系统

抖音团购服务商贴牌系统整体指的是抖音为团购服务商提供的一套定制化解决方案&#xff0c;使其能够以自己的品牌形象和标识在抖音平台上进行团购活动。这个系统通常包括以下组成部分&#xff1a; 品牌定制&#xff1a;抖音允许团购服务商根据自身品牌形象和标识进行定制&am…

Bpmn.js流程建模结合业务整合工作流(三)

前两篇文章概述了bpmn的搭建及其基本使用 现在说下流程所需的表单 流程建模之表单设计如下图所示 VForm是一款基于Vue 2/Vue 3的低代码表单&#xff0c;支持Element UI、iView两种UI库&#xff0c;定位为前端开发人员提供快速搭建表单、实现表单交互和数据收集的功能。 VForm由…

在SpringBoot中如何整合消息服务组件?

在开发中&#xff0c;消息服务组件在系统架构中扮演着举足轻重的角色。本文将介绍消息服务组件的基本概念&#xff0c;以及如何在SpringBoot中整合常见的消息服务组件&#xff0c;如ActiveMQ、RabbitMQ和Kafka。最后&#xff0c;我们将探讨整合消息服务组件在实际应用场景中的优…

jmeter连接数据库jdbc(sql server举例)

目录 前言&#xff1a; 一、下载第三方工具包驱动数据库 二、连接JDBC Connection Configuration 三、jdbc request 四、查看数据 前言&#xff1a; JMeter是一款强大的性能测试工具&#xff0c;它不仅可以模拟用户行为进行接口测试&#xff0c;还可以通过使用JDBC&#…

libevent(10)使用event处理socket连接

这个例子中&#xff0c;我们通过event处理socket连接&#xff0c;并进行一些简单的数据处理。 代码如下 test_event_server.cpp&#xff1a; #include <iostream> #include <thread> #include <sys/types.h> #include <sys/stat.h> #include <fcnt…

Scrapy框架--Request和FormRequest

目录 Request对象 原理 参数 将附加数据传递给回调函数 原理 示例代码 FormRequest 概念 参数 请求使用示例 响应对象 参数 Request对象 原理 爬虫中请求与响应是最常见的操作&#xff0c;Request对象在爬虫程序中生成并传递到下载器中&#xff0c;后者执行请求…

【Linux进程】进程的基本概念 {基本概念,Linux中的PCB—task_struct,查看进程,进程标识符—PID,创建子进程}

一、进程的基本概念 什么是进程&#xff1f; 进程是计算机中正在运行的程序的实例。它是操作系统进行资源分配和调度的基本单位。每个进程都有自己的内存空间、代码、数据和执行状态。进程可以独立运行&#xff0c;相互之间不会干扰。操作系统可以同时运行多个进程&#xff0c…

vue3文件从创建 - 运行

新建文件 npm init vuelatest 2、报错处理 &#xff08;1&#xff09;TypeScript选项‘importsNotUsedAsValues‘和‘preserveValueImports‘弃用 在tsconfig.json中添加"ignoreDeprecations": "5.0" 参考&#xff1a;TypeScript选项‘importsNotUsedAs…

推荐10款Python图形界面(GUI)框架以及使用PyQt6和QtDesigner快速开发

9个国外最佳免费编程学习一站式网站 http://www.360doc.com/content/22/1024/17/63953942_1053111478.shtml QT文档 https://doc.qt.io/ QtDesigner pyqt6 https://blog.csdn.net/lyshark_lyshark/article/details/125847218 https://doc.qt.io/qtforpython-6/contents.htm…