模糊去重实战:算法原理、数据清洗与备份去重配置指南
2026/9/10 4:10:22 网站建设 项目流程

你可能遇到过这种情况:两份客户名单,看起来都是同一家公司,但一份写着“深圳市腾讯计算机系统有限公司”,另一份写着“深圳腾讯计算机系统有限公司”,用传统的精确去重去比较,程序会把它们当成两条完全不同的记录。这就是这篇博文要聊的题目——Fuzzy去重,也就是模糊去重。

我最早接触“Fuzzy去重”不是从教科书里学到的,而是一次真实的数据清洗事故。当时要把三个渠道收集的客户信息合并进主数据库,我以为用 group by 或者 distinct 就能搞定,结果一跑发现重复率不到预期,反而多出来几千条“看起来很相似但程序认为不一样”的记录。后面才意识到,真实世界的数据从来不是干净、全等的,精确匹配只是在理想世界成立。模糊去重解决的就是这个问题:在数据存在噪音、格式不统一、轻微错漏的情况下,判定两条记录是否代表同一个实体。

这篇文章我会从算法原理讲到实际落地,覆盖数组去重、对象数组去重、SQL 查询去重、图片去重,还有我踩过的备份存储去重配置坑。不管你是做数据清洗、后端开发,还是做运维备份,都能找到可以直接抄走的方案。

1. 为什么需要Fuzzy去重:精确匹配解决不了的真问题

1.1 数组去重和SQL去重:看似够用,其实很脆弱

程序员最熟悉的去重大概就是数组去重。const arr = [1, 2, 2, 3]; const unique = [...new Set(arr)];一行搞定,速度快、写法优雅。SQL 里的SELECT DISTINCTGROUP BY也是同理,本质上都在做一件事:只有当两个值完全相等的时候才判断为重复。

这个逻辑在数字和 ID 上没有问题,但只要数据进入“人可读”的文本世界,精确匹配就开始翻车。我来列举几个我实际遇到过的例子:

  • 手机号在导入时被 Excel 自动加了空格,13800138000138 0013 8000被识别成两个号码。
  • 地址字段有的是“北京市朝阳区”,有的是“北京朝阳区”,行政区划的层级描述不一致。
  • 姓名里出现别名,比如“张伟”和“张伟(先生)”,一个括号就导致去重失败。
  • 用户在表单里填写“腾讯”和“深圳市腾讯计算机系统有限公司”,同一个实体出现两种粒度。

这些场景共同点在于:字段里包含了同一个实体的信息,但因为没有精确相等,传统去重方法就把它们放过了。对象数组去重也是一样,很多人会按id或者name做 key,但一旦不同来源的数据没有同一个主键,按 key 去重就直接失效了。

1.2 哪些场景必须上模糊去重

不是所有去重都需要模糊匹配。如果你处理的是订单流水、用户 ID、日志编号这种强约束字段,精确去重就够了,用模糊反而会误伤。真正必须上模糊去重的场景,通常具备几个特征:数据来源复杂、字段由人手工输入或经过 OCR 识别、同一个实体没有统一标识。

我按高频程度列一下:

  • 多渠道客户数据清洗。CRM、财务系统、第三方平台导出名单,三份数据合并时,同一个人或同一家公司往往没有统一编号。
  • 日志和报错聚合。线上服务报错,Error message 里夹着时间戳、内存地址、UUID,同一个 bug 每次打印的日志都“几乎一样但又不完全一样”,精确去重会把一个故障拆成几百条。
  • OCR 与图片识别的结果处理。扫描件转文字后,识别错误率通常不低,“深圳”可能被识别成“深珊”,图片文件本身也可能存在分辨率差异、水印、裁剪等变化。
  • 结构化文本库去重。比如商品标题,同一款商品不同卖家写的标题可能差异巨大,但核心信息(品牌、型号、规格)是重叠的。
  • 新闻资讯与爬虫数据合并。同一条新闻源被不同站点转载,标题往往被修改,正文也有段落调整,需要按内容相似度判断。

这类需求的共同点,不是“两条数据是否完全一样”,而是“两条数据是否在表达同一个事物”。这就是模糊去重存在的意义。

1.3 Fuzzy去重的本质:把“全等判断”升级为“相似度判断”

模糊去重的核心思路其实很简单,可以拆成三步:把对象抽象成可比较的表示;用相似度算法量化两条记录的相似程度;设定阈值和匹配策略,决定什么程度算是重复。

用生活类比来解释,精确去重像是在问“你身份证号是多少”,只要号码不一致就不是同一个人;模糊去重像是在问“你是不是同一个人”,它会看你的五官轮廓、身高体重、说话方式,综合判断,允许一定范围内存在差异。做模糊去重的人,本质上就是在设计一套“看起来像不像”的评判标准。

实际操作中,模糊去重有两条路线:一条是局部匹配,比如判断 A 是否近似包含在 B 里;另一条是整体相似度,衡量两条记录的整体一致程度。选哪条、用什么算法、阈值定多少,都得根据数据特征来。这部分是模糊去重的技术核心,下一章详细展开。

2. 核心算法拆解:相似度从哪来

2.1 编辑距离与字符级相似度

最常见的模糊匹配算法就是编辑距离(Edit Distance),尤其是 Levenshtein 距离。它计算的是把一个字符串变成另一个字符串最少需要多少次单字符插入、删除、替换。

比如把kitten变成sitting,需要把 k 改成 s,把 e 改成 i,最后加一个 g,一共 3 次操作,所以 Levenshtein 距离是 3。它的直观含义很好理解,代码也不难写,但直接使用距离值有一个问题:长度不同的字符串,绝对值没有可比性。比如两个长度 100 的字符串差 2 个字符,和两个长度 5 的字符串差 2 个字符,后者明显差异更大。

所以工程上一般会做归一化,把距离转成相似度,常见公式是similarity = 1 - distance / max(len1, len2)。这样两边长度都接近 100、差 2 个字符时相似度约为 0.98,两边长度 5、差 2 个字符时相似度只有 0.6,更符合人的直觉。

比 Levenshtein 更进一步的是 Damerau-Levenshtein 算法,它在增删改之外还允许相邻字符的转置。手写输入场景里“teh”和“the”这种错误特别常见,用带转置的算法能更好处理。字符级编辑距离适合短文本,比如姓名、电话、地址简写,我实际测试下来在中文短字段上效果不错,但长文本上性能会迅速恶化,因为动态规划的时间复杂度是 O(m×n)。

2.2 集合相似度与N-gram

处理中长文本时,字符级编辑距离计算量太大,集合相似度是更实用的方向。最经典的是 Jaccard 相似度,公式是交集大小除以并集大小,把两条文本分别拆成集合,集合重叠越多,相似度越高。

但直接按整句或者单词拆集合,对中文并不友好。中文没有天然的空格分词,所以实践中我用得最多的是 N-gram,尤其是二元语法(bigram)。把“模糊去重”拆成 2-gram,就是“模糊”“糊去”“去重”;把“模糊查重”拆成 2-gram,就是“模糊”“糊查”“查重”。两者有一个公共gram,但整体重叠率不高,Jaccard 值会明显小于全等文本,这个差异恰好反映了语义差异。

N-gram 的粒度选择是个经验活。2-gram 对中文字符级别的顺序变化非常敏感,适合处理错别字少的场景;3-gram 抗噪能力强一些,但对短字段会过于宽松。实践里我会对同一批数据分别计算 2-gram 和 3-gram 的 Jaccard,再结合编辑距离做综合打分。

在更复杂的场景中,可以用 TF-IDF 把文本转成向量,再用余弦相似度比较。这种方式相当于给每个词加了权重,常见词权重低,特征词权重高。比如“公司”这种词在几乎所有企业名里都出现,权重很低;“腾讯”这种词权重很高,两个文本都含“腾讯”时相似度提升明显。这个思路适合标题查重、资讯去重这类长文本场景。

2.3 海量数据下的SimHash与MinHash

两层两两比较的时间复杂度是 O(n²),当数据量到几万条以上时就不太现实了。比如 18 万条地址数据,两两比较要计算约 16 亿次相似度,Python 单线程跑要几十天,完全没法上线。这时候需要能快速缩小候选集的方法。

SimHash 是 Google 用来做网页去重的经典方案。思路是把文档映射成一个 64 位指纹,两个文档的海明距离越小,相似度越高。SimHash 的巧妙之处在于,它把“局部修改不影响整体概要”做了数学化表达,一段文本改几个字,得到的指纹只会在少量位上变化。实际使用中,我一般用海明距离小于等于 3 作为判定阈值,效果比较稳定。

