我正在尝试使用自定义距离度量(即亲和力)使用团聚聚类,因为我想按序列相似性将整数序列聚集,而不是像Euclidean距离一样没有意义。
我的数据看起来像这样
>> 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]])
我已经创建了以下相似性函数
def sim(x, y):
return np.sum(np.equal(np.array(x), np.array(y)))/len(x)
因此,我只用numpy返回两个序列中的%匹配值,然后进行以下调用
cluster = AgglomerativeClustering(n_clusters=5, affinity=sim, linkage='average')
cluster.fit(dat.values)
但是我遇到了一个错误,说
TypeError: sim() missing 1 required positional argument: 'y'
我不确定为什么要遇到这个错误;我认为该功能将群集对行,因此每个必需的参数将通过。
对此的任何帮助将不胜感激
'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)
您可以使用 affinity='precomputed'
,如@avchauzov所建议的那样。为此,您将必须通过fit()
中的观察结果传递预定的距离矩阵。类似:
cluster = AgglomerativeClustering(n_clusters=5, affinity='precomputed', linkage='average')
distance_matrix = sim_affinity(X)
cluster.fit(distance_matrix)
注意:您已经指定了相似性代替距离。因此,请确保您了解聚类在这里如何工作。或者也许调整您的相似性功能以返回距离。类似:
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)
这样做的常见方法是放置 affinity='precomputed
并适合距离矩阵(请参阅此处:https://gist.github.com/codehacken/8b9316e025beeabbbb082dda42da4d0654a6fa)
upd在sklearn.hierarchical.py中不是y)作为输入。输入应为linkage_tree。因此,您需要重写SIM()函数。
,但我认为第一种方法更加方便。