我最近在我的项目中尝试使用spark LBFGS方法,但是当我阅读源代码时,我真的遇到了一个大问题,这里是代码: the code I don't understand 这是源代码链接:https://github.com/apache/spark/blob/v1.6.0/mllib/src/main/scala/org/apache/spark/mllib/optimization/LBFGS.scala
我的问题是:如果我的输入数据(标签,功能)只包含标签和特征向量,treeAggregate seqOp如何匹配{case((grad,loss),(label,features)}?我认为它可以只匹配{case(label,features)}。
事实上,我并不真正理解" treeAggregate"或者,有人可以帮助我吗?
答案 0 :(得分:0)
我认为您真的不了解treeAggregate operation
。
在发布图片时,让我告诉您thorough description
您的问题。
之后您就会明白为什么源代码可以正确匹配!
如果您发现treeAggregate
令人困惑,您可以先了解它的简单但相似的版本 - aggregate
。
聚合的原型是:
def aggregate[U](zeroValue: U)(seqOp: (U, T) ⇒ U, combOp: (U, U) ⇒ U)(implicit arg0: ClassTag[U]): U
似乎复杂,对吗?让我为你澄清一下:
RDD为许多分区中的物理分布式数据提供抽象,那么我们如何汇总一个特定密钥的值?
显然有两种情况:
合并同一分区中的一个值。
跨不同分区合并数据。
seqOp: (U, V) ⇒ U
这正是操作如何在一个分区结果中合并值。
combOp: (U, U) ⇒ U
这是跨分区合并操作!
我猜您熟悉reduce
操作。
事实上,aggregate
操作比reduce
操作更通用。
为什么aggregate
存在,有时我们需要"减少"唯一键的值,但希望得到的结果与父级rdd 中的结果不同。
例如,如果我们想在父rdd中找到一个特定的键,它有多少个唯一值呢?
这"减少"操作的值类型明显不同于父rdd。
val pairs = sc.parallelize(Array(("a", 3), ("a", 1), ("b", 7), ("a", 5)))
val sets = pairs.aggregateByKey(new HashSet[Int])(_+_, _++_)
sets.collect
res0: Array[(String, scala.collection.mutable.HashSet[Int])] =Array((b,Set(7)), (a,Set(1, 5, 3))
示例是关于 aggregateByKey ,但聚合可以理解,只使用整个数据聚合,而不是关于不同的密钥。
全部。