MinHash 和 LSH(局部敏感哈希)则是另一类做法。MinHash 用多个哈希函数对集合做签名,同一个集合无论怎么打乱元素顺序,签名都基本一致,适合 Jaccard 相似度的大规模近似计算。配合 LSH 可以把“可能相似的候选对”分到同一个桶里,只在桶内做精确两两比较,能把计算量降低一到两个数量级。

这套方案前期实现成本不低,但如果你处理的是百万级以上的文本数据,这笔投入非常值得。我的建议是:数据量小于 1 万,直接两层循环加编辑距离就行;1 万到 20 万,用 N-gram 倒排索引先过滤候选集;超过 20 万,再考虑 SimHash 或 MinHash。

2.4 相似度阈值:这个参数比算法还关键

很多新手做模糊去重时,总觉得算法越高深越好,实际上真正决定准确率的是阈值。我见过太多次误判,都源于“阈值拍脑门”定了 0.8 或 0.9。

阈值并不是一个通用常量。姓名去重的场景里,两个字的名字“王涛”和“王涛(先生)”,相似度可能不到 0.8,但确实是同一个人;而长篇新闻正文哪怕只改了几个句子,相似度可能还是高达 0.95。因此阈值必须结合数据长度和业务语义去定。

我常用的定阈值方法是抽样标注法:从数据里随机抽 300 到 500 条,人工标注哪些该合并,哪些不该合并,然后把这批数据跑一遍相似度计算,画出相似度的概率分布图。你会发现通常存在一个“灰色地带”,比如相似度 0.7 以下绝大多数该分开,0.9 以上绝大多数该合并,中间区域则是人肉审核区。最终我会设置双阈值:高阈值自动合并,中间段落入人工审核队列,低阈值直接忽略。这套流程虽然前期费点功夫,但能省掉后面海量的人工校对时间。

3. 四种落地姿势:数组、对象数组、SQL、图片

3.1 数组文本模糊去重:RapidFuzz快速实现

先从一个最常见的需求说起:一个字符串数组里有不少内容近似重复的文本,需要把相似度高于阈值的条目视为同一条。Python 生态里最顺手的是 RapidFuzz,它是老牌库 fuzzywuzzy 的 C++ 重写版,速度快、内存占用低,接口也基本兼容。

我写了一个简单的数组文本去重代码,思路是两层循环计算相似度,高于阈值就把后者标记为重复并挂到前者下面:

from rapidfuzz import fuzz texts = [ "深圳市腾讯计算机系统有限公司", "深圳腾讯计算机系统有限公司", "腾讯科技(深圳)有限公司", "北京市朝阳区建国路93号", "北京朝阳区建国路93号", ] threshold = 80 merged = {} used = [False] * len(texts) for i in range(len(texts)): if used[i]: continue merged[texts[i]] = [] for j in range(i + 1, len(texts)): if used[j]: continue ratio = fuzz.ratio(texts[i], texts[j]) if ratio >= threshold: merged[texts[i]].append(texts[j]) used[j] = True for key, dup_list in merged.items(): if dup_list: print(key, "->", dup_list)

这段代码本身不难,但有几个优化点需要说明。第一,fuzz.ratio是全字符串相似度,适合比较结构完整的文本;如果你的数据是“长文本里包含关键信息”,建议换fuzz.partial_ratiofuzz.token_sort_ratio。第二,阈值设成 80 还是 90 差别很大,建议先用样本数据观察分布再定。第三,两层循环在数据量大的时候非常慢,可以先按“首字”或者“长度区间”分桶,只在桶内做比较。

3.2 对象数组去重:多字段加权聚类合并

真实业务里数据通常是一条条对象,比如:

[ {"name": "深圳市腾讯计算机系统有限公司", "address": "深圳市南山区海天二路33号", "phone": "0755-86013388"}, {"name": "深圳腾讯计算机系统有限公司", "address": "深圳南山区海天二路33号", "phone": "0755-86013388"} ]

如果只看 name 字段,上面两条很像;只看 phone 字段则完全相同。对象数组去重的关键是从多个字段综合判断,而不是拿单一字段硬碰。

我的做法是给每个字段分配权重。比如 name 权重 0.5,address 权重 0.3,phone 权重 0.2,最后综合得分 = 0.5×name相似度 + 0.3×address相似度 + 0.2×phone相似度。实现时可以把每个字段的相似度计算封装成单独函数,方便以后调整权重:

