我们在之前的文章中Locality Sensitive Hashing(局部敏感哈希)中已经详细的说了这个算法的基本核心思想,现在我们就来一点一点的把这个算法的每一步都来实现了。

首先我们至少得构建出我们能够比较的样本的特征值,设计出我们的布尔矩阵(Boolean Matrix)。局部敏感哈希的一个优点就是避免两两比较(pairwise comparison),主要的方法就是看最后的band 被映射 同一个bucket的话我们就一般认为这两个特征值其实是相似的,或者说在某个概率下是相同的。

首先我们先构建一个数据集,比如说把它叫做dataSet,这个里面有一些特征向量,我们就用之前我们说的下图这个例子来写我们的代码吧。

我们可以设计我们的dataSet 为一个二维的数组,设计我们需要查询的(或者说找到我们的这个待查询的这个数组为它找到和它相似的数据集)数组为一维数组。我们可以给这个查询的数据叫做query. 我们把这个查询的数组设置为一维数组。

我们可以这么来构建我们的数据结构:

dataSet = [[1,1,0,0,0,1,1],[0,0,1,1,1,0,0],[1,0,0,0,0,1,1]]query = [0,1,1,1,1,0,0]dataSet.append(query)
#把这个查询的数组加入到我们的整个数据集当中,并且将它转换成矩阵的形式
matrix = np.array(dataSet).T

如果要写成代码,我们可以像下面这样操作。把我们的这些要操作的数据集设置为我们的输入参数来做:

def  get_data(dataSet,query):dataSet.append(query)matrix = np.array(dataSet).T

得到我们的数据之后,当然就是生成我们的signature matrix ,这个时候当然就是用到我们的minhash 这个函数,对我们的原始矩阵进行一个行的置换,这个时候找到某列的第一个元素为1 的行号作为我们的signature matrix 的特征值。

我们肯定不会直接把这个矩阵放到内存里面排序进行行置换的操作,这样实在是太占内存了,我们介绍过几种方法,对我们的行号进行置换。依次查询即可。

如果我们按照我们之前章节里面的算法的思路就是对行号进行排序,或者说是置换,这个时候我们来查找置换后的行得到的列中第一次出现1的那个行的行号。

#!/usr/bin/env python
# coding=utf-8from random import shuffle
import numpy as np
import hashlib def generateSig(matrix):"""generate the signature value for the signature matrix param matrix: input matrix """# 在这里我们得到原始矩阵的行号rowSeries= [i for i in range(matrix.shape[0])]#在这里我们设置我们的signature签名矩阵的初始值result = [-1 for i in range(matrix.shape[1])]colcount = 0# 对行号重新排序shuffle(rowSeries)for i in range(len(rowSeries)):rowIndex = rowSeries.index(i)for j in range(matrix.shape[1]):if result[j]==-1 and matrix[rowIndex][j]!=0:result[j]=rowIndex colcount += 1  if colcount == matrix.shape[1]:break return resultdef genSigMatrix(matrix,k):'''generate the signature matrix :param matrix : the input matrix :param k : k =n*r n is the number of bandr is the number of row in each band '''sigMatrix = []for i in range(k):sig = generateSig(matrix)sigMatrix.append(sig)return np.array(sigMatrix)

当然我们还有其他的解决办法,比如我们随机选取一行,而不用对我们的整个行进行重拍我们可以向下面这样做。

这个算法的主要思想就是利用随机行数,抽取一行,然后逐列查询,如果改行的这一列元素刚好是1,那么我们就把对应的签名矩阵的列填上我们抽取的行号,不是1的元素的列继续对行遍历,当然我们会删除之前抽取的行号

import numpy as np
import random
import hashlibdef sigGen(matrix):"""* generate the signature vector:param matrix: a ndarray var:return a signature vector: a list var"""# the row sequence setseqSet = [i for i in range(matrix.shape[0])]# initialize the sig vector as [-1, -1, ..., -1]result = [-1 for i in range(matrix.shape[1])]count = 0while len(seqSet) > 0:# choose a row of matrix randomlyrandomSeq = random.choice(seqSet)for i in range(matrix.shape[1]):if matrix[randomSeq][i] != 0 and result[i] == -1:result[i] = randomSeqcount += 1if count == matrix.shape[1]:breakseqSet.remove(randomSeq)# return a listreturn result

此处代码可以参考这里:
https://github.com/guoziqingbupt/Locality-sensitive-hashing/edit/master/min_hash.py



通过这一步之后我们得到了我们的signature matrix ,这个时候我们要计算这些signature 是不是能够被映射到同一个bucket 里面。

我们需要把我们的matrix 划分成不同的bands , 每一个band 里面包含有r 行。然后映射到不同的buckets 里面,经过我们的分析,我们知道如果两个签名是相似的,那么他们会被映射到同一个buckets 里面。这个时候我们LSH避免了两两比较,这个时候LSH极大的提高了运算的效率。


def minHash(input_matrix, b, r):"""map the sim vector into same hash bucket:param input_matrix::param b: the number of bands:param r: the row number of a band:return the hash bucket: a dictionary, key is hash value, value is column number"""hashBuckets = {}# permute the matrix for n timesn = b * r# generate the sig matrixsigMatrix = sigMatrixGen(input_matrix, n)# begin and end of band rowbegin, end = 0, r# count the number of band levelcount = 0while end <= sigMatrix.shape[0]:count += 1# traverse the column of sig matrixfor colNum in range(sigMatrix.shape[1]):# generate the hash object, we used md5hashObj = hashlib.md5()# calculate the hash valueband = str(sigMatrix[begin: begin + r, colNum]) + str(count)hashObj.update(band.encode())# use hash value as bucket tagtag = hashObj.hexdigest()# update the dictionaryif tag not in hashBuckets:hashBuckets[tag] = [colNum]elif colNum not in hashBuckets[tag]:hashBuckets[tag].append(colNum)begin += rend += r# return a dictionaryreturn hashBuckets

