0

我想用 HDBSCAN* 对一些数据进行聚类。

距离是根据两个值的某些参数的函数计算的,因此如果数据如下所示:

    label1 | label2 | label3
0    32        18.5     3
1    34.5      11       12
2    ..        ..      ..
3    ..        ..      ..

两个样本之间的距离将类似于:

def calc_dist(i,j)
     return 0.5 * dist_label1_func(data.iloc[i]['label1],data.iloc[j]['label1] + 
     0.4 * dist_label2_func(data.iloc[i]['label2],data.iloc[j]['label2] +
     0.1 * dist_label3_func(data.iloc[i]['label3],data.iloc[j]['label3]

由于数据的大小,我无法计算距离矩阵,所以似乎可调用是我唯一的选择。

我的代码看起来像:

clusterer = hdbscan.HDBSCAN(metric=calc_dist).fit(i=i,j=j)

错误:fit() got an unexpected keyword argument 'i

clusterer = hdbscan.HDBSCAN(metric=calc_dist).fit(i,j)

错误: ValueError: Expected 2D array, got scalar array instead:array=4830. Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

它不起作用,我还尝试将内部参数更改为原始数据集名称:

clusterer = hdbscan.HDBSCAN(metric=calc_dist).fit(data)

错误:raise ValueError("Found array with dim %d. %s expected <= 2.") ValueError: setting an array element with a sequence.

但它也不能接受。

我想念什么?

4

1 回答 1

1

通常回调会得到向量,而不是行索引。

所以也许你可以使用:

def calc_dist(i,j):
     return 0.5 * dist_label1_func(i['label1],j['label1]) + 
            0.4 * dist_label2_func(i['label2],j['label2]) +
            0.1 * dist_label3_func(i['label3],j['label3])

clusterer = hdbscan.HDBSCAN(metric=calc_dist).fit(data.iloc)

或者如果类型进入您的方式,您可以使用原始距离的索引数组:

def calc_dist(i,j):
     i, j = int(i[0]), int(j[0])
     return 0.5 * dist_label1_func(data.iloc[i]['label1],data.iloc[j]['label1]) + 
            0.4 * dist_label2_func(data.iloc[i]['label2],data.iloc[j]['label2]) +
            0.1 * dist_label3_func(data.iloc[i]['label3],data.iloc[j]['label3])

range = np.arange(0, len(data), dtype=np.int8).reshape(-1, 1)
clusterer = hdbscan.HDBSCAN(metric=calc_dist).fit(range)

请注意,使用自定义指标的 sklearn 和类似 python 库的性能可能非常差。Numba 可能会或可能不会帮助提高性能;对于足够小的数据,通常建议计算成对矩阵并使用metric="precomputed",因为编写高效的代码来预先计算矩阵通常要容易得多(并使用现有的高效代码来处理预先计算的矩阵),而不是获取自定义指标在库代码中高效。这是因为 python 被解释了;所以每次距离计算都需要经过解释器。具有强大 JIT 编译器的 Java 等语言通常更擅长优化此类情况。

于 2019-12-16T09:45:05.593 回答