使用Hadoop做K-Means计算的总结

2019-03-28 13:56|来源: 网络

以K均值聚类算法为实验对象。

通过调整各项Hadoop参数,已经不能再进一步缩短K均值迭代的时间,在计算过程中,CPU User态的使用率始终维持在95%左右。

尝试过的配置项有:

mapred.min.split.size

io.sort.mb

io.sort.spill.percent

io.sort.factor

min.num.spill.for.combine

mapred.child.java.opts

mapred.reduce.tasks

mapred.compress.map.output

dfs.data.dir     这里设置多个分布在不同存储设备上的目录,可以明显的提高IO效率。

由于Hadoop的原理是将大数据切分成数据块,多个数据块的处理可以并行,www.linuxidc.com 所以,对整个作业的优化问题,可以转化为对处理单个数据块的过程的优化。也就是想办法优化一个MapTask。

在试验中,5个计算节点,一个MapTask的执行时间为130s,输入是512M的数据,包含约2,800,000条记录。

在相同的机器上进行单机实验,使用一个包含3,000,000条记录的512M的文件作为输入,边读文件边计算,耗时41s; 不计算读文件时间,运算时间仅耗时13s。

由此推断,一个MapTask中,只有三分之一的时间消耗在读文件和运算上。看来Map端的shuffle时间比较长。

下面是一个比较详细的MapTask运行机理,其中对shuffle阶段的描述比较详细:

1.        在map task执行时,它的输入数据来源于HDFS的block,当然在MapReduce概念中,map task只读取split。Split与block的对应关系可能是多对一,默认是一对一。在WordCount例子里,假设map的输入数据都是像“aaa”这样的字符串。

2.        在经过mapper的运行后,我们得知mapper的输出是这样一个key/value对: key是“aaa”, value是数值1。因为当前map端只做加1的操作,在reduce task里才去合并结果集。前面我们知道这个job有3个reduce task,到底当前的“aaa”应该交由哪个reduce去做呢,是需要现在决定的。

MapReduce提供Partitioner接口,它的作用就是根据key或value及reduce的数量来决定当前的这对输出数据最终应该交由哪个reduce task处理。默认对key hash后再以reduce task数量取模。默认的取模方式只是为了平均reduce的处理能力,如果用户自己对Partitioner有需求,可以订制并设置到job上。

在我们的例子中,“aaa”经过Partitioner后返回0,也就是这对值应当交由第一个reducer来处理。接下来,需要将数据写入内存缓冲区中,缓冲区的作用是批量收集map结果,减少磁盘IO的影响。我们的key/value对以及Partition的结果都会被写入缓冲区。当然写入之前,key与value值都会被序列化成字节数组。

整个内存缓冲区就是一个字节数组,它的字节索引及key/value存储结构我没有研究过。如果有朋友对它有研究,那么请大致描述下它的细节吧。

相关问答

更多
  • Scipy的集群实现工作很好,它们包括k-means实现。 还有scipy-cluster ,它是聚集的聚类; 它的优点是您不需要提前决定集群的数量。 Scipy's clustering implementations work well, and they include a k-means implementation. There's also scipy-cluster, which does agglomerative clustering; ths has the advantage that ...
  • 正确,结果可能不同。 要点:x1 =(0,0),x2 =(1,1),x3 =(0.75,0),x4 =(0.25,1); m1 =(0,0.5),m2 =(1,0.5)。 K-means将x1和x4分配给m1-cluster,将x2和x3分配给m2-cluster。 新均值为m1'=(0.125,0.5),m2'=(0.875,0.5),不进行重新分配。 使用顺序K均值,在指定x1之后,m1移动到(0,0),x2移动m2到(1,1)。 那么m1最接近于x3,所以m1移动到(0.375,0)。 最后,m2最接 ...
  • 您可以使用矢量量化。 您可以在x + 1和y + 1方向上制作每个像素和每个相邻像素的列表,然后选择差异并沿对角线绘制它。 然后,您可以计算voronoi图并获得平均颜色并计算特征向量。 然后使用简单的基于网格的平均颜色会更有效。 You can use a vector quantisation. You can make a list of each pixel and each adjacent pixel in x+1 and y+1 direction and pick the differenc ...
  • 这取决于你所说的k -means。 寻找k-均值目标函数全局最优的问题 是NP难的。 然而,运行标准算法的迭代次数为固定数目i只需要在d维中有n个点的O( iknd ),这就是实际的实现(通常在迭代之间随机重启)。 标准算法仅接近上述函数的局部最优值,所以我见过的所有k均值算法都是这样。 It depends on what you call k-means. The problem of finding the global optimum of the k-means objective functio ...
  • 找到解决方案,也许有人会使用: public static List DoKMeans(PointCollection points, int clusterCount, Point[] startingCentres) { // code... int ctr = 0; foreach (List group in allGroups) { PointCollection cluster = new Point ...
  • 是的,您应该将矩阵重新1xN为1xN向量,其中N对应于您正在聚类的色调值的数量。 每个被视为要聚类的单个数据点。 k-means的很大一部分是找到正确的聚类中心。 这种情况适合您,不需要先验设置。 如果要初始化具有良好中心的群集,请查看k-means ++ ,但在运行k-means之前不必查找群集中心。 要在聚类之后获得计算的聚类中心,您只需要查看从k-means调用提供的输出数组。 签名如下: double kmeans(InputArray data,int K,InputOutputArray bes ...
  • KMeansDataGenerator使用sc.parallelize来生成数据。 sc.parallelize有一个参数是分区号。 您可以通过KMeansDataGenerator选项进行更改。 之后, SparkKMeans将在整个k-means算法中使用此分区号。 每个从节点是否获得一个数据文件分区? Spark不保证分区的位置。 但是,它会尝试将计算安排到具有分区文件的最近节点。 KMeansDataGenerator uses sc.parallelize to generate the data ...
  • 您可以尝试均值移位聚类,它的行为类似于k-means聚类,并且没有ak参数。 基本思想如下:聚类就像增加数据集中的“高频”或“锐化”数据集一样,以便找到“模式”(“模式”对应于数据集中的重要“趋势”) )。 逆操作,即平滑数据集,更容易定义(简而言之,用其邻居的平均值替换每个样本)。 因此,根据此定义,您可以提取信号的“高频”分量,作为初始信号和平滑信号之间的差异。 这为您提供了“渐变方向”或“良好移动”,可以锐化信号。 在该过程结束时,所有样本将聚集在少量的点中,对应于“模式”。 参考: https : ...
  • 您可以使用方法predict为矩阵X每个样本获取最近的聚类: from sklearn.cluster import KMeans model = KMeans(n_clusters=K) model.fit(X_train) label = model.predict(X_test) You can use the method predict to get the closest cluster for each sample in a matrix X: from sklearn.cluster ...
  • 为什么k-means不适用于任意距离 K-means不是基于距离的算法。 K均值最小化了群内平方和,这是一种方差(它大致是所有群集的加权平均方差,其中每个对象和维度被赋予相同的权重)。 为了使Lloyds算法收敛,您需要让两个步骤优化相同的函数: 重新分配步骤 质心更新步骤 现在,“均值”函数是最小二乘估计。 即,在步骤2中选择均值对于WCSS目标是最佳的。 在步骤1中通过最小二乘偏差(=欧氏距离平方,单调欧几里德距离)分配对象也可以保证收敛。 平均值正是你的环绕式想法会崩溃的地方 。 如果按照@elyas ...