You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UMAP中实现自定义组合距离度量?

在UMAP中实现混合欧氏-Haversine加权距离的解决方案

问题核心

需要在UMAP中使用自定义混合距离度量:

distance(v1, v2) = alpha * euclidean(f1_eucl, f2_eucl) + beta * haversine(f1_hav, f2_hav)

其中f1_eucl为常规数值特征(用欧氏距离),f1_hav为GCS坐标(用Haversine距离)。你尝试的两种方法分别遇到了内存/性能问题、自定义函数不生效的问题。


自定义函数不生效的原因

你提到设置函数返回0但UMAP结果无变化,本质是自定义度量未被正确调用,常见原因:

  1. Numba编译失败:UMAP仅支持Numba JIT兼容的自定义函数,若函数包含Numba无法编译的代码(如Python第三方库调用、动态类型操作),会自动 fallback 到默认的欧氏距离。
  2. 特征划分错误:函数内未正确拆分欧氏特征与GCS坐标,导致实际计算的仍是全欧氏距离。
  3. 参数传递缺失:未通过metric_kwds传递alpha/beta/特征划分索引等参数,函数使用默认值(如beta=0),等价于纯欧氏距离。

正确实现自定义混合距离的步骤

1. 实现Numba兼容的Haversine距离

避免使用地理库(如geopy)的Haversine实现,改用纯NumPy+Numba的数值计算:

import numba
import numpy as np

@numba.njit()
def haversine(lat1, lon1, lat2, lon2):
    # 转换为弧度
    lat1_rad = np.radians(lat1)
    lon1_rad = np.radians(lon1)
    lat2_rad = np.radians(lat2)
    lon2_rad = np.radians(lon2)
    
    dlat = lat2_rad - lat1_rad
    dlon = lon2_rad - lon1_rad
    
    a = np.sin(dlat/2)**2 + np.cos(lat1_rad) * np.cos(lat2_rad) * np.sin(dlon/2)**2
    c = 2 * np.arcsin(np.sqrt(a))
    R = 6371.0  # 地球半径(公里)
    return c * R

2. 实现混合加权距离函数

明确拆分特征,支持通过参数调整权重与特征范围:

@numba.njit()
def mixed_distance(v1, v2, alpha=1.0, beta=1.0, eucl_end_idx=-2):
    # 拆分欧氏特征与GCS坐标:前eucl_end_idx个为欧氏特征,最后2个为坐标
    eucl_v1 = v1[:eucl_end_idx]
    eucl_v2 = v2[:eucl_end_idx]
    # 计算欧氏距离
    eucl_dist = np.sqrt(np.sum((eucl_v1 - eucl_v2)**2))
    # 计算Haversine距离
    lat1, lon1 = v1[-2], v1[-1]
    lat2, lon2 = v2[-2], v2[-1]
    hav_dist = haversine(lat1, lon1, lat2, lon2)
    # 加权求和
    return alpha * eucl_dist + beta * hav_dist

3. 在UMAP中调用自定义度量

通过metric传入函数,metric_kwds传递参数:

from umap import UMAP

# 示例数据:4096个样本,8个欧氏特征+2个GCS坐标
X = np.random.rand(4096, 10)

# 初始化UMAP模型
umap_model = UMAP(
    metric=mixed_distance,
    metric_kwds={"alpha": 0.5, "beta": 0.5, "eucl_end_idx": -2},
    n_neighbors=15,
    random_state=42,
    verbose=True  # 开启日志,确认自定义度量是否被加载
)
embedding = umap_model.fit_transform(X)

验证函数是否生效

  • 测试1:设置alpha=0, beta=1,降维结果应仅由GCS坐标决定
  • 测试2:设置beta=0, alpha=1,结果应与纯欧氏距离的UMAP结果一致

两种方法的优劣对比

  1. 预计算距离矩阵:

    • 弊端:内存开销为O(n²),当n较大时(如n>10k)完全不可行;合并两个矩阵时内存翻倍,计算效率远低于UMAP原生流程。
    • 仅适用于极小数据集(n<1k),不推荐使用。
  2. 自定义可调用函数:

    • 优势:内存开销O(n),计算效率与UMAP原生流程一致;通过Numba JIT编译实现高速计算。
    • 是大规模数据集下的最优方案。

方法合理性分析

这种混合加权距离的方案完全合理,属于多类型特征融合的常规手段:

  • 空间坐标与数值特征的距离度量逻辑不同,无法直接用单一距离函数覆盖
  • 通过alpha/beta加权可以平衡两类特征对降维结果的贡献,可根据业务需求或交叉验证调整权重
  • 注意:需先对欧氏特征做归一化(如StandardScaler),避免因特征尺度差异导致某类特征的贡献被完全掩盖

内容的提问来源于stack exchange,提问作者Yann Hoffmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:50:24