编辑距离算法的优化与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编辑距离算法的优化与实现
摘要:在分析基于动态规划的编辑距离算法对文本相似度计算的不足的基础上,利用数据结构在空间效率和时间效率上优化该算法、采用中文分词的思想优化和改善该算法的时间效率和准确率,克服了原有的基于动态规划的计算方法所具有的效率低、准确率低、耗内存高的缺点。通过多种优化方案的实验测试和分析,结果表明优化后的算法取得了很好的准确率和时空效率,更好的用于文本相似度计算。
关键词:编辑距离算法;文本相似度计算;算法优化;动态规划
1引言
文本相似度的计算在信息检索、文本分类、知识挖掘、网页去重、问答系统等诸多领域有着极为广泛的应用,长期以来一直是研究的热点和难点。人们在文本相似度计算中使用编辑距离算法,但该方法单纯以字为单位计算各个字符之间的编辑距离,插入删除替换三种基本操作的代价值的方法不够明确合理,从而使计算结果存在一定的偏差。故对传统的文本相似度检测编辑距离算法进行优化和改善,提出了一种基于改进编辑距离和中文分词相融合的计算文本相似度的方法,使优化改善后的算法具有较高的准确率和效率、较低的存储空间,更符合文本相似度计算的要求,有效提高文本相似度算法的效率和准确性,使文本相似度计算的性能进一步改善。
2编辑距离算法
4.3.1编辑距离定义
编辑距离又称Levenshtein距离(也叫做Edit Distance),是由俄国科学家Vladimir Levenshtein于1965年在文献[1]中提出的,是一种常用的距离函数度量方法,在多个领域特别是文本相似度检测得到了广泛的应用。编辑距离是指两系列字符串之间只能通过插入、删除和替换三种基本操作把源字符串(S)转换成目标字符串(T)所需的最少基本操作次数。编辑距离值越大,则相似度越小。
4.3.2编辑距离算法原理
对于求两个字符串之间的编辑距离实际上可以转化为一个求最优解的问题,可以利用动态规划的思想[2]来计算,计算原理的步骤如下表2-1所示:
表2-1 编辑距离算法原理的计算步骤
本小节将演示如何计算源字符串"GUMBO"和目标字符串"GAMBOL"两个字符串之间的Levenshtein距离,计算步骤如下:
步骤7,编辑距离是矩阵右下角的值,d[m,n]=2;
源字符串"GUMBO"变换为目标字符串"GAMBOL"的过程,直观可看出的,即通过将"A"替换为"U",并在末尾追加"L"字符,这跟计算的结果一致。
4.3.3编辑距离以及文本相似度计算
编辑距离D(S,T)的计算方法如下所述。首先假设D
ij =D(s
1
…s
i,
, t
1
…t
j
),
0≤i≤m,0≤j≤n, D
ij 表示从s
1
…s
i
到t
1
…t
j
的编辑距离,那么(m+1)×(n+1)
阶矩阵D
ij
可通过下面的(1)式计算得到:
0 i=0且j=0;
D
i-1 j-1+(if s
i
= t
j
then 0 else 1);
D ij = Min D
i-1,j
+1; i>0或j>0; (1)式
D
i,j-1
+1;
(1)式包含删除、插入、替换三种操作,该算法是从两字符串的左边开始比较,记录已经比较过的编辑距离,然后进一步得到下一个字符位置时的编辑距离。
矩阵D
ij 能够通过从D
00
逐步逐列计算获取,最终D
mn
表示D(S,T)的值,即S和T
的编辑距离。
文本相似度计算[3]:编辑距离越大,相似度越小。假设源字符串S与目标字符串T长度的最大值为L max,编辑距离为LD,相似度为SI,则相似度SI的计算如(2)式所示。
SI=1-LD/L max (2)式4.3.4编辑距离算法核心代码
public int LevenshteinDistance(string strs1, string strs2)
{
char[] str1=strs1.ToCharArray();
char[] str2=strs2.ToCharArray();
int i,j,temp;
if (str1.Length == 0)
{
temp = str2.Length;
}
if (str2.Length == 0)
{
temp = str1.Length;
}
int[,] dist = new int[str1.Length + 1, str2.Length + 1];
for(i=0;i<=str1.Length;i++) dist[i,0]=i;
for(i=0;i<=str2.Length;i++) dist[0,i]=i;
for(i=1;i<=str1.Length;i++)
{
for(j=1;j<=str2.Length;j++)
{
if( str1[i-1] == str2[j-1])
{
dist[i,j]=dist[i-1,j-1];
}
else
{
dist[i, j] = LowerOfThree(dist[i, j - 1], dist[i - 1, j-1], dist[i - 1, j]) + 1;
}