scala – 了解UID在Spark MLLib Transformer中的作用
我正在使用Apache Spark和
Scala来创建ML管道.我在其管道中的变形金刚之一在此过程的早期就进行了昂贵的连接操作.由于我的ParamGrid中有很多功能,这意味着程序必须在内存中保存这个巨大的,连接的DataFrame,同时优化网格中的每个功能.
为了尝试解决这个问题,我创建了一个自定义Transformer,通过将其写入S3中的镶木地板并返回从镶木地板中读取的DataFrame来缓存此大型中间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") // ... 我认为我误解了uid是如何工作的…我的信念是每当Spark对ParamGrid进行优化时,就会在管道中的那个阶段进行任何类型的创建,创建它们的新实例,并为它们提供新的,独特的uid.跟踪他们.我怀疑缓存是错误的,因为Spark没有为它创建的新Transformer实例提供唯一的uid,这意味着只要创建了一个新的缓存Transformer实例,就会不断覆盖缓存的镶木地板.任何人都可以提供关于如何为管道创建的阶段的每个实例生成唯一的随机uid的任何指针吗? 干杯! 解决方法
一步步:
>可识别特征需要> uid(Transformer扩展PipelineStage,扩展Params,扩展可识别).
>一般情况下: >参数是可变的.设置参数会返回此值,不会影响uid. import org.apache.spark.ml.feature.OneHotEncoder val enc = new OneHotEncoder() val enc_ = enc.setInputCol("foo") enc == enc_ Boolean = true enc.uid == enc_.uid Boolean = true >复制Params会创建一个新实例但保持相同的uid(请参阅前一点引用的重点部分). val encCopy = enc.copy(new org.apache.spark.ml.param.ParamMap()) encCopy == enc Boolean = false encCopy.uid == enc.uid Boolean = true >您可以尝试覆盖 可能的解决方案: >根本不要使用变压器uid或使路径依赖于当前的参数集.>不要手动编写缓存文件并使用内置缓存机制(Dataset.persist).它不仅解决了手头的问题,还解决了一个隐藏的问题,即在退出时释放资源. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |