You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言模糊去重内存不足问题求解(支持Cluster分组)

解决R中大规模数据集模糊去重的内存问题

示例数据集

address = c("882 4N Road River NY, NY 12345", "882 - River Road NY, ZIP 12345", "123 Fake Road Boston Drive Boston", "123 Fake - Rd Boston 56789")
name = c("ABC Center Building", "Cent. Bldg ABC", "BD Home 25 New", "Boarding Direct 25")
cluster = c("A", "A", "B", "B")
my_data = data.frame(address, name, cluster)

数据集输出:

address                name cluster
1    882 4N Road River NY, NY 12345 ABC Center Building       A
2    882 - River Road NY, ZIP 12345      Cent. Bldg ABC       A
3 123 Fake Road Boston Drive Boston      BD Home 25 New       B
4        123 Fake - Rd Boston 56789  Boarding Direct 25       B

目标

移除数据集中的模糊重复数据——人工可识别上述数据仅含2条唯一记录,但计算机无法直接判定,需通过模糊匹配技术处理。

此前尝试的方法及内存错误

处理10万行真实数据时,全量对比的方法因内存占用过大报错:

library(dplyr)
library(tidyr)
library(stringdist)

# 方法1
my_data_dists <- my_data %>% 
    mutate(row = row_number()) %>% 
    full_join(., ., by = character()) %>% 
    filter(row.x < row.y) %>% 
    mutate(
        address.dist = stringdist(address.x, address.y),
        name.dist = stringdist(name.x, name.y)
    ) %>% 
    arrange(scale(address.dist) + scale(name.dist)) %>% 
    relocate(
        row.x, row.y,
        address.dist, name.dist,
        address.x, address.y, 
        name.x, name.y
    )
# 报错:Error: cannot allocate vector of size 237.6 Gb

# 方法2
name_dists <- adist(my_data$name)
# 报错:Error: cannot allocate vector of size 475.3 Gb

需要完成的测试

  • 测试1:基于名称和地址移除模糊重复数据
  • 测试2:仅基于地址移除模糊重复数据

注:可借助cluster字段,在每个分组内执行去重以减少计算量(例如从4C2降至2C2)。


可行解决方案

核心思路:利用cluster分组,将大数据集拆分为小分组后再进行模糊匹配,避免全量两两对比导致的内存爆炸。结合字符串标准化提升匹配精度,使用高效的距离算法降低计算成本。

通用预处理(可选)

先对字符串做标准化处理,减少无关字符干扰,提升匹配准确性:

library(dplyr)
library(stringdist)
library(stringr)

# 字符串标准化函数
standardize_str <- function(x) {
    x %>%
        str_to_lower() %>%
        str_remove_all("[^a-zA-Z0-9\\s]") %>% # 移除特殊字符
        str_replace_all("\\s+", " ") %>% # 合并多个空格
        str_replace_all("rd", "road") %>% # 替换常见缩写
        str_replace_all("bldg", "building") %>%
        str_trim() # 去除首尾空格
}

# 应用标准化到数据集
my_data <- my_data %>%
    mutate(
        address_std = standardize_str(address),
        name_std = standardize_str(name)
    )

测试1:基于名称+地址的分组模糊去重

在每个cluster分组内,结合地址和名称的字符串距离判定重复,保留每组内的第一条有效记录:

# 分组内模糊重复判定函数
find_fuzzy_duplicates <- function(df, addr_thresh = 0.1, name_thresh = 0.1) {
    n <- nrow(df)
    if (n <= 1) return(df)
    
    # 计算Jaro-Winkler距离(适合短字符串匹配,范围0-1,值越小越相似)
    addr_dist <- stringdistmatrix(df$address_std, df$address_std, method = "jw")
    name_dist <- stringdistmatrix(df$name_std, df$name_std, method = "jw")
    
    # 合并距离并排除自身对比
    combined_dist <- addr_dist + name_dist
    diag(combined_dist) <- Inf
    
    # 标记重复行
    duplicates <- apply(combined_dist, 1, function(x) any(x < (addr_thresh + name_thresh)))
    
    # 保留非重复行(可根据需求调整保留规则,比如保留最完整的记录)
    df %>% filter(!duplicates) %>% slice(1)
}

# 按cluster分组处理
result_test1 <- my_data %>%
    group_by(cluster) %>%
    group_modify(~find_fuzzy_duplicates(.x)) %>%
    ungroup() %>%
    select(address, name, cluster) # 保留原字段

print(result_test1)

测试2:仅基于地址的分组模糊去重

仅使用地址字段进行模糊匹配,逻辑与测试1一致:

# 基于地址的重复判定函数
find_address_duplicates <- function(df, addr_thresh = 0.1) {
    n <- nrow(df)
    if (n <= 1) return(df)
    
    addr_dist <- stringdistmatrix(df$address_std, df$address_std, method = "jw")
    diag(addr_dist) <- Inf
    
    duplicates <- apply(addr_dist, 1, function(x) any(x < addr_thresh))
    
    df %>% filter(!duplicates) %>% slice(1)
}

# 按cluster分组处理
result_test2 <- my_data %>%
    group_by(cluster) %>%
    group_modify(~find_address_duplicates(.x)) %>%
    ungroup() %>%
    select(address, name, cluster)

print(result_test2)

关键优化点

  1. 分组计算:利用cluster拆分数据集,每个分组内的两两对比量大幅降低,彻底避免内存溢出。
  2. 字符串标准化:预处理消除无关字符、统一格式,提升匹配准确性的同时降低计算复杂度。
  3. 高效距离算法:Jaro-Winkler距离相比传统编辑距离,更适合地址、名称这类短字符串的模糊匹配,计算速度更快。
  4. 阈值可调:根据实际数据调整距离阈值,Jaro-Winkler距离0表示完全匹配,0.1以内通常可判定为高度相似的模糊重复。

内容的提问来源于stack exchange,提问作者stats_noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:15:35