zoukankan      html  css  js  c++  java
  • 由浅入深弄懂simhash来比较文本的相似度

    背景

      彻底搞懂simhash原理,及如何进行文本相似度的比较。

    simhash原理

      概括的说即是:将文本向量化后,进行向量间的距离计算,卡某个阈值来判定两个文本是否相似。

      涉及关键点

    1. 文本向量化操作
      1. 切词,并赋权重值
      2. bin(hash(切词)).zfill(64); 转成定长01向量
      3. 向量乘权重;遇到1的乘正权重,遇到0乘负权重
      4. 全部向量对应维度上进行加和
      5. 降维:大于0的变成1,小于0的变成0,产出文本的向量
    2. 海明距离计算
      1. 异或时,只有在两个比较的位不同时其结果是1 ,否则结果为0
      2. 两个向量“异或”后得到1的个数即为海明距离的大小

    举个例子

    需要安装的包

    1. jieba分词包:https://pypi.org/project/jieba/
      1. 选择半自动安装:下载最新tar包,本地解压后,python setup.py install
    2. numpy包:pip install numpy

    详细代码如下:

    # -*- coding: utf-8 -*-
    
    import jieba.analyse
    import jieba
    import json
    import numpy as np
    
    class SimHash(object):
    
        # 文本使用simhash方法,转成64维向量
        def content_vector(self, contents):
            # 获取关键词及其tf-idf权重值
            # 分词 hash 加权
            keywords = jieba.analyse.extract_tags(contents, withWeight=True)
            ret_list = []
            for word, weight in keywords:
                # hash
                word_hash = bin(hash(word)).replace('0b', '').replace('-', '').zfill(64)
                weight = int(weight * 10)
                tmp_list = []
                for feature in word_hash:
                    if feature == '1':
                        # 加权
                        tmp_list.append(weight)
                    else:
                        tmp_list.append(-1 * weight)
                ret_list.append(tmp_list)
            
            # 降维
            sum_list = np.sum(np.array(ret_list), axis=0)
            res_str = ''
            for i in sum_list:
                if i > 0:
                    res_str += '1'
                else:
                    res_str += '0'
            return res_str
    
        # 计算两个向量的海明距离
        def cal_hamming_distance(self, vector1, vector2):
            vec1_int = int(('0b'+ vector1), 2)
            vec2_int = int(('0b' +vector2), 2)
            # 异或操作
            num = vec1_int ^ vec2_int
            # 获取num中1的个数,即为海明距离
            count = 0
            for i in bin(num).replace('0b', ''):
                if i == '1':
                    count += 1
            return count
  • 相关阅读:
    equals方法
    StringBudilde
    日期
    system
    File类
    calender
    stringbuilder tostring
    File的三种构造方法
    Java入门——day52
    Java入门——day53
  • 原文地址:https://www.cnblogs.com/syw-home/p/12332413.html
Copyright © 2011-2022 走看看