这里我们有一个技巧,我们可以把我们的桶设置为一般的hash 函数,比如说md5,sha256 等等。

这个时候我们记录列号,我们把hash 值作为我们字典的键,把列号作为值来计算。
一个字典里面如果,一个键对应的元素是大于两个的,我们则认为找到了相似的样本。

感觉CSDN在写到一定的长度就



局部敏感哈希(Locality sensitive hash) [3]—— 代码篇相关推荐

  1. 局部敏感哈希-Locality Sensitive Hashing

    局部敏感哈希 转载请注明http://blog.csdn.net/stdcoutzyx/article/details/44456679  在检索技术中,索引一直需要研究的核心技术.当下,索引技术主要 ...

  2. 局部敏感哈希Locality Sensitive Hashing归总

    最近发邮件讨论Semantic Hashing的同学和同事很多,推荐李老师的文献列表供大家参阅:http://cs.nju.edu.cn/lwj/L2H.html 说到Hash,大家都很熟悉,是一种典 ...

  3. 局部敏感哈希算法(Locality Sensitive Hashing)

    from:https://www.cnblogs.com/maybe2030/p/4953039.html 阅读目录 1. 基本思想 2. 局部敏感哈希LSH 3. 文档相似度计算 局部敏感哈希(Lo ...

  4. R语言实现︱局部敏感哈希算法(LSH)解决文本机械相似性的问题(一,基本原理)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 私认为,文本的相似性可以分为两类:一类是机械相 ...

  5. 局部敏感哈希(Locality Sensitive Hashing)二三问[2]

    #写在前面的话 今天的这一章有几个目的,一是回答一下各位网友在各大博客上提出的问题,然后其他博主没有回答的问题.二是纠正一些别人在写局部敏感哈希时候出现的错误.就是这么贴心有没有. #假装自己是正文的 ...

  6. 最近邻和K近邻及其优化算法LSH(局部敏感哈希,Locality Sensitive Hashing) Kd-Tree

    引言 在处理大量高维数据时,如何快速地找到最相似的数据是一个比较难的问题.如果是低维的小量数据,线性查找(Linear Search)就可以解决,但面对海量的高维数据集如果采用线性查找将会非常耗时.因 ...

  7. 在茫茫人海中发现相似的你——局部敏感哈希(LSH)

    一.引入 在做微博文本挖掘的时候,会发现很多微博是高度相似的,因为大量的微博都是转发其他人的微博,并且没有添加评论,导致很多数据是重复或者高度相似的.这给我们进行数据处理带来很大的困扰,我们得想办法把 ...

  8. mysql 查找相似数据_局部敏感哈希LSH(Locality-Sensitive Hashing)——海量数据相似性查找技术...

    一. 前言 最近在工作中需要对海量数据进行相似性查找,即对微博全量用户进行关注相似度计算,计算得到每个用户关注相似度最高的TOP-N个用户,首先想到的是利用简单的协同过滤,先定义相似性度量(cos,P ...

  9. LSH系列1:局部敏感哈希(LSH)——基本原理介绍

    文章目录 参考 局部敏感哈希(LSH)基本原理介绍 背景 LSH 的基本思想 LSH 的哈希函数族(Hash Family) LSH 的查找过程 LSH 常见的 Hash Function 参考 LS ...

最新文章

  1. SAP QM创建一个包含Multiple Specification的检验计划
  2. HPUX在oracle10g安装和卸载缩写
  3. mega_[MEGA DEAL]带有Kotlin捆绑包的完整Android Oreo(95%折扣)
  4. ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(二)
  5. linux cp 强制yes,linux cp实现强制覆盖
  6. mac地址漂移flapping的前因后果
  7. php如何输出关联数组的值,php - 如何从PHP关联数组中获取确切的输出 - SO中文参考 - www.soinside.com...
  8. 大数据之-Hadoop3.x_Yarn_基础架构---大数据之hadoop3.x工作笔记0141
  9. 对$()与``区别的理解
  10. 平凡的故事:年轻开发者的那些伤心事
  11. Enterprise Library v5.0 -- Data Access Application Block 开发向导(2)
  12. springboot +vue实现打印PDF(实现批量打印快递单)
  13. git commit 参数详解 --amend
  14. 实时换脸技术——直播,视频通话|脸部交换程序
  15. react 返回一个页面_react项目中实现返回不刷新
  16. 如何让IE窗口打开时就自动默认为最大化
  17. 信源编码课程实验一:基于Audacity的浊音、清音和爆破音信号的时域及频域特性分析
  18. Nature子刊:AI技术从零开始设计具有生物活性的蛋白质
  19. matlab 旋转曲面,在matlab中实现旋转曲面的动画设计
  20. Linux强制使用短密码|修改短密码|passwd无效的密码

热门文章

  1. 农行数据中台建设与应用实践
  2. 美团高级技术专家:DDD 在旅游电商架构演进中的实践
  3. 扒一扒 JVM 的垃圾回收机制,拿大厂offer少不了它!
  4. 阿里、百度、腾讯都选择 Flink,它到底有什么魔力?
  5. 共享思维导图leangoo,可以导入XMind文件了
  6. ROS~kinectv1~边缘检测
  7. ubuntu——python
  8. 先进先出置换算法(FIFO)
  9. 网络负载均衡相关技术-七层负载
  10. HTML的标签描述12