我需要在Scala中编写一个带有对象突变的for循环。在机器学习中,当进行聚类(将样本分配到最佳的独立组中)时,为了确定一组中的最佳组数,将使用不同的组号运行聚类算法,并为每个组号计算一些误差度量。最佳组数是组数图使误差度量成为弯头的地方。
在Spark ML库中,public function getTeam(Team $team)
{
// The team parameter is the given Team model instance.
// We can use directly
return response()->json($team);
}
对象用于对组号作为参数进行传递的群集。因此,我计算误差度量以绘制肘形图,如下所示:
KMeans
我必须将集群对象声明为var,并在每次迭代时对其进行变异。有没有更多scala方式来编写此代码?
答案 0 :(得分:3)
您可以避免var这样做:
2 to 10 map { k =>
baseClusterer.setK(k).fit(scaledDF).computeCost(scaledDF)
}
答案 1 :(得分:2)
注意:此版本是根据评论从原始版本修改的
如果要对其他数据重复此操作,则可能需要考虑创建一个集群列表,然后使用该列表:
val clusterers = (2 to 10).map(k =>
new KMeans()
.setFeaturesCol("scaledFeatures")
.setPredictionCol("clusters")
.setSeed(0)
.setk(k)
)
val costs = clusterers.map(_.fit(scaledDF).computeCost(scaledDF))
但是请参阅@BogdanVakulenko的答案,以找到重写原始版本的好方法。
还请注意,最好反复使用相同的k
和不同的setSeed
值来避免局部最小值。
答案 2 :(得分:0)
如果我正确理解了您的逻辑,也许您可以使用foldLeft,在该方法中,每个循环都将返回修改/更新的对象,如下所示:
val finalClusterer = (2 to 10).foldLeft(baseClusterer) { (accum, elem) =>
val newClusterer = accum.copy(k = k)
newClusterer.fit(scaledDF).computeCost(scaledDF)
}
这样一来,您最终将得到一个“ finalClusterer”,在其中始终以基数为原点进行操作。
编辑:我的代码使用baseClusterer作为case类,因此使用copy方法。如果您没有它,因为它好像是一个Java类,也许您可以创建一个充当包装器的隐式类,然后可以在其中定义这样的方法:
implicit class ClustererWrapper {
def copy {
...
}
}