from rapidfuzz import fuzz def record_similarity(a, b): name_score = fuzz.ratio(a["name"], b["name"]) / 100.0 addr_score = fuzz.ratio(a["address"], b["address"]) / 100.0 phone_score = fuzz.ratio(str(a["phone"]), str(b["phone"])) / 100.0 return 0.5 * name_score + 0.3 * addr_score + 0.2 * phone_score

阈值同样不是拍脑袋定。我习惯先把所有候选对的综合得分算出来,观察分布,再定合并线。实际项目中,我遇到过 phone 识别合格的记录一条但 name 和 address 差别很大,如果不做加权,单靠 phone 会把两个完全不同的公司合并成一条,因为公司换了负责人和地址,但业务联系电话沿用的情况很常见。所以权重的设定要与业务强绑定,最好做成可配置项。

合并时还要注意字段的保留策略。通常按数据源的信誉度和时间戳排序:人工录入优于自动抓取,最新的覆盖旧的,字段为空的让另一个补充。同时一定要保留合并轨迹,记录“哪几条 ID 被合并进了哪条主记录”,否则审计和回滚都会很痛苦。

3.3 SQL语句中的模糊去重查询

聊完应用层,再看数据库层。SQL 里的DISTINCTGROUP BY都是精确去重,要做模糊去重必须借助特定函数或扩展。

PostgreSQL 里最方便的是 pg_trgm 扩展,它基于三元组(trigram)做相似度计算,直接能返回一个 0 到 1 的相似度分数:

CREATE EXTENSION IF NOT EXISTS pg_trgm; SELECT a.id, b.id, similarity(a.name, b.name) AS sim FROM records a JOIN records b ON a.id < b.id WHERE similarity(a.name, b.name) > 0.8;

MySQL 自带函数里没有现成的 Levenshtein 实现,但可以通过自定义函数或存储过程实现,逻辑并不复杂。不过我的经验是,不要把高强度的模糊匹配完全压到数据库里。自连接产生的候选对数量是 O(n²),即使数据库性能不错,一旦到了百万级数据,查询会拖垮整个库。更合理的架构是先用 SQL 做一个粗筛,比如把长度接近、首字符相同的记录选出来,再在应用层用向量和索引做精细的模糊比较。

SQL Server 提供了DIFFERENCESOUNDEX,它们基于发音相似度,适合英文姓名类字段。中文场景下效果一般,我不建议用它们做中文业务数据的模糊去重,最多做辅助排序字段。

3.4 图片去重:感知哈希的实战用法

很多人一提到去重就联想到文本,实际上图片去重在素材库、版权排查、电商图库场景里非常常见。早期我用 MD5 或 SHA1 直接比对文件哈希,结果发现同一张图片只要换个分辨率、加个水印、微调一下亮度,哈希就完全不同,去重完全失效。

图片模糊去重的标准方案是感知哈希(Perceptual Hash),核心思路是把图像缩小到固定尺寸,转换成灰度图,提取一个“结构指纹”。常用算法有 aHash(平均哈希)、pHash(感知哈希)、dHash(差异哈希),它们的逻辑大同小异,我用 dHash 最多,因为计算快、对缩放和水印的鲁棒性不错。大概流程是:把图片缩放到 9x8 像素,转灰度,比较相邻像素的亮度差异,得到 64 位二进制哈希。两张图片的哈希海明距离小于 5,就基本可以判定为同一张图的近似复制。

用 Python 实现的话,Pillow 配合 imagehash 库非常方便:

from PIL import Image import imagehash hash1 = imagehash.dhash(Image.open("photo1.jpg")) hash2 = imagehash.dhash(Image.open("photo2.jpg")) diff = hash1 - hash2 # 海明距离 print("相似度差值:", diff) if diff <= 5: print("判定为近似重复图片")

这类实现很多图片去重工具比如“米牛图片去重大师”就是这个思路。它扫描目录里的所有图片,批量计算感知哈希,然后把距离小于阈值的图片挑出来给你确认。如果你要自己实现一个类似功能,别忘了第一步先做尺寸缓存,把每张图缩放到统一大小再算哈希,否则性能会非常难看。

4. 一个容易被忽视的决策:Veeam与Data Domain集成时的去重开关

4.1 备份链路里的两级去重

文本和图片的模糊去重聊完了,再来一个我踩过的存储备份领域的坑。Veeam 是常用的虚拟机备份软件,Data Domain(简称 DD)是 Dell EMC 的重复数据删除存储设备,很多企业把 Veeam 备份作业指向 DD 作为目标存储。问题来了:Veeam 自己带源端去重压缩,DD 也带内联去重,两层的去重叠在一起,真的能“好上加好”吗?

先说背景。Veeam 的去重是源端去重,在备份代理机读取虚拟机数据后,直接对数据块做哈希识别,相同的块只传一次,目的是节省网络带宽和备份窗口。DD 的去重是目标端去重,数据落到 DD 后,DD 会再做一次内容定义分块和指纹比对,只存储唯一的数据块。从功能上看,两层都在做去重,但它们的算法、块边界和指纹库都是各自独立的,并不会因为 Veeam 已经去重就让 DD 的去重变快,反而可能出现负优化。

4.2 为什么目标端已是DD时建议关掉Veeam去重

我在集成测试里发现,Veeam 开启去重压缩再往 DD 写,最直接的影响是备份代理的 CPU 占用很高,任务耗时也会变长。而且 DD 收到的数据如果已经被 Veeam 重新组织过,数据块的连续性和原始模式会被破坏,DD 自身的指纹命中率反而可能下降,最终存储占用并没有显著变少,甚至还可能变大。整体算下来,初期省下的带宽,在中后段被性能和压缩率损失抵消掉了。

社区里很多最佳实践文档同样建议:当备份目标已经使用 DD 这种具备高等级去重能力的存储时,建议在 Veeam 侧关闭去重压缩,把去重的工作统一交给 DD 完成。这里的关键是“不要让两个去重引擎互相打架”。你可以把 Veeam 的去重想象成给快递先做了一次压包,再把压过的包裹交给专线运输,专线时又要拆包重新装车,来回折腾反而耗时。

当然这不是绝对规则。如果你的链路里网络带宽极其紧张,比如跨站点备份,源端必须先做一次去重压缩才能把数据传过去,那源端去重依然有意义。这种情况下就要做测试,找到一个两端都相对合理的平衡点。

4.3 怎么验证该关谁的去重:一组对照测试

拿我做过的一个项目举例,环境是一台 Veeam 备份服务器,后面接一台 DD3300。我先保留 Veeam 默认的去重压缩模式,跑了一个全量备份加增量,记录了备份耗时、CPU 峰值、传送到 DD 的数据体积,以及 DD 侧最终存储占用。然后我把 Veeam 备份作业的“去重压缩”选项关闭,只保留传输,再跑同样的备份任务,对比两组数据。

结果大致是这样:开启 Veeam 去重时,全量备份耗时 2 小时多一点,DD 侧显示逻辑备份数据量约 230GB,实际存储约 90GB;关闭 Veeam 去重后,备份耗时降到了 1 小时 40 分,DD 侧显示收到约 240GB 的逻辑数据,实际存储约 70GB。虽然网络侧多传了约 10GB 数据,但备份窗口更短,DD 的最终空间占用反而明显下降。

原因就是前面说的,Veeam 和 DD 各自分块算法不一致,Veeam 预处理过的数据流打乱了 DD 的指纹识别模式,导致 DD 去重率降低。所以我在生产环境的建议是:如果目标端是 DD 这类专用去重存储,优先关闭 Veeam 的去重压缩选项;如果没有 DD,只有普通磁盘或 NAS,那 Veeam 源端去重就得保留。评估标准不是单看某一层的产物大小,而是端到端的“备份耗时 + 最终存储占用 + 恢复速度”综合评分。

5. 常见问题与排查技巧实录

5.1 误判率偏高:阈值不是越高越好,要看文本长度

模糊去重最常见的翻车现场是误判率过高。我遇到过一个案例,阈值定在 0.85,结果把“北京市丰台区”和“北京市丰台区科技园”判成了同一条记录。单看相似度,两者确实超过 0.85,但业务上“丰台区”和“丰台区科技园”可能是完全不同的地点。问题出在短文本对相似度非常敏感:长度只有几个字的字符串,几个字符的差异对整体相似度影响被稀释了。

我的对策是引入长度因子。文本越短,判定为重复所需的阈值越高。具体做法是把阈值公式改成动态阈值,比如dynamic_threshold = base_threshold + min(len1, len2) * 0.005,或者直接用一条经验规则:长度小于 6 的字段,阈值不低于 0.95;长度大于 50 的字段,阈值可以降到 0.8。用动态阈值之后,误判率至少降低一半。

另外,每次判定的时候我都会把相似度分数记录进日志,方便事后回溯。如果业务方反馈“你把我两条不同数据合错了”,我可以直接查出当时两条记录的相似度分数,快速定位是阈值设置问题还是数据本身太像。

