2014-11-07 70 views
5

我试图用Weka对一组数据进行K-Means聚类,检查不同的权重如何影响不同的属性。Weka总是为不同的数据生成相同的簇

但是,当我调整每个属性的权重时,我在聚类中看不到任何差异。

//Initialize file readers 
... 
Instances dataSet = readDataFile(dataReader); 
double[][] modifiers = readNormalizationFile(normReader, dataSet.numAttributes()); 
normalize(dataSet, modifiers); 
SimpleKMeans kMeans = new SimpleKMeans(); 
kMeans.setPreserveInstancesOrder(true); 
int[] clusters = null; 
try 
{ 
    System.out.println(kMeans.getSeed()); 
    if(distMet != 0) 
     kMeans.setDistanceFunction(new ManhattanDistance(dataSet)); 
    kMeans.setNumClusters(k); 
    kMeans.buildClusterer(dataSet); 

    clusters = kMeans.getAssignments(); 
} 
//Print clusters 

“修饰符”数组的第一维对应于每个属性,每个属性中有两个值。第一个从属性值中减去,然后结果除以第二个值。

正常化是这样的:

public static void normalize(Instances dataSet, double[][] modifiers) 
{ 
    for(int i = 0; i < dataSet.numInstances(); i++) 
    { 
     Instance currInst = dataSet.instance(i); 
     double[] values = currInst.toDoubleArray(); 
     for(int j = 0; j < values.length; j++) 
     { 
      currInst.setValue(j, (values[j] - modifiers[j][0])/modifiers[j][1]); 
     } 
    } 
} 

我的期望是,增加第二正常化应减少特定属性的重要性,聚类,并因此改变簇是如何分配的,而不是什么我正在观察。我的调试器显示正确的标准化值正在发送到群集器中,但我发现很难相信Weka正在搞乱我而不是我。

我是否正确使用了Weka的K-Means,还是我遗漏了一些重要的东西?

+0

Weka通常会自动标准化您的数据,从而破坏权重。改为尝试ELKI。 – 2014-11-07 07:24:59

+1

尽管Weka确实为我规范了数据,但我没有时间去取消所有的代码,然后重新启动另一个框架。正如下面回答的那样,只是告诉Weka不要规范化就更有意义了。 – MichaelPlante 2014-11-07 12:16:26

回答

2

有一个NormalizableDistance距离测量(如欧几里得和曼哈顿)称为dontNormalize的选项,它可能会自动为您规范化值。默认情况下,这将被启用,这可能会取消在normalize函数调用中完成的所有工作。

我为随机数据集运行测试,然后操纵其中一个属性数据进行第二次试验,并且两个聚类最终完全相同。将该值设置为true导致不同的群集,因此分配数据集中的实例。

希望这有助于!

+0

谢谢!就像一个笔记一样,我的程序默认使用EuclideanDistance,如果命令行选项指定它,它只使用Manhattan,但Euclidean具有相同的dontNormalize选项,因此该解决方案无论如何工作。 – MichaelPlante 2014-11-07 12:18:21

+0

我已更新我的回答,以更好地反映情况。谢谢。 – 2014-11-09 22:27:34