k-means聚类

szqfcxe2  于 2021-05-30  发布在  Hadoop
关注(0)|答案(1)|浏览(441)

我对机器学习和聚类分析不是很有经验,但我有以下问题:
我有~100kk-1000kk个数据块,我不能一次全部加载到内存中,我需要将其划分为若干类(比如1-10k类,甚至100k类),以便进一步分析。为此,我选择了在openimaj库(floatkmeans类)中实现的k-means算法。我知道k-means算法可以分为两个阶段:
学习阶段-在这里,我传递所有的数据,我必须创建/填充类
assignemnt阶段-在这里我可以询问集群给定的数据属于哪个类
我计划使用hadoop reduce阶段构建集群模型,在这个阶段我将一个接一个地接收数据片段(这就是为什么我不能一次将数据全部传递给算法)
我的问题是:
openimaj实现对于这种“bigdata”用例来说是最佳的吗?难道不是要花很长时间来计算吗?
有没有可能在hadoop reduce faze期间将数据“流”到算法中,以便学习集群?
是否可以将学习到的集群(模型)保存为字节,以便将模型传递给下一个hadoop作业?
在hadoopMap期间运行算法分配阶段可以吗?
谢谢你的帮助

o8x7eapl

o8x7eapl1#

k-means聚类是一种迭代算法,可以对数据进行多次传递。在每个过程中,将点指定给簇质心,然后在指定所有点后,将簇质心重新计算为指定点的平均值。在传统意义上,您不能将数据“流”到算法中,因为您需要在随后的迭代中返回到它。
关于openimaj FloatKMeans 实现:是的,这可以处理“大数据”,因为它不介意从哪里获取数据-从 DataSource 它作为输入的示例可以在必要时从磁盘读取数据。唯一的要求是,在算法运行期间,可以在内存中保留所有质心。这个实现是多线程的,所以所有的cpu核都可以在计算过程中使用。这里有一个示例代码:https://github.com/openimaj/openimaj/blob/master/demos/examples/src/main/java/org/openimaj/examples/ml/clustering/kmeans/bigdataclusterexample.java. openimaj IOUtils.writeBinary(...) 方法可用于将生成的簇质心保存在 FloatCentroidsResult 对象。
k-means的最大代价之一是计算每个数据点和每个簇质心之间的距离,以便找到最近的。这样做的代价与数据的维数和质心的数目有关。如果你有大量的质心和高维数据,那么使用一个近似的k-means实现可以有很大的速度优势,代价是精度上的轻微损失(参见 FloatKMeans.createKDTreeEnsemble() 例如,它使用kd树的集合来加速邻居计算)。
关于与hadoop的集成,可以将k-means实现为一系列map-reduce任务(每对任务对应于算法的一次迭代)。有关讨论,请参阅本文:http://eprints.soton.ac.uk/344243/1/paper.pdf . 如果您想沿着这条路线走下去,openimaj在这里有一个非常粗略的实现,您可以构建它:https://github.com/openimaj/openimaj/tree/master/hadoop/tools/hadoopfastkmeans. 如本文所述,apache mahout还包含一个实现:https://mahout.apache.org. 这两种实现的一个问题是,它们需要在Map器和reducer之间传输大量数据(每个Map器发出当前数据点及其分配的集群id)。这种程度可能意味着使用算法的非hadoop实现可能会更快,但这取决于可用的处理资源和数据集的性质。map和reduce之间的数据传输问题也可以通过一个聪明的hadoop来解决 Combiner 并从数据子集计算加权质心,然后将这些质心传递给(修改的)缩减器以计算实际质心。

相关问题