`

比较两个地址相似程度

阅读更多
需求:比较两个地址相似程度

1, 排除数字, 排除字母(大小写), 特殊符号

如以下三个地址都可以认为是实际相同,只是表述不同:
湖北省-武汉市-东西湖区 湖北省武汉市东西湖区革新大道四明路物流园c5
湖北省-武汉市-东西湖区 革新大道四明路物流园c5门
湖北省-武汉市-东西湖区 革新大道四明路南特1号

实际上,这些地址,前两个是相同的, 第三个是不同的

思路:
1, 格式化地址, 重复的去掉
2, 去掉数字, 排除字母(大小写), 特殊符号
3, 选取算法

目前能处理的字符串相同的算法很多,常见的:

1)SimHash:算法的主要思想是降维,将高维的特征向量映射成一个f-bit的指纹(fingerprint),通过比较两篇文章的f-bit指纹的Hamming Distance来确定文章是否重复或者高度近似。由于每篇文章我们都可以事先计算好Hamming Distance来保存,到时候直接通过Hamming Distance来计算,所以速度非常快适合大数据计算,google用的就是这个。但是SimHash对于短文本误判率比较高,因此建议大于500字以上的使用此算法。

2)汉明距离: 以理查德·卫斯里·汉明的名字命名的。在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。例如:
1011101 与 1001001 之间的汉明距离是 2。
2143896 与 2233796 之间的汉明距离是 3。
"toned" 与 "roses" 之间的汉明距离是 3。

3)Levenshtein 距离:  又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。
许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
编辑距离的算法是首先由俄国科学家Levenshtein提出的,故又叫Levenshtein Distance。
java中也有实现的工具类:org.apache.commons.lang.StringUtils.getLevenshteinDistance(str1, str2);
可用于:DNA分析,拼字检查,语音辨识,抄袭侦测

4)余弦定理:通过对两个文本分词,TF-IDF算法向量化,对比两者的余弦夹角,夹角越小相似度越高,但由于有可能一个文章的特征向量词特别多导致整个向量维度很高,使得计算的代价太大不适合大数据量的计算。

经过一番测试后, 选择余弦定理
具体实例入下:
未采用分词
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class CosineSimilarAlgorithm {
    public static double getSimilarity(String content1, String content2) {
            Map<Integer, int[]> wordMap = new HashMap<Integer, int[]>();
             
            // 将两个字符串中的中文字符以及出现的总数封装到,AlgorithmMap中
            char[] char1 = content1.toCharArray();
            for (int i = 0; i < char1.length; i++) {
                if(isHanZi(char1[i])){
                    int charIndex = getGB2312Id(char1[i]);
                    if(charIndex != -1){
                        int[] fq = wordMap.get(charIndex);
                        if(fq != null && fq.length == 2){
                            fq[0]++;
                        }else {
                            fq = new int[2];
                            fq[0] = 1;
                            fq[1] = 0;
                            wordMap.put(charIndex, fq);
                        }
                    }
                }
            }
 
            char[] char2 = content2.toCharArray();
            for (int i = 0; i < char2.length; i++) {
                if(isHanZi(char2[i])){
                    int charIndex = getGB2312Id(char2[i]);
                    if(charIndex != -1){
                        int[] fq = wordMap.get(charIndex);
                        if(fq != null && fq.length == 2){
                            fq[1]++;
                        }else {
                            fq = new int[2];
                            fq[0] = 0;
                            fq[1] = 1;
                            wordMap.put(charIndex, fq);
                        }
                    }
                }
            }
             
            Iterator<Integer> iterator = wordMap.keySet().iterator();
            double sqdoc1 = 0;
            double sqdoc2 = 0;
            double denominator = 0; 
            while(iterator.hasNext()){
                int[] c = wordMap.get(iterator.next());
                denominator += c[0]*c[1];
                sqdoc1 += c[0]*c[0];
                sqdoc2 += c[1]*c[1];
            }
            return denominator / Math.sqrt(sqdoc1*sqdoc2);
    }
 
    public static boolean isHanZi(char ch) {
        // 判断是否汉字
        return (ch >= 0x4E00 && ch <= 0x9FA5);
 
    }
 
    /**
     * 根据输入的Unicode字符,获取它的GB2312编码或者ascii编码,
     * 
     * @param ch 输入的GB2312中文字符或者ASCII字符(128个)
     * @return ch在GB2312中的位置,-1表示该字符不认识
     */
    public static short getGB2312Id(char ch) {
        try {
            byte[] buffer = Character.toString(ch).getBytes("GB2312");
            if (buffer.length != 2) {
                // 正常情况下buffer应该是两个字节,否则说明ch不属于GB2312编码,故返回'?',此时说明不认识该字符
                return -1;
            }
            int b0 = (int) (buffer[0] & 0x0FF) - 161; // 编码从A1开始,因此减去0xA1=161
            int b1 = (int) (buffer[1] & 0x0FF) - 161; // 第一个字符和最后一个字符没有汉字,因此每个区只收16*6-2=94个汉字
            return (short) (b0 * 94 + b1);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return -1;
    }

    public static void main(String[] args) {        
        String address1 = "湖北省-武汉市-东西湖区 革新大道四明路物流园c5门";
        String address2 = "湖北省-武汉市-东西湖区 革新大道四明路南特1号";
        System.out.println(getSimilarity(address1, address2));
    }
}


方案一:
1, 规整地址后(去掉重复省市, 特殊符号,数字,字母)
2, 结合上面的代码

方案二:
1, 规整地址后(去掉重复省市, 特殊符号,数字,字母)
2, 结合上面的代码(加入分词概念), 地址词库的完整直接关系到判断的准确性.

对比方案一和方案二选取最优的一个.

看官若有好的建议,欢迎拍砖
分享到:
评论

相关推荐

    判断相似程度

    6. **比较熵值**:对两幅图像的投影熵进行比较,如果两个熵值接近,那么这两幅图像在所投影的方向上具有相似的复杂性,从而在一定程度上表示它们在整体上是相似的。 7. **综合判断**:为了全面评估图像的相似性,...

    C#比较图片相似度,两张图片有多少相似

    在数字图像处理中,相似度通常通过计算两个图像之间的距离或相关性来衡量。这涉及到像素级别的比较、特征检测以及可能的图像预处理步骤。以下是一些常用的方法: 1. **像素级比较**:最基础的方法是直接比较两张...

    numpy 计算两个数组重复程度的方法

    最近有个需求,是做两个数组重复程度计算,麻烦就麻烦在单个数组的元素有可能重复,处理思路如下: 1. 找到重复元素 2. 元素个数统计,利用np.bincount转换,即元素个数统计到元素转化的索引 3. 统计相同元素匹配个...

    比较两个文件是否雷同

    具体来说,它需要创建两个文本文件,并输入一些单词,之后判断这两个文件的内容相似程度。如果相同单词的数量占所有单词总数的80%,则认为这两个文件是雷同的。 #### 二、需求分析 - **创建文件**:程序需要具备...

    使用 OpenCV 和 Python 检测两个图像的相似程度(SIFT算法,包括代码和数据)

    在图像处理领域,比较两幅图像的相似程度是一项常见的任务,尤其在计算机视觉、图像识别和内容检索等应用中。本教程将详细讲解如何利用OpenCV库和Python编程语言实现SIFT(Scale-Invariant Feature Transform,尺度...

    基因序列对比

    类基因由4种核苷酸 分别用字母ACTG表示 要求编写一个程序 按以下规划比较两个基因序列并确定它们的相似程度 即两 给出两个基因序列AGTGATG和GTTAG 它们有多相似呢 测量两个基因的相似度一种方法称为对齐 使用对齐...

    实施八个评估指标来访问两个图像之间的相似性。这八个指标如下:RMSE、PSNR、SSIM、ISSM、FSIM、SRE、SAM

    实施八个评估指标来访问两个图像之间的相似性。这八个指标如下:RMSE、PSNR、SSIM、ISSM、FSIM、SRE、SAM 和 UIQ。 图像相似度测量 实施八个评估指标来访问两个图像之间的相似性。八项指标如下: 均方根误差 (RMSE...

    矢量图图形相似性比较

    1.对于任意两个图形的相似程度必须得出一个量化的结果,在此称为图形相似度。 2.对图形形状的检测必须忽略 大小、旋转、轴对称、连线顺序的影响。 3.对于相同的图形,形状相似度必须为1;对于不相同的图形,形状...

    2019秋九年级数学上册第四章图形的相似4探索三角形相似的条件第2课时两边成比例且夹角相等的两个三角形相似学案2无答案新版北师大

    首先,我们需要理解相似三角形的基本定义:两个三角形如果对应角相等且对应边成比例,那么这两个三角形就相似。相似三角形的形状是相同的,但大小可以不同。这个定义为我们提供了判断三角形是否相似的基础。 学习...

    2019秋九年级数学上册第四章图形的相似4探索三角形相似的条件第1课时两角分别相等的两个三角形相似学案1无答案新版北师大版201

    换句话说,如果两个三角形的三个角分别对应相等,那么这两个三角形就是相似的。用符号表示为:ΔABC ∼ ΔA'B'C'。 2. **三角形相似的判定方法**: - **两角法**(本课时重点):如果两个三角形有两对角分别相等,...

    据结构课程设计实验报告之源程序的相似性.docx

    如果两个程序的关键字频度向量之间的相似度达到一定程度,就可以认为这两个程序在结构上是相似的。 总的来说,这个数据结构课程设计项目提供了一种高效的方法来比较Java源代码的相似性,通过对关键字的频度进行统计...

    2021-2022年收藏的精品资料使用哈希表技术判别两个源程序的相似性.doc

    最后,通过编写多个具有不同相似程度的C程序进行测试,可以验证这种方法的有效性和局限性。在发现S值非常小的情况时,应结合人工审查以确定源程序的真正相似性。此外,为了提高判断的准确性,还可以考虑引入其他因素...

    2016秋九年级数学上册23.3利用两角判定两个三角形相似第2课时习题课件新版华东师大版.ppt

    例如,如果知道两个相似三角形的其中一个边长的比例,我们可以推算出其他边长的比例,进而求解未知边长。相似三角形的性质还可以用于解决实际生活中的问题,如测量建筑物的高度、地图比例尺的应用等。 在“第2课时...

    两种云相似性判断代码

    在云模型中,我们可以将每个云看作是高维空间中的一个点,计算两点之间的距离来衡量它们的相似程度。距离越小,相似性越高。其中,欧几里得距离是最常见的,它是两点间直线距离,计算公式为两向量各维度差的平方和的...

    人类基因相似度对比ACTG

    要求编写一个程序,按以下规划比较两个基因序列并确定它们的相似程度。即两给出两个基因序列AGTGATG和GTTAG,它们有多相似呢?测量两个基因的相似度一种方法称为对齐。使用对齐方法可以在基因的适当位置加入空格,让...

    易语言取相似颜色

    2. **取差异度**:差异度是衡量两个颜色之间差异的程度,通常用某种色差公式来计算,如CIEDE2000,它可以提供一个量化指标来判断颜色之间的接近程度。 3. **取近似颜色索引**:在有限的颜色表中,找到与目标颜色最...

    使用直方图比较检索相似图像

    `compareHist`函数是OpenCV中用于比较两个直方图的工具,它可以计算两个直方图之间的相似度。该函数支持多种比较方法,如Correlation(相关性)、Intersection(交集)、Chi-Square(卡方)、Kullback-Leibler ...

    两个字符串相似度匹配

    字符串相似度匹配旨在量化两个字符串之间的相似程度,通常以百分比的形式表示。它考虑了字符的顺序、重复以及缺失等因素,旨在找出字符串间的共同部分,从而评估它们的相似性。描述中提到的“好像不是很准确”,可能...

    数学九年级上浙教版4.3两个三角形相似的条件同步练习4精选.doc

    由于正方形的四边相等,角都是90度,所以当CM=1时,根据两边对应成比例的条件,可以推断出这两个三角形相似。 二、选择题解析 1. 选择题(1)中,选项C不能判定两三角形相似,因为只有两边对应成比例,并不能确定...

Global site tag (gtag.js) - Google Analytics