Sklearn聚集聚类自定义亲和力

App*_*ics 1 python hierarchical-clustering scikit-learn sklearn-pandas

我试图将聚集聚类与自定义距离度量(即亲和力)一起使用,因为我想通过序列相似性而不是无意义的欧几里德距离对整数序列进行聚类。

我的数据看起来像这样

>> dat.values 

array([[860, 261, 240, ..., 300, 241,   1],
   [860, 840, 860, ..., 860, 240,   1],
   [260, 860, 260, ..., 260, 220,   1],
   ...,
   [260, 260, 260, ..., 260, 260,   1],
   [260, 860, 260, ..., 840, 860,   1],
   [280, 240, 241, ..., 240, 260,   1]]) 
Run Code Online (Sandbox Code Playgroud)

我创建了以下相似性函数

def sim(x, y): 
    return np.sum(np.equal(np.array(x), np.array(y)))/len(x)
Run Code Online (Sandbox Code Playgroud)

所以我只用numpy返回两个序列中的%匹配值,然后进行以下调用

cluster = AgglomerativeClustering(n_clusters=5, affinity=sim, linkage='average')
cluster.fit(dat.values)
Run Code Online (Sandbox Code Playgroud)

但我说错了

TypeError: sim() missing 1 required positional argument: 'y'
Run Code Online (Sandbox Code Playgroud)

我不确定为什么会收到此错误;我以为该函数将群集成对的行,因此将传递每个必需的参数。

任何帮助,将不胜感激

Viv*_*mar 5

'affinity'作为可调用对象,需要一个输入X(这是您的要素或观察矩阵),然后调用其中的所有点(样本)之间的距离。

因此,您需要将方法修改为:

# Your method to calculate distance between two samples
def sim(x, y): 
    return np.sum(np.equal(np.array(x), np.array(y)))/len(x)


# Method to calculate distances between all sample pairs
from sklearn.metrics import pairwise_distances
def sim_affinity(X):
    return pairwise_distances(X, metric=sim)

cluster = AgglomerativeClustering(n_clusters=5, affinity=sim_affinity, linkage='average')
cluster.fit(X)
Run Code Online (Sandbox Code Playgroud)

或者您可以affinity='precomputed'按照@avchauzov的建议使用。为此,您必须将预先计算的距离矩阵传递给中的观测值fit()。就像是:

cluster = AgglomerativeClustering(n_clusters=5, affinity='precomputed', linkage='average')
distance_matrix = sim_affinity(X)
cluster.fit(distance_matrix)
Run Code Online (Sandbox Code Playgroud)

注意:您已指定相似性代替距离。因此,请确保您了解群集在此处的工作方式。或者也许调整您的相似度函数以返回距离。就像是:

def sim(x, y): 
    # Subtracted from 1.0 (highest similarity), so now it represents distance
    return 1.0 - np.sum(np.equal(np.array(x), np.array(y)))/len(x)
Run Code Online (Sandbox Code Playgroud)