我正在查看大量文本数据上的数据预处理任务,希望将预处理后的数据加载到TensorFlow 2.x中。预处理数据包含整数值数组,因为预处理步骤生成:
因此,我一直在想,我将使用pyspark对数据进行预处理,并将结果转储到JSON
文件中(因为CSV不能存储结构化数据)。到目前为止,一切顺利。但是,我在tf.data.Dataset
中处理tf.data.Dataset
文件时遇到了问题(或者其他任何可以与TensorFlow 2.x接口的高效扩展文件)。
除了Tensorflow和PySpark之外,我不想使用/安装一个额外的库(例如PySpark),所以我想知道是否有可能使用JSON文件高效地链接这两个库,因为似乎没有其他方法来保存/加载包含数据列表的记录(?)。JSON测试文件如下所示:
readDF = spark.read.format('json').option('header',True).option('sep','|').load('/output.csv')
readDF.select('label4').show(15, False)
+---------------------------------------------------------+
|label4 |
+---------------------------------------------------------+
|[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]|
|[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]|
|[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]|
|[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
|[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]|
|[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]|
+---------------------------------------------------------+
因此,label4列已经进行了一个热编码,令牌化文本列在应用到它之后将类似于它。因此,我的问题是:一个JSON
文件是否能够用tf.data.Dataset
高效地加载(可能通过生成器函数),或者我应该为这个文件选择一条不同的道路(有一个额外的库)?
发布于 2021-03-17 07:18:00
tf.data
提供了几种有效使用来自不同来源的数据的方法。虽然我会说“更干净”的解决方案可能是使用TensorFlow本身来处理预处理,但让我为您的用例提供一些建议:
1)单热编码
我可以看到,你预处理数据并存储整个一个热编码向量,这将惩罚你的数据传输,因为你将读取大部分的零,而不是实际感兴趣的标签。我建议将其编码为整数,并在摄入时使用python生成器将其转换为一个热编码。或者,如果使用分类交叉熵损失函数,则可以使用标签编码(将每个类编码为整数),并使用稀疏范畴交叉熵。
如果您已经有了一个热编码列表,您可以简单地使用my_list.index(1)
获取标签编码(毕竟,它与向量中唯一1的索引相同)。
2)使用发电机
使用tf.data
完全可以做到这一点。实际上,它们提供了from_generator
函数来包装python,用于将数据摄取到模型中。如文档中所示,您将这样使用它:
def gen():
ragged_tensor = tf.ragged.constant([[1, 2], [3]])
yield 42, ragged_tensor
dataset = tf.data.Dataset.from_generator(
gen,
output_signature=(
tf.TensorSpec(shape=(), dtype=tf.int32),
tf.RaggedTensorSpec(shape=(2, None), dtype=tf.int32)))
list(dataset.take(1))
3)考虑回到CSV
如果您正在处理大量的数据,您可能可以围绕JSON编码并在类似CSV的格式(如TSV )中编码某些结构,如果需要类似列表的列,则可以使用其他分隔符(例如,您可以通过\t
分隔列,然后可以使用,
或|
分离列中的元素,或者使用任何字符可以减少与现有数据的冲突。
作为一个示例,让我们假设您的CSV文件具有以下结构:
comlumn name 1, column name 2, column name 3, column name 4
0.1,0.2,0.3,0:0:0:1
0.1,0.2,0.3,0:0:1:0
0.1,0.2,0.3,0:1:0:0
...
也就是说,您有4列由,
分隔,而第4栏本身是一个由:
分隔的值列表,它也是4个类的一个热门表示形式,您可以在上面的代码中使用一个生成器:
def my_generator(filename):
first_line = True
with open(filename) as f:
for line in f:
if first_line:
# do something to handle the header
first_line = False
continue
fields = line.split(',')
# here you extract the index of the one-hot encoded class
label = fields[3].split(':').index(1)
fields[3] = label
yield fields # return a list of features and the class
https://stackoverflow.com/questions/66612607
复制相似问题