2014-11-07 69 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