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

如何用minhash处理全负元素数组?解决datasketch的NaN报错

解决datasketch WeightedMinHash的"All-NaN slice encountered"错误

问题根源

你遇到的ValueError: All-NaN slice encountered错误,本质是因为**WeightedMinHashGenerator.minhash()要求输入的向量元素必须是非负的**。当输入全为负数的向量时,底层代码执行np.log(w)(w为向量元素)会生成全NaN的数组,后续np.nanargmin处理全NaN数组时直接抛出错误。

你的第14行向量[-1.9261107, -2.7339218, -2.3160297, -2.0100772, -2.0696172, -0.79079717]全为负数,触发了这个问题;而前13行向量至少包含非负元素,所以能正常计算。

解决方案:数据预处理为非负区间

通过全局归一化将所有数据(包括Dataset和查询集Q)转换到非负区间,既满足WeightedMinHash的输入要求,又不会破坏向量间的相对距离关系(不影响top-k近邻的排序结果)。

具体步骤

  1. 合并Dataset和Q,计算全局的最小值和最大值,确保归一化范围覆盖所有数据;
  2. 使用Min-Max归一化将所有元素缩放到[0, 1]区间;
  3. 用归一化后的数据运行LSH索引和查询逻辑。

修改后的代码示例

import numpy as np
import time
from datasketch import WeightedMinHashGenerator, MinHashLSHForest

# 假设Dataset和Q是已加载的numpy数组
# 第一步:全局预处理,转换为非负
all_data = np.vstack([Dataset, Q])
global_min = all_data.min()
global_max = all_data.max()

# 归一化到[0,1]区间
Dataset_normalized = (Dataset - global_min) / (global_max - global_min)
Q_normalized = (Q - global_min) / (global_max - global_min)

if __name__=="__main__":
    M = WeightedMinHashGenerator(Dataset_normalized.shape[1])
    LSH_forest = MinHashLSHForest()
    
    # 用归一化后的Dataset构建索引
    for index, value in enumerate(Dataset_normalized):
        m_hash = M.minhash(value)
        LSH_forest.add(index, m_hash)

    LSH_forest.index()
    LSH_kneighbors = []
    
    time_start2 = time.perf_counter()
    # 用归一化后的Q执行查询
    for j in range(Q_normalized.shape[0]):
        LSH_kneighbors.append(LSH_forest.query(M.minhash(Q_normalized[j]), 10))

额外说明

如果你的数据中有0值,np.log(0)会得到-inf,但WeightedMinHash的底层逻辑可以处理这种情况(会选择对应最小的ln_a值),所以无需额外处理0值。如果需要更严格的正数输入,可以在归一化后给所有元素加一个极小的常数(比如1e-8),避免出现0值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:15:36