使用 TensorFlow 加载 CSV 数据

在机器学习相关的任务之中,我们最常用的数据集合的格式就是 CSV 格式了,因此我们不仅仅要对CSV格式文件有所了解,同时也要学会如何在 TensorFlo w之中使用 CSV 数据。

1. 认识 CSV 数据格式

CSV 文件,全称叫做“逗号分隔值文件”文件后缀为“.csv”,它是一种表格文件;与 Excel 等文件不同的是,它是以纯文本表示的表格文件,而单元格之间用逗号分隔,因此被称作逗号分隔值文件。

CSV 文件大体可以分为两个部分:

  • 列名部分;
  • 数据部分。

比如以下CSV文件:

      a   b   c           # 列名部分
0    1   'a'   89         # 数据部分
1    3   'f'   88
2    8   'g'   99

该 CSV 文件一共包含三条数据,每条数据包括 a、b、c 三个字段,而其中 a 和 c 字段是整数,而 b 字段是字符串。

在实际的应用之中,一般的 CSV 数据会包含很多冗余的数据,我们会根据自己的需要来选择我们所需要的数据字段,从而进行下一步的工作。

2. 如何在 TensorFlow 之中使用 CSV 数据

要在 TensorFlow 之中使用 CSV 数据进行训练的话,我们大致需要经过三个步骤:

  • 获取 CSV 数据文件;
  • 将 csv 文件数据构建为 TensorFlow 中的 dataset 格式
  • 对数据集合进行进一步的处理以便符合模型输入的需求。

2.1 获取 CSV 数据文件

这一步中我们要首先获取到数据文件,获取的方式各不相同。

如果要使用 TensorFlow 内部的函数 API 进行网络 CSV 数据文件的获取,则我们可以通过以下 API 来实现数据集合的获取:

file_path = tf.keras.utils.get_file("data.csv", DATA_URL)

其中第一个参数表示的是获取的数据文件所保存的名字,而第二个参数 DATA_URL 表示的是网络 CSV 文件的地址。同时该函数会将本地保存文件的目录返回。

2.2 将 csv 文件数据构建为 TensorFlow 中的 tf.dataset 格式

在这一步之中,我们需要使用到 TensorFlow 中的 API 函数来将 csv 格式的数据转化为 TensorFlow 可以理解的数据形式,具体来说,我们可以通过以下API实现:

dataset = tf.data.experimental.make_csv_dataset(
      file_path, batch_size, label_name, na_value, num_epochs
    )

该API之中的几个参数需要我们有所了解:

  • file_path:CSV数据文件的路径;
  • batch_size:我们要划分数据集合的批次大小;
  • label_name:我们要进行预测的列;
  • na_value:该API会将文件中的空白值替换为 na_value ;
  • num_epochs:重复读取该数据集合的数量,通常设置为 1,因为我们只需要读取一遍数据集即可。

2.3 对数据集合进行进一步的处理以便符合模型输入的需求

在该步骤之中,我们会对数据进行预处理,我们常见的预处理包括:

  • 过滤掉无用数据;
  • 指定数据的规模;
  • 指定该数据中的离散值与连续值
  • 将离散值离散化

这些数据的预处理方法我们会在后面的示例中实践到。

3. CSV文件数据处理示例

在该示例之中,我们会采用公开数据集合:泰坦尼克生存数据集。该数据集合以CSV格式保存,同时也被 TensorFlow 纳入为内置数据集,因此使用较为方便。

该数据集合中包含了每个乘客的基本信息,比如名字、性别、年龄等,同时也包含了改乘客是否生还。我们所训练的模型就是要根据乘客的基本信息来判断改乘客最终是否生还。

import tensorflow as tf

# 获取数据集
train_path = tf.keras.utils.get_file("train.csv",
            "https://storage.googleapis.com/tf-datasets/titanic/train.csv")
valid_path = tf.keras.utils.get_file("eval.csv",
            "https://storage.googleapis.com/tf-datasets/titanic/eval.csv")

# 通过CSV文件构建数据集
train_data = tf.data.experimental.make_csv_dataset(train_path, batch_size=32,
        label_name='survived', na_value="?", num_epochs=1,
        ignore_errors=True )
valid_data = tf.data.experimental.make_csv_dataset(valid_path, batch_size=32,
        label_name='survived', na_value="?", num_epochs=1,
        ignore_errors=True )

# 定义离散列并进行处理
caetogries = {'sex': ['male', 'female'],
    'class' : ['First', 'Second', 'Third'],
    'deck' : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
    'embark_town' : ['Cherbourg', 'Southhampton', 'Queenstown'],
    'alone' : ['y', 'n']}
categorical_columns = []
for feature, vocab in caetogries.items():
    cat_col = tf.feature_column.categorical_column_with_vocabulary_list(
        key=feature, vocabulary_list=vocab)
    categorical_columns.append(tf.feature_column.indicator_column(cat_col))

# 定义连续列
numerical_names = {'age',
    'n_siblings_spouses',
    'parch',
    'fare'}
numerical_columns = []
for feature in numerical_names:
    num_col = tf.feature_column.numeric_column(feature)
    numerical_columns.append(num_col)

# 定义模型
model = tf.keras.Sequential([
    tf.keras.layers.DenseFeatures(categorical_columns + numerical_columns),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid'),
])

model.compile(
    loss='binary_crossentropy',
    optimizer='adam',
    metrics=['accuracy'])

# 模型训练
model.fit(train_data, epochs=20)

# 模型评估
model.evaluate(valid_data)

在该示例之中,我们首先获取了 CSV 数据集合并且构建了 dataset。然后我们便进行了至关重要的一步,我们对于离散数据和连续数据进行了预处理。

对于离散数据,我们进行了以下几步处理:

  • 定义离散列以及其可能的值(我们称作字典);
  • 使用 tf.feature_column.categorical_column_with_vocabulary_list 这个函数 API 构建 TensorFlow 能够识别的离散列;
  • 将所有的离散列合在一起以待后面使用。

对于连续数据,我们同样进行了以下几步处理:

  • 定义连续列;
  • 使用 tf.feature_column.numeric_column 这个函数 API 构建 TensorFlow 能够识别的连续列;
  • 将所有的连续列合在一起以待后面使用。

最后在模型的第一层,我们添加了一个特征的预处理层,因为我们输入的特征有的是连续值,有些是离散值,因此我们需要该层进行特征的预处理。

最后我们得到的输出为:

Epoch 1/20
20/20 [==============================] - 0s 2ms/step - loss: 0.7948 - accuracy: 0.6459
......
Epoch 19/20
20/20 [==============================] - 0s 2ms/step - loss: 0.4619 - accuracy: 0.8022
Epoch 20/20
20/20 [==============================] - 0s 2ms/step - loss: 0.4661 - accuracy: 0.7990
9/9 [==============================] - 0s 2ms/step - loss: 0.4571 - accuracy: 0.7841
[0.45707935094833374, 0.7840909361839294]

于是我们可以看到,我们的模型最终在测试集合上达到了78.4%的准确率。

4. 小结

在该节课之中,我们学习了 CSV 的数据文件格式,同时了解了在 TensorFlow 之中如何处理该格式的数据。同时,我们也使用泰坦尼克数据集进行了实践,最终达到了一个不错的效果。

图片描述