• 数据清洗:相似重复记录检测算法SNM及其Python实现


    1. 相似重复记录删除

      相似重复记录是指数据库中存在这样的两条记录 R 1 R_{1} R1 R 2 R_{2} R2,他们的内容相同或者相似,且都对应着同一个现实实体,则记录对 < R 1 , R 2 > <R1,R2>互为相似重复记录。实际数据库中可能存在多对互为相似重复的记录,它们的存在降低了数据的质量,可能会妨碍系统的正常运行,甚至会影响企业信息管理系统决策的正确性。

      之所以会存在重复记录,是因为在进行数据获取或数据存储的过程中,相同数据产生了不同的表现形式,比如:同一个单词的拼写错误、印刷错误、字符格式不统一、字符缺失等。

    2. SNM(近邻排序算法)

      SNM算法的设计思路如下:

    • 首先,根据所在领域的专家知识经验,指定数据集排序时所使用的关键字的生成方式;
    • 其次,遍历数据集,对每一条记录生成的排序非关键字,然后按照记录的排序关键字对记录进行排序,根据相似记录对应的关键字内容也相似的原理,不同的重复记录在排序完成后理论上会处于邻近的位置;
    • 重复记录检测及合并: 为数据集设定一个大小可以滑动的窗口。将最后一个滑入窗口的记录数据与窗口内的其他记录数据进行比较,判定两条记录是否完全相同。如果相同则将两条记录判定为相似重复记录,并将这两条记录进行合并;如果不同,就将窗口向后滑动。滑动窗口内的记录是采用先进先出的方式进行组织,比较后的数据则滑向下一条记录的位置,再进行新的检测。

    3. Python实现

      本实验采用的数据是由第三方的数据生成器“febrl"生成的,”febrl"生成的数据的来源是澳大利亚某卫生部门的数据库。

    import pandas as pd
    import numpy as np
    
    data=pd.read_csv(r'C:/Users/sunta/Downloads/febrl-master/data/dedup-dsgen/dataset_A_10000.csv')
    
    def edit_distance_similarity(word1,word2):
        len1,len2=len(word1),len(word2)
        dp=np.zeros((len1+1,len2+1))
        dp[0]=range(len2+1)
        dp[:,0]=range(len1+1)
        
        for i in range(1,len1+1):
            for j in range(1,len2+1):
                delta=0 if word1[i-1]==word2[j-1] else 1
                dp[i,j]=min(dp[i-1,j-1]+delta,dp[i-1,j]+1,dp[i,j-1]+1)
            
        similarity=1-dp[len1,len2]/max(len1,len2)
        return similarity
    
    def detect_similarity(col1,col2):    
        similarity=[edit_distance_similarity(str(col1[idx]),str(col2[idx])) for idx in col1.index]
        return sum(similarity)/len(similarity)
        
    #排序
    data_sorted=data.sort_values(by='soc_sec_id')
    threshold=4 #窗口大小
    label=[]
    for i in range(data_sorted.shape[0]):
        start=0 if i<threshold else i-threshold+1
        end=i+1
        tmp=data_sorted.iloc[start:end,:]
        if tmp.shape[0]==1:
            label.append(1)
        else:
            tmp_old=tmp.iloc[:-1,:]
            tmp_new=tmp.iloc[-1,:]
            tmp_old=tmp_old.apply(detect_similarity,axis=1,args=(tmp_new,))
            label.append(1 if tmp_old.max()>0.9 else 0)   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    参考文献

    1. 《面向重复记录检测的数据清洗算法的研究》
    2. 《相似重复记录的数据清洗技术的研究_王开祥》
  • 相关阅读:
    R语言入门看这一章就够了(上)
    Spring源码分析refresh()第一篇
    Latex论文写作小技巧记录,不断更新
    DispatcherSynchronizationContext and Dispatcher
    如何在3DMax中使用超过16个材质ID通道?
    测试工程师如何帮助开发域的质量变好
    爬虫学习——第一章 初识爬虫
    fork主仓库后拉取主仓库的最新代码,拉取后更新fork的仓库
    学生信息系统(python实现)
    【PAT甲级 - C++题解】1072 Gas Station
  • 原文地址:https://blog.csdn.net/yeshang_lady/article/details/126350183