Path: blob/master/site/zh-cn/tutorials/load_data/pandas_dataframe.ipynb
25118 views
Copyright 2019 The TensorFlow Authors.
Licensed under the Apache License, Version 2.0 (the "License");
加载 pandas DataFrame
![]() |
在 Google Colab 中运行 | ![]() |
![]() |
本教程提供了将 pandas DataFrame 加载到 TensorFlow 中的示例。
本教程使用了一个小型数据集,由克利夫兰诊所心脏病基金会(Cleveland Clinic Foundation for Heart Disease)提供. 此数据集中有几百行CSV。每行表示一个患者,每列表示一个属性(describe)。我们将使用这些信息来预测患者是否患有心脏病,这是一个二分类问题。
使用 pandas 读取数据
下载包含心脏病数据集的 CSV 文件:
使用 pandas 读取 CSV 文件:
数据如下:
您将构建模型来预测 target
列中包含的标签。
创建并训练模型
如果您的数据具有统一的数据类型或 dtype
,则可在任何可以使用 NumPy 数组的地方使用 pandas DataFrame。这是因为 pandas.DataFrame
类支持 __array__
协议,并且 TensorFlow 的 tf.convert_to_tensor
函数接受支持该协议的对象。
从数据集中获取数值特征(暂时跳过分类特征):
可以使用 DataFrame.values
属性或 numpy.array(df)
将 DataFrame 转换为 NumPy 数组。要将其转换为张量,请使用 tf.convert_to_tensor
:
通常,如果一个对象可以使用 tf.convert_to_tensor
转换为张量,则可以在任何可以传递 tf.Tensor
的位置传递该对象。
使用 Model.fit
解释为单个张量的 DataFrame,可以直接用作 Model.fit
方法的参数。
下面是使用数据集的数值特征训练模型的示例。
第一步是归一化输入范围。为此,请使用 tf.keras.layers.Normalization
层。
要在运行之前设置层的均值和标准差,请务必调用 Normalization.adapt
方法:
调用 DataFrame 前三行的层,以呈现此层的输出的样本:
使用归一化层作为简单模型的第一层:
当您将 DataFrame 作为 x
参数传递给 Model.fit
时,Keras 会将 DataFrame 视为 NumPy 数组:
使用 tf.data
如果您想对统一 dtype
的 DataFrame 应用 tf.data
转换,Dataset.from_tensor_slices
方法将创建一个遍历 DataFrame 的行的数据集。每行最初都是一个值向量。要训练模型,您需要 (inputs, labels)
对,因此传递 (features, labels)
和 Dataset.from_tensor_slices
将返回所需的切片对:
DataFrame 作为字典
当您开始处理异构数据时,不再可能将 DataFrame 视为单个数组。TensorFlow 张量要求所有元素都具有相同的 dtype
。
因此,在这种情况下,您需要开始将它视为列字典,其中每一列都具有统一的 dtype
。DataFrame 非常像数组字典,所以您通常只需将 DataFrame 强制转换为 Python 字典。许多重要的 TensorFlow API 都支持将(嵌套)数组字典作为输入。
tf.data
输入流水线可以很好地进行此项处理。所有 tf.data
运算都会自动处理字典和元组。因此,要从 DataFrame 制作字典样本数据集,只需将其强制转换为字典,然后再使用 Dataset.from_tensor_slices
对其进行切片:
以下是该数据集中的前三个样本:
接受字典的 Keras
通常,Keras 模型和层需要单个输入张量,但这些类可以接受和返回字典、元组和张量的嵌套结构。这些结构称为“嵌套”(有关详细信息,请参阅 tf.nest
模块)。
可以通过两种等效方式编写接受字典作为输入的 Keras 模型。
1. 模型-子类样式
编写 tf.keras.Model
(或 tf.keras.Layer
)的子类。直接处理输入,并创建输出:
此模型可以接受列字典或字典元素数据集进行训练:
以下是前三个样本的预测:
2. Keras 函数式样式
您可以像模型子类一样训练函数式模型:
完整样本
如果您将异构 DataFrame 传递给 Keras,则每列都可能需要独特的预处理。您可以直接在 DataFrame 中进行此预处理,但要使模型正常工作,始终需要以相同的方式对输入进行预处理。因此,最好的方式是将预处理构建到模型中。Keras 预处理层涵盖许多常见任务。
构建预处理头文件
在此数据集中,原始数据中的一些“整数”特征实际上是分类索引。这些索引并非真正有序的数值(有关详细信息,请参阅数据集描述)。这些索引是无序的,因此不适合直接馈送给模型;该模型会将它们解释为有序索引。要使用这些输入,您需要将它们编码为独热向量或嵌入向量。这同样适用于字符串分类特征。
注:如果您有许多特征需要相同的预处理,那么在应用预处理之前将它们连接在一起会更加有效。
另一方面,二元特征通常不需要编码或归一化。
首先创建属于每个组的特征的列表:
下一步为构建预处理模型,该模型将对每个输入应用适当的预处理并连接结果。
本部分使用 Keras 函数式 API 来实现预处理。首先为 dataframe 的每一列创建一个 tf.keras.Input
:
对于每个输入,您都将使用 Keras 层和 TensorFlow 运算应用一些转换。每个特征都以一批标量 (shape=(batch,)
) 开始。每个特征的输出都应是一批 tf.float32
向量 (shape=(batch, n)
)。最后一步将把这些向量全部连接到一起。
二元输入
二元输入不需要任何预处理,因此只需添加向量轴,将它们强制转换为 float32
并将它们添加到预处理输入列表中:
数值输入
与之前的部分一样,使用前需要先通过 tf.keras.layers.Normalization
层运行这些数值输入。不同之处是此次它们将作为字典输入。以下代码会从 DataFrame 中收集数值特征,将它们堆叠在一起并将传递给 Normalization.adapt
方法。
以下代码堆叠数值特征并通过规一化层运行它们。
分类特征
要使用分类特征,您首先需要将它们编码为二元向量或嵌入向量。这些特征仅包含少量类别,因此使用 tf.keras.layers.StringLookup
和 tf.keras.layers.IntegerLookup
层均支持的 output_mode='one_hot'
选项将输入直接转换为独热向量。
以下是这些层如何工作的示例:
要确定每个输入的词汇表,请创建一个用于将该词汇表转换为独热向量的层:
组装预处理头文件
此时,preprocessed
仅为所有预处理结果的 Python 列表,每个结果的形状均为 (batch_size, depth)
:
沿 depth
轴连接所有预处理特征,使每个字典样本都转换为单个向量。向量包含分类特征、数值特征和分类独热特征:
现在通过该计算创建模型以便重用:
要测试预处理器,请使用 DataFrame.iloc 访问器对 DataFrame 中的第一个样本进行切片。然后将它转换为字典并将字典传递给预处理器。结果为包含二元特征、归一化数值特征和独热分类特征的单个向量,按该顺序:
创建和训练模型
现在,构建模型主体。使用与上一个示例相同的配置:一对 Dense
修正线性层和一个 Dense(1)
输出层用于分类。
现在,使用 Keras 函数式 API 将这两部分结合在一起。
此模型需要一个输入字典。将数据传递给它的最简单方式是将 DataFrame 转换为字典并将该字典作为 x
参数传递给 Model.fit
:
也可以使用 tf.data
: