我試圖使用sklearn的聚集聚類命令執行約束聚類。爲了使算法受到限制,它請求「連通性矩陣」。這被描述爲:Scikit學習凝聚聚類連接矩陣
約束經由連接矩陣施加的連接:只在一個行的交叉處,並與應連接的數據集的索引的列具有元素SciPy的稀疏矩陣。這個矩陣可以由先驗信息構成:例如,你可能希望只通過將鏈接合併到一個指向另一個的鏈接來聚合網頁。
我有一個觀察對列表,我希望算法將強制保留在同一個集羣中。我可以將其轉換爲稀疏scipy
矩陣(coo
或csr
),但生成的集羣無法強制約束。
一些數據:
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)?
你的代碼不會像這樣運行:)也許值得在新的python會話中自己測試一下。 – Roelant
更新!感謝您的領導 –
您的連接矩陣無效。所有點必須連接在一起,因爲聚集聚類將所有點集中在一個層次結構中。 (你可以認爲所有點必須形成一個不能分離的圖,節點之間的邊可以關閉)。這就是你得到警告的原因。沒有什麼好方法可以做你想用凝聚聚類來做的事情。 – y300