2012-05-27 74 views
5

我知道凝聚式聚類算法,它以每個數據點作爲單獨的聚類開始,然後將點組合以形成聚類。從零開始實現自定義凝聚算法

現在,我有一個n維空間和幾個數據點,其中每個維度的值。我想基於像業務規則進行聚類兩點/集羣:

  • 羣集兩點C1和C2如果跨過維度1簇之間的距離爲T1 <,以及跨維度的距離2 < T2,.. 。和跨度n的距離< Tn。
  • 如果跨維度1規則被滿足,跨維度2規則滿足,則羣集他們沒有理會其他尺寸...

....以及類似的自定義規則。另外,我有自己的方式來定義和測量任何兩個集羣之間在任何特定維度上的距離。維度可能只包含字符串,我想定義我自己的字符串距離度量。在另一個維度中,它可以保存位置的名稱,並且沿着該維度的兩個點之間的距離是名稱位置之間的地理距離,以及其他維度的地理距離。

是否有框架/軟件讓我實現這種定義自定義距離度量標準的方法,然後實現凝聚性聚類?當然,當商業規則在任何時間點都不符合時,聚集性聚類就會停止,並且我們在最後的n維空間中形成聚類。

感謝 阿布舍克小號

+0

我想用JAVA,並優選(如果可用)或我:-) –

回答

4

您可以用Weka做到這一點。

您將不得不執行Distance Function,並使用setDistanceFunction(DistanceFunction distanceFunction)方法將它傳遞給Hierarchical Clusterer

在Weka中其他可用的clusterers是:蛛網,EM,FarthestFirst,FilteredClusterer,MakeDensityBasedClusterer,RandomizableClusterer,RandomizableDensityBasedClusterer,RandomizableSingleClustererEnhancer,SimpleKMeans,SingleClustererEnhancer。

一個例子距離函數,從NormalizableDistance類:

/** Index in ranges for MIN. */ 
    public static final int R_MIN = 0; 

    /** Index in ranges for MAX. */ 

    public static final int R_MAX = 1; 

    /** Index in ranges for WIDTH. */ 
    public static final int R_WIDTH = 2; 

    /** the instances used internally. */ 
    protected Instances m_Data = null; 

    /** True if normalization is turned off (default false).*/ 
    protected boolean m_DontNormalize = false; 

    /** The range of the attributes. */ 
    protected double[][] m_Ranges; 

    /** The range of attributes to use for calculating the distance. */ 
    protected Range m_AttributeIndices = new Range("first-last"); 

    /** The boolean flags, whether an attribute will be used or not. */ 
    protected boolean[] m_ActiveIndices; 

    /** Whether all the necessary preparations have been done. */ 
    protected boolean m_Validated; 


public double distance(Instance first, Instance second, double cutOffValue, PerformanceStats stats) { 
    double distance = 0; 
    int firstI, secondI; 
    int firstNumValues = first.numValues(); 
    int secondNumValues = second.numValues(); 
    int numAttributes = m_Data.numAttributes(); 
    int classIndex = m_Data.classIndex(); 

    validate(); 

    for (int p1 = 0, p2 = 0; p1 < firstNumValues || p2 < secondNumValues;) { 
     if (p1 >= firstNumValues) 
     firstI = numAttributes; 
     else 
     firstI = first.index(p1); 

     if (p2 >= secondNumValues) 
     secondI = numAttributes; 
     else 
     secondI = second.index(p2); 

     if (firstI == classIndex) { 
     p1++; 
     continue; 
     } 
     if ((firstI < numAttributes) && !m_ActiveIndices[firstI]) { 
     p1++; 
     continue; 
     } 

     if (secondI == classIndex) { 
     p2++; 
     continue; 
     } 
     if ((secondI < numAttributes) && !m_ActiveIndices[secondI]) { 
     p2++; 
     continue; 
     } 

     double diff; 

     if (firstI == secondI) { 
     diff = difference(firstI, 
        first.valueSparse(p1), 
        second.valueSparse(p2)); 
     p1++; 
     p2++; 
     } 
     else if (firstI > secondI) { 
     diff = difference(secondI, 
        0, second.valueSparse(p2)); 
     p2++; 
     } 
     else { 
     diff = difference(firstI, 
        first.valueSparse(p1), 0); 
     p1++; 
     } 
     if (stats != null) 
     stats.incrCoordCount(); 

     distance = updateDistance(distance, diff); 
     if (distance > cutOffValue) 
     return Double.POSITIVE_INFINITY; 
    } 

    return distance; 
    } 

顯示可分開處理的各種尺寸(被稱爲屬性在Weka中)。因此,您可以爲每個維度/屬性定義不同的距離。

關於避免將某些實例聚集在一起的業務規則。我認爲你可以創建一個距離函數,當業務規則不滿意時返回Double.positiveInfinity

+0

使用框架,我們可以在不同的維度上分別設置距離函數?另外,只有業務規則匹配時,我們纔可以編寫業務規則來對兩個點/集羣進行集羣嗎? –

+0

我更新了我的答案。希望現在它回答你所有的問題:) –

+0

非常感謝Vitalij。你有可能解釋代碼嗎?我無法知道少數變量(如m_Data,m_ActiveIndices)是因爲它們沒有在方法中聲明。有一個參考教程可以告訴我這些變量是什麼嗎? –

2

ELKI是另一種選擇。它比Weka具有更多的聚類算法(對分類最有用)。他們甚至有一個Wiki教程解釋如何實現自定義距離功能(然後您應該可以在層次聚類中使用): distance function tutorial

注意,「業務規則」不指定距離函數一種很常見的方式...

+0

我想要指定跨各個維度計算的距離的業務規則。您是否知道一個允許我指定這些業務規則的框架,然後只有在業務規則匹配的情況下,框架纔會聚集兩個數據點/集羣? –

+0

Anony,你知道我在哪裏可以學習如何使用ELKI進行編程嗎?它看起來很有趣。 –

+0

您是否嘗試過發佈的教程鏈接?不,我永遠不會觸及商業規則。他們被稱爲「商業」廢話的原因。 –