2017-03-15 84 views
4

我試圖使用sklearn的聚集聚類命令執行約束聚類。爲了使算法受到限制,它請求「連通性矩陣」。這被描述爲:Scikit學習凝聚聚類連接矩陣

約束經由連接矩陣施加的連接:只在一個行的交叉處,並與應連接的數據集的索引的列具有元素SciPy的稀疏矩陣。這個矩陣可以由先驗信息構成:例如,你可能希望只通過將鏈接合併到一個指向另一個的鏈接來聚合網頁。

我有一個觀察對列表,我希望算法將強制保留在同一個集羣中。我可以將其轉換爲稀疏scipy矩陣(coocsr),但生成的集羣無法強制約束。

一些數據:

import numpy as np 
import scipy as sp 
import pandas as pd 
import scipy.sparse as ss 
from sklearn.cluster import AgglomerativeClustering 


# unique ids 
ids = np.arange(10) 

# Pairs that should belong to the same cluster 
mustLink = pd.DataFrame([[1, 2], [1, 3], [4, 6]], columns=['A', 'B']) 

# Features for training the model 
data = pd.DataFrame([ 
[.0873,-1.619,-1.343], 
[0.697456, 0.410943, 0.804333], 
[-1.295829, -0.709441, -0.376771], 
[-0.404985, -0.107366, 0.875791], 
[-0.404985, -0.107366, 0.875791], 
[-0.515996, 0.731980, -1.569586], 
[1.024580, 0.409148, 0.149408], 
[-0.074604, 1.269414, 0.115744], 
[-0.006706, 2.097276, 0.681819], 
[-0.432196, 1.249149,-1.159271]]) 

轉換成對一個 「連接矩陣」:

# Blank coo matrix to csr 
sm = ss.coo_matrix((len(ids), len(ids)), np.int32).tocsr() 
# Insert 1 for connected pairs and diagonals 
for i in np.arange(len(mustLink)): # add links to both sides of the matrix 
    sm[mustLink.loc[i, 'A'], mustLink.loc[i, 'B']] = 1 
    sm[mustLink.loc[i, 'B'], mustLink.loc[i, 'A']] = 1 
for i in np.arange(sm.tocsr()[1].shape[1]): # add diagonals 
    sm[i,i] = 1 
sm = sm.tocoo() # convert back to coo format 

火車和適應凝聚聚類模式:

m = AgglomerativeClustering(n_clusters=6, connectivity=sm) 
out = m.fit_predict(X=data) 

警告我得到:

UserWarning:連接矩陣的連接組件數量爲7> 1.完成此操作以避免提早停止樹。 連接,n_components = _fix_connectivity(X,連接)

除不祥的警告,我希望會屬於同一個集羣的對,沒有。

這是因爲sklearn算法不是設計來處理mustlink約束,而是隻能使用distance矩陣(區別here)?

+1

你的代碼不會像這樣運行:)也許值得在新的python會話中自己測試一下。 – Roelant

+0

更新!感謝您的領導 –

+1

您的連接矩陣無效。所有點必須連接在一起,因爲聚集聚類將所有點集中在一個層次結構中。 (你可以認爲所有點必須形成一個不能分離的圖,節點之間的邊可以關閉)。這就是你得到警告的原因。沒有什麼好方法可以做你想用凝聚聚類來做的事情。 – y300

回答

3

將連通性矩陣傳遞給sklearn.cluster.AgglomerativeClustering時,必須連接矩陣中的所有點。凝聚式聚類創建了一個層次結構,其中所有點都被迭代地分組在一起,因此孤立的聚類不能存在。連接矩陣有助於「關閉」可能在歐幾里得空間附近的點的連接,但與另一個度量標準相距甚遠(請參閱用戶指南here中的果凍卷示例)。

另一種想法是,你的觀點必須形成一個不脫節的圖形,你所能做的就是關閉節點之間的邊界。

此警告:

UserWarning:連接矩陣的連接部件的數量是7> 1.完成,以避免早期停止樹。連通性,n_components = _fix_connectivity(X,連通性)

告訴你,你有7個不相交的羣集,這是超過允許的1。因爲這樣的sklearn「完成」它(基本上填充它不會有不相交的集羣),這就是爲什麼你的約束完全不受尊重。

這裏沒有簡單的解決方法。您可以在集羣后嘗試重新分配中心來尊重您的約束條件,否則您需要使用不同的算法。