SKIL/工作流程/数据转换

数据转换

在实践中,数据很少以方便神经网络使用的格式存在。它是字符串、类别、数字、不同格式的图像的混合体,而且大部分时间它没有被归一化。通常,数据科学家必须花费超过50%的时间来清理和转换数据,然后才能将其输入深度神经网络。

 

什么是转换?

数据转换是一个广义的术语,用来描述适合于输入函数的数据转换。在深度学习环境中,这通常意味着获取原始文件(如csv)、删除列或计算新列、按公共键对行进行分组(如果创建序列)、规范化数据(通常是统计数据),最后将输入矢量化为NDArrays
skil支持在DataVec中实现的转换的特定实现。这些转换也可以通过JSON格式序列化。

 

转换的类型
在skil中,我们可以构建和部署两种类型的转换。

 

CSV 转换

 CSV转换使用文本CSV数据。它们要求首先建立一个概要,该概要指定与每一列相关的元数据,以及数据源中的类型。在概要建立之后,你可以定义要对数据执行的不同转换过程。你可以删除列,更改它们的数据类型,对它们进行分类并归一化数据。

 

图像转换

图像转换在图像上进行。它们用于通过图像转换过程缩放、过滤和裁剪图像。它们主要以图像为输入,在其上运行转换列表并返回转换后的图像。

 

转换流程

你可以在skil工作间实验中使用任何Zeppelin笔记本来构建你自己的转换。

 

CSV 转换

我们可以通过以下方式构建一个csv转换:

 

创建一个概要

如果示例数据看起来像这样:5.1,3.5,1.4,0.2,Iris-setosa,其中逗号分隔的序列为sepal length、sepal width、patal length、patal width和label的类别,则概要将如下所示:

import org.datavec.api.transform.schema.Schema

val schema = new Schema.Builder()
            .addColumnsDouble("Sepal length", "Sepal width", "Petal length", "Petal width") // 定义"Double"类型的列
            .addColumnCategorical("Species", "Iris-setosa", "Iris-versicolor", "Iris-virginica") // 定义分类数据-列名后跟着分类元素
            .build(); 

 

定义一个转换过程(TransformProcess)

如果我们要将类别标签转换为整数符号,可以按以下方式进行转换:

import org.datavec.api.transform.TransformProcess

val tp = new TransformProcess.Builder(schema) // 从初始化创建的概要开始
            .categoricalToInteger("Species") // 转换分类为它们对应的整型值
            .build();

如果你想知道更多细节,请查看datavec的javadocs中的 TransformProcess.

 

执行转换

你需要定义一个Spark作业来执行转换过程。按以下方式完成:

/* 下载数据 */
import org.apache.commons.io.FileUtils

import java.io.File
import java.net.URL

val filename = "/tmp/iris.data"

val url = new URL("https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data")

val irisText = new File(filename)
if (!irisText.exists()){
    FileUtils.copyURLToFile(url, irisText)
}

/* ---------------------------------------------------------------------- */

/* 执行CSV转换*/
import org.apache.spark.api.java.JavaRDD
import org.apache.spark.api.java.JavaSparkContext
import org.datavec.api.writable.Writable
import org.datavec.api.records.reader.impl.csv.CSVRecordReader
import org.datavec.spark.transform.misc.StringToWritablesFunction

val jsc = JavaSparkContext.fromSparkContext(sc) //从zeppelin的SparkContext中创建一个JavaSparkContext
val stringData = jsc.textFile(filename) // 将数据读取为JavaRDD[String]

val rr = new CSVRecordReader()
val parsedInputData = stringData.filter((line: String) => !(line.isEmpty())).toJavaRDD().map(new StringToWritablesFunction(rr)); // 把Strings转为Writables的列表

val processedData = SparkTransformExecutor.execute(parsedInputData, tp) //执行转换过程

/* ---------------------------------------------------------------------- */

/* 查看数据 */
import org.datavec.spark.transform.misc.WritablesToStringFunction
import scala.collection.JavaConversions._ // 从Java列表到Scala列表的隐式转换

val processedAsString = processedData.map(new WritablesToStringFunction(",")) // 从JavaRDD 转换为 String
val inputDataParsed = processedAsString.collect()	// 执行和收集处理的输入数据

inputDataParsed.foreach { println } // 打印数据

执行转换不是必须的

在这里,我们执行转换只是为了显示基本的转换流程。你不必执行转换过程来保存和部署它。至少,你可以定义TransformProcess或ImageTransformProcess并保存它。我们只需要转换过程JSON来部署它。

 

保存转换

我们的转换现在可以保存了。你可以使用TransformProcess.toJson函数保存你实现的转换。

import java.nio.file.{Paths, Files}
import java.nio.charset.StandardCharsets

val transformProcessJson = tp.toJson()

Files.write(Paths.get("/tmp/transformProcess.json"), transformProcessJson.getBytes(StandardCharsets.UTF_8)) // 保存转换过程

 

图像转换

图像转换过程由ImageTransform列表定义为:

 

定义一个ImageTransformProcess

图像转换过程可以构建为:

import org.datavec.image.transform.ImageTransformProcess

val itp = new ImageTransformProcess.Builder()
    .seed(12345) // 随机种子
    .cropImageTransform(10, 10, 100, 100) // Top, Left, Bottom, Right
    .build 

有关ImageTransform实现的更多详细信息,请参见此处

 

保存图像转换

图像转换过程也可以与转换过程相同的方式保存。

import java.nio.file.{Paths, Files}
import java.nio.charset.StandardCharsets

val imageTransformProcessJson = itp.toJson()

Files.write(Paths.get("/tmp/imageTransformProcess.json"), imageTransformProcessJson.getBytes(StandardCharsets.UTF_8)) //保存图像转换过程

猜你喜欢

转载自blog.csdn.net/bewithme/article/details/89302971