5.2 计算量爆炸:先缩小候选集再两两比较

第二个高频问题是性能。很多人一开始会用最朴素的双层循环,数据量一上来就扛不住。我前面提到过 18 万条地址数据的两两比较要 16 亿次,这个听起来很吓人,但实际解决思路并不复杂:先缩小候选集,再做精细匹配。

缩小候选集的做法叫 blocking,也叫分块。最简单的分块是取首字符或者前两个字作为桶键,只有同一个桶内的记录才做两两比较。地址数据还可以按行政区划代码分桶,姓名数据可以按姓氏分桶,电话数据可以按前三位号段分桶。加了首地址分块之后,我在那个 18 万条的项目里把候选对从 16 亿降到了约 800 万,再配合多进程并行,几小时就跑完了。

如果分块后候选集还是太大,可以用倒排索引做 N-gram 过滤:把每条文本拆成 2-gram,建立 gram 到文档 ID 的倒排表,只比较至少共享一个 gram 的文档对。这一招在文本查重场景里特别有效,因为完全不共享任何 2-gram 的两条文本,相似度大概率很低,直接跳过没有损失。

5.3 中文文本清洗的几个坑

中文模糊去重比英文麻烦得多,主要原因是中文没有天然分隔符,而且格式层面容易埋雷。第一是半角全角,数字、字母、标点都可能有全半角差异,比如“ABC”和“ABC”看似一样,字符编码完全不同,必须统一转成半角。第二是繁简体,企业名称和法律条文里经常混用,建议先统一转简体再比较。第三是中英文混排的空格问题,“北京市 Beijing”和“北京市Beijing”如果直接做 n-gram,可能会产生多余的空格差异,比较前最好也把空格规范掉。

清洗规则虽然琐碎,但收益非常大。我通常把清洗做成管道式函数:字符串类型转换、全角转半角、繁转简、去除首尾空格、压缩连续空格、统一大小写。先清洗,再计算相似度,数据质量会稳定很多。

还有一个容易忽略的细节:中文的“省”“市”“区”这类行政区划后缀,有的数据源省略、有的保留,直接参与相似度计算会拉低分数。如果业务上确定这些前缀后缀不影响判定,可以考虑把它们作为可忽略词处理,或者用带权重的 token 比较方式。

5.4 对象合并策略:留谁、删谁、如何溯源

最后一个常见坑是合并策略没有预案。模糊去重找到重复记录后,总要保留一条主记录,把其他记录合并进来,这时候就会碰到“留谁”的问题。如果只是简单保留数组里第一条,可能留下一条字段残缺、来源最差的记录,后面业务调用时会出各种问题。

我的经验是按三个优先级决策:第一优先是时间戳,保留最近更新的记录;第二优先是数据源质量,人工录入和官方接口的数据,优先级高于爬虫和手工导入;第三优先是字段完整度,保留非空字段最多的那条。三个规则可以组合成打分公式,综合得分最高的记录作为主记录,其余记录挂到主记录的合并列表中。

同时我强烈建议记录合并轨迹。每个对象加一个source_ids字段,把被合并掉的原始 ID 全部存进去,再写审计日志。这样一旦业务方质疑数据被改错,你能清楚看到“这条记录在什么时间、基于什么规则、由哪几条原始记录合并而来”。没有溯源机制的模糊去重,本质上是不可维护的脚本,后续会变成数据质量黑洞。

写在最后的几点体会

做了几年数据清洗和备份运维,我最大的体会是:模糊去重从来不是算法问题,而是决策问题。相似度算法随手就能拉开源库实现,难的是确定“像到什么程度就算是同一条记录”“合并时保留谁的字段”“被合并掉的数据如何溯源”。如果只是写脚本一次性跑完,怎么折腾都行;一旦要长期运维,一定要把阈值、算法、合并策略全部参数化、可回放,否则业务方质问你为什么把两条数据合错的时候,你连解释的依据都没有。

一个小技巧送给你:在跑模糊去重之前,永远先用精确去重把完全相同的记录清一遍。两个集合分开处理,能省掉一大半无效计算,也给后面的人工审核留出缓冲空间。模糊去重的价值不是把数据变干净,而是在不可避免的噪声里,依然能认出“这其实是同一个人、同一个公司、同一张图、同一份数据”。认出来之后怎么处理,才是真正考验架构和业务理解的地方。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询