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

如何自定义python-levenshtein字符值以适配爱尔兰语文本正字法变化

解决python-levenshtein对爱尔兰语正字法变体的相似度计算问题

我明白你的需求——你在用python-levenshtein分析跨时间维度的爱尔兰语文本,这些文本里的正字法变体(比如bí→ḃí→bhí)其实是同一语法弱化形式,但默认的Levenshtein.ratio把它们当成完全不同的字符处理,导致相似度偏低。下面给你两个实用的解决方案,优先推荐第一种,简单直接还精准。

方案一:正字法归一化(最推荐)

核心思路是先把所有等价的正字法变体转换成统一的基础形式,再计算Levenshtein距离。这样语义/语法等价的文本归一化后完全一致,相似度自然拉满。

步骤1:构建爱尔兰语正字法映射表

把表示相同语法功能的变体映射到同一个基础字符,比如把弱化形式的ḃ、bh都映射回原始的b:

# 可根据爱尔兰语正字法规则,补充更多变体
ortho_map = {
    # 辅音弱化的变体映射
    'ḃ': 'b',
    'bh': 'b',
    'ḋ': 'd',
    'dh': 'd',
    'ḟ': 'f',
    'fh': 'f',
    'ġ': 'g',
    'gh': 'g',
    'ṁ': 'm',
    'mh': 'm',
    'ṗ': 'p',
    'ph': 'p',
    'ṡ': 's',
    'sh': 's',
    'ṫ': 't',
    'th': 't',
}

注意:要优先处理多字符变体(比如bh),避免单字符变体先替换导致匹配错误,后续处理时要按字符长度从长到短排序。

步骤2:编写归一化函数

这个函数会把输入文本里的所有变体替换成统一形式:

def normalize_irish_text(text):
    # 按变体的字符长度从长到短排序,确保多字符变体先被替换
    sorted_variants = sorted(ortho_map.keys(), key=lambda x: len(x), reverse=True)
    normalized_text = text
    for variant in sorted_variants:
        normalized_text = normalized_text.replace(variant, ortho_map[variant])
    return normalized_text

步骤3:结合python-levenshtein计算相似度

现在用归一化后的文本计算,就能得到符合预期的结果:

from Levenshtein import ratio

# 测试正字法变体
text_original = "bí"
text_lenited_1 = "ḃí"
text_lenited_2 = "bhí"

# 归一化处理
norm_original = normalize_irish_text(text_original)
norm_lenited_1 = normalize_irish_text(text_lenited_1)
norm_lenited_2 = normalize_irish_text(text_lenited_2)

# 计算相似度
print(f"原始bí和ḃí的相似度:{ratio(norm_original, norm_lenited_1)}")  # 输出1.0
print(f"原始bí和bhí的相似度:{ratio(norm_original, norm_lenited_2)}")  # 输出1.0
print(f"ḃí和bhí的相似度:{ratio(norm_lenited_1, norm_lenited_2)}")    # 输出1.0

对于更长的文本,这个方法同样适用,能有效消除正字法变化带来的不必要距离。

方案二:自定义编辑成本(保留细微差异时用)

如果你不想完全归一化,而是希望给这些变体设置更低的替换成本(比如让ḃ替换成b的成本远低于普通字符替换),可以手动处理编辑操作的权重:

from Levenshtein import editops

def custom_irish_ratio(text_a, text_b):
    total_cost = 0
    max_length = max(len(text_a), len(text_b))
    # 获取所有编辑操作
    operations = editops(text_a, text_b)
    
    for op_type, idx_a, idx_b in operations:
        if op_type == 'replace':
            char_a = text_a[idx_a]
            char_b = text_b[idx_b]
            # 检查两个字符是否是等价的正字法变体
            mapped_a = ortho_map.get(char_a, char_a)
            mapped_b = ortho_map.get(char_b, char_b)
            if mapped_a == mapped_b:
                # 等价变体,设置低替换成本
                total_cost += 0.1
            else:
                # 普通替换,成本为1
                total_cost += 1
        else:
            # 插入或删除操作,成本为1
            total_cost += 1
    
    # 计算自定义相似度(1 - 总成本/最大长度)
    return 1 - (total_cost / max_length)

# 测试单字符变体
print(f"自定义相似度:bí vs ḃí = {custom_irish_ratio('bí', 'ḃí')}")  # 输出约0.95

⚠️ 注意:这个方法对多字符变体(比如bh)处理起来比较麻烦,因为editops会把bí和bhí识别为插入一个h的操作,而非替换b为bh,所以如果你的文本里有大量多字符正字法变体,优先用方案一。


内容的提问来源于stack exchange,提问作者Charlie Tizzard Ó Kevlahan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:51:13