JAVA implementation for Locality Sensitive Hash

private int dimention; //维度大小,例如对于sift特征来说就是128

private int max; //所需向量中元素可能的上限,譬如对于RGB来说,就是255

private int hashCount; //哈希表的数量,用于更大程度地削减false positive

//LSH随机选取的采样位数,该值越小,则近似查找能力越大,但相应的false positive也越大;若该值等于size,则为由近似查找退化为精确匹配

private int bitCount; 

private int size; //转化为01字符串之后的位数,等于max乘以dimensions

private int[][] hashFamily; //LSH哈希族,保存了随机采样点的INDEX

VectorComparator comparator; 

// private HashMap<String, ArrayList<IdentifiedVector>> map;

private HashMap<String, ArrayList<String>> map;

 

public SimpleLSH(int dimention, int max, int hashCount, int bitCount) {

    this.dimention = dimention;

    this.max = max;

    this.hashCount = hashCount;

    this.bitCount = bitCount;

    this.size = this.dimention * this.max;

    this.hashFamily = new int[hashCount][bitCount];

    // map = new HashMap<String, ArrayList<IdentifiedVector>>();

    map = new HashMap<String, ArrayList<String>>();

    this.comparator = new VectorComparator(new int[] { 0 });

}

 

//生成随机的投影点

private void generataHashFamily() {

    Random rd = new Random();

    for (int i = 0; i < hashCount; i++) {

    for (int j = 0; j < bitCount; j++) {

        hashFamily[i][j] = rd.nextInt(size);

    }

}

 

//将向量转化为二进制字符串,比如元素的最大范围255,则元素65就被转化为65个1以及190个0

private int[] unAray(int[] data) {

    int unArayData[] = new int[size];

    for (int i = 0; i < data.length; i++) {

        for (int j = 0; j < data[i]; j++) {

   unArayData[i * max + j] = 1;

        }

    }

    return unArayData;

}

 

//将向量映射为LSH中的key

private String generateHashKey(int[] list, int hashNum) {

    StringBuilder sb = new StringBuilder();

    int[] tempData = unAray(list);

    int[] hashedData = new int[bitCount];

    //首先将向量转为二进制字符串

    for (int i = 0; i < bitCount; i++) {

        hashedData[i] = tempData[hashFamily[hashNum][i]];

sb.append(hashedData[i]);

// System.out.print(hashedData[i]);

    }

 

    //再用常规hash函数比如MD5对key进行压缩

    MessageDigest messageDigest = null;

    try 

    {

        messageDigest = MessageDigest.getInstance("MD5");

    }

    catch (NoSuchAlgorithmException e) {

    }

 

    byte[] binary = sb.toString().getBytes();

    byte[] hash = messageDigest.digest(binary);

    String hashV = MathUtils.getHexDigest(hash);

    return hashV;

}

 

//将向量映射为LSH中的key,并保存至map中

private void generateHashMap(String id, int[] vercotr) {

    for (int j = 0; j < hashCount; j++) {

        String key = generateHashKey(vercotr, j);

        ArrayList<String> l;

        if (map.containsKey(key)) {

            l = map.get(key);

        } else {

            l = new ArrayList<String>();

        }

        l.add(id);

        map.put(key, l);

    }

}

 

// 查询与输入向量最接近(海明空间)的向量

public Set<String> query(int[] data) {

    // Set<IdentifiedVector> result = new HashSet<IdentifiedVector>();

    Set<String> result = new HashSet<String>();

    for (int j = 0; j < hashCount; j++) {

        String key = generateHashKey(data, j);

        if (map.containsKey(key)) {

            result.addAll(map.get(key));

        }

    }

    return result;

}

我利用上面的LSH对图片的边缘直方图特征进行建模,获得了不错的效果,可以用于近似图片的查找,效果如下: 

感谢原创

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 局部敏感哈希(Locality Sensitive Hashing)是一种用于高维数据相似性搜索的技术。它通过将高维数据映射到低维空间中,并在低维空间中使用哈希函数来快速识别相似的数据点。这种技术在大规模数据处理和机器学习中得到广泛应用。 ### 回答2: 局部敏感哈希(Locality Sensitive Hashing,LSH)是一种近似近邻搜索(Approximate Nearest Neighbor Search,ANNS)算法,用于高维数据的快速相似性搜索。它的基本思想是将相似的点映射成同一个桶中,从而降低了相似性搜索的计算复杂度。它在大规模数据处理中有着广泛的应用,如图像搜索、文本相似度搜索等。 LSH 基于随机化的思想,其核心在于哈希函数的设计。哈希函数的设计原则是:如果两个点在高维空间中很接近,那么它们在哈希表中的映射值也应该相近。常用的哈希函数有欧氏距离哈希、Jaccard 相似度哈希、海明距离哈希等。其中,欧氏距离哈希是最普遍的一种。 LSH 的搜索过程主要分为两个步骤:首先,将查询向量通过哈希函数映射成一些桶中,并确定一些候选集;然后,计算候选集中每个桶中的所有向量与查询向量之间的相似度,最终返回相似度最高的向量。虽然 LSH 的搜索结果是近似值,并非精确值,但是它的搜索速度很快,适用于大规模数据处理。 LSH 算法的优点是其可以进行高维度数据相似性搜索,并且不会受到噪声等外部干扰的影响。 它的缺点是搜索结果具有一定的误差,并且哈希函数的设计需要经验和调整。 ### 回答3: 本地敏感哈希(Locality Sensitive Hashing,LSH)是一种用于相似度搜索的技术。它能帮助我们在大规模数据集中高效地找到与给定数据相似的数据。 在传统的哈希表中,散列函数只是简单地将数据映射到哈希表中的一个位置。而在LSH中,我们使用多个哈希函数,并通过一个哈希值的向量来表示数据。具体来说,给定一个数据点,我们可以通过多次哈希得到该数据点的多个哈希值。这些哈希值构成了该数据点的哈希值向量。我们可以将这个哈希值向量看作是该数据点的一个“指纹”。 在相似度搜索中,我们通常通过计算两个数据点的距离来判断它们的相似度。但对于大规模数据集,遍历整个数据集的时间代价是巨大的。在这种情况下,我们可以使用LSH来快速减少需要计算距离的数据点数量。 LSH的核心思想是,通过选择合适的哈希函数来最大限度地减少不相似的数据点产生相同哈希值的可能性,增加相似的数据点产生相同哈希值的可能性。这样,我们在需要查找相似数据时,只需要针对哈希值相同的数据点计算距离,从而减少计算开销。 举个例子,可以使用哈希函数将相似的文本数据映射到相同的桶里。对于文本数据,可以选择将一个文档中各个单词的计数向量作为该文档的哈希值向量,然后选择海明距离(Hamming Distance)作为距离计算方式。当两个文档的向量在海明距离上很接近时,它们就有可能是相似的文档。 总之,LSH是一种高效的相似度搜索技术,它可以减少在大规模数据集中需要遍历的数据数量,从而节省计算开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值