如何读取Mahout聚类输出

4

我在Mahout教程中运行了k-Means聚类算法,使用了合成控制数据,并想知道如何解释输出结果。我运行了clusterdump并收到了以下类似的输出(为节省空间而截断):

CL-592{n=57 c=30.726, 29.813...] r=[3.528, 3.597...]}
Weight : [props - optional]: Point:
1.0 : [distance=27.453962995925863]: [24.672, 35.261, 30.486...]
1.0 : [distance=27.675053294846002]: [25.592, 29.951, 34.188...]
1.0 : [distance=28.97727289419493]: [30.696, 32.667, 34.223...]
1.0 : [distance=21.999685652862784]: [32.702, 35.219, 30.143...]
...
CL-598{n=50 c=[29.611, 29.769...] r=[3.166, 3.561...]}
Weight : [props - optional]:  Point:
1.0 : [distance=27.266203490250472]: [27.679, 33.506, 23.594...]
1.0 : [distance=28.749781351838173]: [34.727, 28.325, 30.331...]
1.0 : [distance=32.635136046420186]: [27.758, 33.859, 29.879...]
1.0 : [distance=29.328974057024624]: [29.356, 26.793, 25.575...]

能有人向我解释一下如何阅读这个内容吗?从我的理解来看,CL-__是一个群集ID,后面跟着n=群集中的点数、c=作为矢量的质心、r=作为矢量的半径,然后是群集中的每个点。这样正确吗?此外,我该如何知道哪个聚类点与哪个输入点匹配?例如,被描述为键值对的点,其中键是点的某种ID,而值是向量吗?如果不是,是否有一些方法可以设置它呢?


不好意思这样打扰你,但是你是怎么得到聚类点的呢?我可以得到聚类中心,但是我不知道如何获取点与它们被分配到的簇之间的关系。 - Kobe-Wan Kenobi
3个回答

7

我认为你对数据的解释是正确的(我只使用Mahout工作了约3周,所以更有经验的人可能会对此发表意见)。

至于将点链接回创建它们的输入,我使用了NamedVector,其中名称是向量的键。当您读取生成的点文件(clusteredPoints)之一时,您可以将每行(点向量)转换回NamedVector,并使用.getName()检索名称。

响应评论的更新

当您最初将数据读入Mahout中时,您将其转换为矢量集合,然后将其写入用于稍后聚类算法的文件(points)。Mahout为您提供了几种可以使用的Vector类型,但它们还提供了访问Vector包装器类的NamedVector,它将允许您标识每个向量。

例如,您可以按以下方式创建每个NamedVector

NamedVector nVec = new NamedVector(
    new SequentialAccessSparseVector(vectorDimensions), 
    vectorName
    );

然后,您可以使用以下类似代码将您的NamedVectors集合写入文件:
SequenceFile.Writer writer = new SequenceFile.Writer(...);
VectorWritable writable = new VectorWritable();

// the next two lines will be in a loop, but I'm omitting it for clarity
writable.set(nVec);
writer.append(new Text(nVec.getName()), nVec);

现在,您可以将此文件用作聚类算法之一的输入。

在使用点文件运行聚类算法后,它将生成另一个点文件,但它将位于名为clusteredPoints的目录中。

然后,您可以读取此点文件并提取与每个向量相关联的名称。它看起来像这样:

IntWritable clusterId = new IntWritable();
WeightedPropertyVectorWritable vector = new WeightedPropertyVectorWritable();

while (reader.next(clusterId, vector))
{
    NamedVector nVec = (NamedVector)vector.getVector();
    // you now have access to the original name using nVec.getName()
}

谢谢你的回答,@JesseBuesking。我也是一个初学者,所以需要一些帮助理解你的回答。你在哪里定义了点作为“NamedVector”?我从何时何地可以使用“.getName()”?谢谢。 - Alison

0
尝试在clusterdump中添加选项-of CSV,您将获得更易于进一步处理的结果。

-1

我也遇到了同样的问题(使用mahout 0.6)。我也是一个初学者。我需要以聚类的形式向用户展示文档。因此,我需要文档名称而不是对应于聚类的单词。我一直在使用shell脚本对文本文档进行聚类。


Seqdumper可以用于获取集群和文件的映射。 - user2039862
如果您希望输出包含文件名,而不是向量,请使用命名向量属性。 - user2039862

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接