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

求助:基于LCS距离的相似短语聚类合并为统一列表问题

问题描述

我有一个短语列表,示例如下:

words = ["client relationships","people management","collaborative teams","collaborative team","collaboration teams"……]

希望用最长公共子序列(LCS)距离度量(阈值0.2)筛选出相似但非相同的元素,将所有相似元素归为一个子列表,预期输出示例:

[["collaborative teams", "collaborative team","collaboration teams"]]

最初编写的代码运行后得到的是两两相似元素组成的子列表,不符合预期;修改后代码仍输出多个两两子列表,同时我还需要支持输出扁平列表(示例:["ability deliver", "ability develop","ability deliver", "quality delivery","ability drive", "ability deliver"]),求正确解决方案。


现有代码

初始代码

words= ["client relationships","people management","collaborative teams","collaborative team","collaboration teams".......]
list1=[]
for i in range(0,len(words)):
    for j in range(i+1,len(words)):
        t=[]
        v=metric_lcs(words[i],words[j])
        if v<=0.2:
            t.append(words[i])
            t.append(words[j])
            list.append(t)  # 原代码存在笔误,应为list1.append(t)

修改后代码

import itertools  # 原代码缺失该导入

list1 = []
for i in range(0,len(words)): 
    t=[]
    for j in range(i+1,len(words)):  
        v=metric_lcs(words[i],words[j])
        if v<=0.2:
            t.append(words[i])
            t.append(words[j])
            t=set(t)
            M=list(t)
            list1.append(M)
t=list1   
t.sort()
list(t for t,_ in itertools.groupby(t)) 

代码问题分析

  1. 初始代码仅记录两两相似对,未将所有互相相似的元素合并为一个组,导致输出均为二元子列表。
  2. 修改后的代码尝试用集合去重再分组,但itertools.groupby仅能对连续相同元素分组,且每次循环仅处理当前两两对,无法实现跨对的组合并。

解决方案

1. 将相似元素归为同一子列表(分组需求)

此需求本质是无向图的连通分量问题:把每个短语看作节点,相似短语间连边,每个连通分量即为一组相似元素。

def metric_lcs(s1, s2):
    # 示例LCS距离计算逻辑,可替换为你的实现(返回0-1之间的距离值)
    len1, len2 = len(s1), len(s2)
    dp = [[0]*(len2+1) for _ in range(len1+1)]
    for i in range(1, len1+1):
        for j in range(1, len2+1):
            if s1[i-1] == s2[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    lcs_len = dp[len1][len2]
    max_len = max(len1, len2)
    return 1 - (lcs_len / max_len) if max_len !=0 else 0

words = ["client relationships","people management","collaborative teams","collaborative team","collaboration teams"]

# 构建相似关系图
graph = {word: [] for word in words}
for i in range(len(words)):
    word1 = words[i]
    for j in range(i+1, len(words)):
        word2 = words[j]
        if metric_lcs(word1, word2) <= 0.2:
            graph[word1].append(word2)
            graph[word2].append(word1)

# 查找所有连通分量(分组)
visited = set()
groups = []
for word in words:
    if word not in visited:
        stack = [word]
        visited.add(word)
        group = []
        while stack:
            current = stack.pop()
            group.append(current)
            for neighbor in graph[current]:
                if neighbor not in visited:
                    visited.add(neighbor)
                    stack.append(neighbor)
        # 仅保留包含多个元素的组(筛选相似非相同的元素)
        if len(group) > 1:
            groups.append(group)

print(groups)
# 输出:[['collaborative teams', 'collaborative team', 'collaboration teams']]

2. 生成相似元素的扁平列表

若需要输出所有相似对的扁平列表(保留重复元素),只需收集所有符合阈值的两两对并展开:

flat_list = []
for i in range(len(words)):
    word1 = words[i]
    for j in range(i+1, len(words)):
        word2 = words[j]
        if metric_lcs(word1, word2) <= 0.2:
            flat_list.append(word1)
            flat_list.append(word2)

print(flat_list)
# 输出示例:['collaborative teams', 'collaborative team', 'collaborative teams', 'collaboration teams', 'collaborative team', 'collaboration teams']

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 15:37:03