the*_*ope 5 scala apache-spark apache-spark-sql apache-spark-ml apache-spark-mllib
我正在使用Apache Spark和Scala来创建ML管道.在我的管道中,我所拥有的变形金刚之一join在此过程中很早就进行了昂贵的操作.由于我有很多功能,ParamGrid这意味着程序必须保持这个巨大的,加入DataFrame内存,同时优化网格中的每个功能.
为了尝试解决这个问题,我创建了一个自定义Transformer缓存这个大型中间件的自定义,DataFrame通过将其写入S3中的镶木地板并返回从镶木地板中读取的DataFrame.这很好用,并提高了模型的速度,直到我ParamGrid在缓存阶段之前添加了功能.当我将镶木地板写入S3时,我使用的路径由下式确定:
class Cacher(override val uid: String) extends Transformer {
// the cachePath variable determines the path within the S3 bucket
lazy val cachePath = Identifiable.randomUID(uid + "transformer-cache")
// ...
Run Code Online (Sandbox Code Playgroud)
我认为我误解了如何uid工作......我的信念是,无论什么时候Spark优化了ParamGrid,它都需要在管道中的那个阶段上演的任何类,创建它们的新实例,并给它们新的,独特的uids来跟踪他们 我怀疑缓存是错误的,因为Spark没有给它创建uid的新Transformer实例赋予独特性,这意味着无论何时Transformer创建缓存的新实例,缓存的镶木地板都会被不断覆盖.任何人都可以提供关于如何为uid管道创建的阶段的每个实例生成唯一的随机s的任何指针吗?
干杯!
一步步:
uid是Identifiable特征所必需的(Transformer扩展PipelineStage扩展Params扩展Identifiable)。根据Identifiable文档uid是:
对象及其派生对象的不可变唯一 ID 。
一般来说:
Params是可变的。设置参数返回this不影响uid。
import org.apache.spark.ml.feature.OneHotEncoder
val enc = new OneHotEncoder()
val enc_ = enc.setInputCol("foo")
enc == enc_
Run Code Online (Sandbox Code Playgroud)
Boolean = true
Run Code Online (Sandbox Code Playgroud)
enc.uid == enc_.uid
Run Code Online (Sandbox Code Playgroud)
Boolean = true
Run Code Online (Sandbox Code Playgroud)copying Params创建一个新实例但保持不变uid(请参阅上一点引用的强调部分)。
val encCopy = enc.copy(new org.apache.spark.ml.param.ParamMap())
encCopy == enc
Run Code Online (Sandbox Code Playgroud)
Boolean = false
Run Code Online (Sandbox Code Playgroud)
encCopy.uid == enc.uid
Run Code Online (Sandbox Code Playgroud)
Boolean = true
Run Code Online (Sandbox Code Playgroud)您可以尝试重写copy方法以避免复制父级uid,但这似乎与 make 背后的整个想法相冲突Params Identifiable。
可能的解决方案:
uid或使路径依赖于当前的参数集。Dataset.persist)。它不仅解决了当前的问题,还解决了退出时释放资源的隐藏问题。| 归档时间: |
|
| 查看次数: |
904 次 |
| 最近记录: |