## 一、非大语言模型字符串相似度(Non-LLM String Similarity) 非大语言模型字符串相似度指标使用传统的字符串距离度量(如 Levenshtein、Hamming 和 Jaro)来衡量参考文本和响应之间的相似度。该指标可用于在不依赖大语言模型(LLMs)的情况下评估响应与参考文本的相似性。该指标返回介于 0 到 1 之间的分数,其中 1 表示响应与参考文本完全匹配。这是一个非大语言模型指标。 ### 使用 Levenshtein 距离的示例 #### 指标定义与公式 通过计算两个字符串之间的编辑距离(Levenshtein距离),衡量字符级相似性,无需依赖LLM。 数学公式: 1. $\text{Similarity} = 1 - \frac{\text{编辑距离}(s_1, s_2)}{\max(\text{len}(s_1), \text{len}(s_2))}$ ○ 编辑距离:将字符串 $s_1$ 转换为 $s_2$ 所需的最少操作次数(插入、删除、替换字符)。 ○ 归一化:通过除以两字符串的最大长度,将结果缩放到 [0,1] 区间。 #### 代码示例解析 ```python # 基于 Levenshtein距离(编辑距离) from ragas.dataset_schema import SingleTurnSample from ragas.metrics._string import NonLLMStringSimilarity sample = SingleTurnSample( response="The Eiffel Tower is located in India.", # 生成回答 reference="The Eiffel Tower is located in Paris." # 参考答案 ) scorer = NonLLMStringSimilarity() await scorer.single_turn_ascore(sample) # 输出 0.8918918918918919 ``` #### 计算过程 1. 字符串对比: ○ 响应:"The Eiffel Tower is located in India."(39字符) ○ 参考:"The Eiffel Tower is located in Paris."(38字符) 2. 编辑距离计算: ○ 需要将 "India" 替换为 "Paris",具体操作: ■ 替换 I → P ■ 替换 n → a ■ 替换 d → r ■ 保留 i → i ■ 替换 a → s ○ 总编辑距离:4次替换操作。 3. 相似度计算: $$ \text{Similarity} = 1 - \frac{4}{\max(39, 38)} = 1 - \frac{4}{39} \approx 0.8974 $$ (实际输出为 0.89189) ### 使用 Hamming 距离的示例 #### 指标定义与公式 1. 定义: 通过计算两个等长字符串在相同位置上的字符差异比例,衡量字符级相似性。 ○ 适用场景:仅适用于长度相同的字符串(如固定格式文本、密码校验)。 2. 数学公式: 3. $\text{Similarity} = 1 - \frac{\text{汉明距离}(s_1, s_2)}{n}$ ○ 汉明距离:两个等长字符串在相同位置上不同字符的数量。 ○ $n$:字符串长度。 #### 代码示例 ```python from ragas.metrics._string import NonLLMStringSimilarity, DistanceMeasure from ragas.dataset_schema import SingleTurnSample # 初始化汉明距离计算器 scorer = NonLLMStringSimilarity(distance_measure=DistanceMeasure.HAMMING) # 创建测试样本(需确保字符串等长) sample = SingleTurnSample( response="karolin", # 生成字符串(7字符) reference="kathrin" # 参考字符串(7字符) ) # 计算相似度 similarity_score = await scorer.single_turn_ascore(sample) print(f"相似度得分: {similarity_score}") # 输出: 0
时间: 2025-03-18 11:03:18 浏览: 73
<think>嗯,用户想了解传统的字符串相似度计算方法,特别是Levenshtein和Hamming距离,以及它们的Python实现。我需要先回顾一下这些算法的基本原理,然后查找相关的Python库或实现方式。
首先,Levenshtein距离,也就是编辑距离,用于计算两个字符串之间通过插入、删除或替换操作所需的最少次数。这在拼写检查和文本相似度中很常用。然后,汉明距离,它只适用于等长字符串,计算对应位置不同字符的数量。常用于编码检错或纠错。
接下来,Python的实现。记得有提到过python-Levenshtein库可以直接计算Levenshtein距离,但用户可能想知道如何手动实现,或者使用其他库比如fuzzywuzzy或者textdistance。不过用户明确提到传统方法,可能需要详细说明算法步骤,再给出代码示例。
比如,对于Levenshtein距离,动态规划的方法,创建一个二维数组,每个元素代表子问题的最小编辑次数。初始化第一行和第一列为0到n,然后逐个填充,根据当前字符是否相等来决定操作。最后返回右下角的值。
而汉明距离比较简单,遍历每个字符比较,统计不同的数量,但前提是字符串长度相同。否则需要处理长度不同的情况,可能抛出错误或者返回某种默认值。
还要注意用户提到的引用,比如引用[3]解释了编辑距离的概念,引用[2]和[5]提到了python-Levenshtein库和自定义函数。可能需要引用这些资料中的信息,确保回答的准确性。
此外,用户可能想知道实际应用场景,比如拼写纠错、文本去重等,如引用[4]所述。需要将这些应用场景结合到回答中,帮助用户理解如何应用这些方法。
然后,代码示例部分,可能需要展示手动实现的动态规划Levenshtein函数,以及使用python-Levenshtein库的方法。同样,汉明距离的手动实现和库函数调用。
可能的问题是如何处理不同长度的字符串在汉明距离中的情况,是否需要预处理或者截断。另外,效率问题,动态规划的时间复杂度是O(n*m),对于长字符串可能不够高效,但传统方法确实如此。
最后,生成相关问题,引导用户进一步学习其他距离度量,比如Jaro-Winkler或余弦相似度,或者优化方法,比如使用动态规划的空间优化。</think>### 传统字符串相似度计算方法及Python实现
#### 1. **Levenshtein距离(编辑距离)**
**原理**
Levenshtein距离表示将字符串$A$转换为字符串$B$所需的最少单字符编辑操作(插入、删除、替换)次数。例如,将`kitten`转换为`sitting`需要3次操作:
- 替换`k→s`
- 替换`e→i`
- 插入`g`
计算公式为动态规划实现:
$$
dp[i][j] = \begin{cases}
\max(i,j) & \text{if } \min(i,j)=0 \\
\min \begin{cases}
dp[i-1][j] + 1 \\
dp[i][j-1] + 1 \\
dp[i-1][j-1] + (0 \text{ if } A[i]=B[j] \text{ else } 1)
\end{cases} & \text{otherwise}
\end{cases}
$$
**Python实现**
手动实现动态规划:
```python
def levenshtein_distance(s1, s2):
m, n = len(s1), len(s2)
dp = [[0] * (n+1) for _ in range(m+1)]
for i in range(m+1):
dp[i][0] = i
for j in range(n+1):
dp[0][j] = j
for i in range(1, m+1):
for j in range(1, n+1):
cost = 0 if s1[i-1] == s2[j-1] else 1
dp[i][j] = min(dp[i-1][j] + 1, # 删除
dp[i][j-1] + 1, # 插入
dp[i-1][j-1] + cost) # 替换
return dp[m][n]
```
使用第三方库`python-Levenshtein`(效率更高)[^2]:
```python
import Levenshtein
distance = Levenshtein.distance("kitten", "sitting") # 输出3
```
#### 2. **汉明距离(Hamming Distance)**
**原理**
汉明距离要求两个字符串长度相等,通过比较对应位置的字符差异数量计算相似度。例如,`karolin`与`kathrin`的汉明距离为3(第3、5、6位字符不同)[^3]。
**Python实现**
手动实现:
```python
def hamming_distance(s1, s2):
if len(s1) != len(s2):
raise ValueError("字符串长度必须相同")
return sum(c1 != c2 for c1, c2 in zip(s1, s2))
```
使用`scipy`库:
```python
from scipy.spatial.distance import hamming
distance = hamming(list("karolin"), list("kathrin")) * len("karolin") # 输出3.0
```
#### 3. **相似度百分比计算**
通过距离值归一化得到相似度百分比。例如,Levenshtein相似度计算公式为:
$$
\text{相似度} = 1 - \frac{\text{Levenshtein距离}}{\max(\text{len}(A), \text{len}(B))}
$$
Python实现[^5]:
```python
def levenshtein_similarity(s1, s2):
max_len = max(len(s1), len(s2))
if max_len == 0:
return 1.0
distance = levenshtein_distance(s1, s2)
return (1 - distance / max_len) * 100
```
#### 应用场景
- **拼写纠错**:如`hte`纠正为`the`(Levenshtein距离=1)[^4]
- **DNA序列比对**:汉明距离用于基因变异分析
- **数据清洗**:检测重复文本(如商品名称去重)
阅读全文
相关推荐




