相似重复记录清洗基本过程:
1.准备阶段。
1)选择关键属性字段。2)分配权重。
2.选择属性字段匹配算法。
3.检测。
比较阈值,大于阈值则认为两条记录相似重复。
4.相似重复记录清理。
重复检测思路:
1.一个字母编辑成另一个字母的步骤。
2.生物领域的差异扣分方式,与1.相反。
3.Jaro和Jaro-Winkler:计算结果为0-1,不会出现编辑距离这种两个完全不相干的单词仍然有步骤。
4.模糊匹配。
5.发音匹配(根据音标)
(参考书籍:Pentaho Kettle Solution(p122) Author: Matt Casters)
算法:
1. 编辑距离。
在这里定义的单字符编辑操作有且仅有三种:
插入(Insertion)
删除(Deletion)
替换(Substitution)
譬如,“kitten” 和 “sitting” 这两个单词,由 “kitten” 转换为 “sitting” 需要的最少单字符编辑操作有:
1).kitten → sitten (substitution of “s” for “k”)
2).sitten → sittin (substitution of “i” for “e”)
3).sittin → sitting (insertion of “g” at the end)
因此,“kitten” 和 “sitting” 这两个单词之间的编辑距离为 3 。
形式化定义:
理解:此处三种情况为单字符编辑操作的三种:删除,插入,替换。累计使得两个比较字符不断接近的次数,最终递推得到总次数。
思考:编辑距离是NLP基本的度量文本相似度的算法,可以作为文本相似任务的重要特征之一,其可应用于诸如拼写检查、论文查重、基因序列分析等多个方面。但是其缺点也很明显,算法基于文本自身的结构去计算,并没有办法获取到语义层面的信息。
算法实现:
递归:
python代码
def Levenshtein_Distance_Recursive(str1, str2):
if len(str1) == 0:
return len(str2)
elif len(str2) == 0:
return len(str1)
elif str1 == str2:
return 0
if str1[len(str1)-1] == str2[len(str2)-1]:
d = 0
else:
d = 1
return min(Levenshtein_Distance_Recursive(str1, str2[:-1]) + 1,
Levenshtein_Distance_Recursive(str1[:-1], str2) + 1,
Levenshtein_Distance_Recursive(str1[:-1], str2[:-1]) + d)
print(Levenshtein_Distance_Recursive("abc", "bd"))
>>>
2
java代码:
//编辑距离递归实现
static int Len_Distance(String str1,String str2) {
int d=0;
if (str1.length()==0) {
return str2.length();
}else if(str2.length()==0) {
return str1.length();
}
//分别取两个字符串的最后一位比较
if(str1.substring(str1.length()-1, str1.length())
==str2.substring(str2.length()-1, str2.length()))
{
d=0;
}else {
d=1;
}
//删除、插入、更新两个字符比较,取最小的步骤
return min(Len_Distance(str1
,str2.substring(0,str2.length()-1))+1,Len_Distance(str1.substring(0,str1.length()-1)
,str2)+1,
Len_Distance(str1.substring(0,str1.length()-1)
,str2.substring(0, str2.length()-1))+d);
}
private static int min(int a,int b,int c) {
if(a<=b&&a<=c) {
return a;
}else if(b<=a&&b<=c) {
return b;
}else
return c;
}
2.最长公共子序列
问题描述:如“abcdba”和“abcya”,序列说明是按照顺序的,再加上其重复性不难看出,公共子序列为加粗字符“abcdba” 和“abcya”。即“abca”。
思考:
1.找到状态值。
1)即每个字符从后向前删除对应的公共序列。
2.找到边界状态。
1)当其中一个字符为空时,返回0;
3.得出方程式。
MaxLen(n,0)=0 (n=0…len1)
MaxLen(0,n)=0 (n=0…len2)
递推:
if(s1[i-1]==s2[j-1]) //最后一个字符的比较
MaxLen(i,j)=MaxLen(i-1,j-1)+1;
else
MaxLen(i,j)=Max (MaxLen(i-1,j), MaxLen(i,j-1)); //逐个删除比较,千万别一起删除最后一个字符,容易造成情况混乱
算法实现:
java代码:
/**
*
* @param s1 字符串s1
* @param s2 字符串s2
* @return 公共子序列长度
*/
public static int Len(String s1,String s2) {
int i=s1.length();
int j=s2.length();
if((s1.length()==0)||(s2.length()==0)) { //当其中一个字符数量为0时,返回0
return 0;
}else if(s1.substring(i-1,i).contains(s2.substring(j-1,j))) { //逐渐从尾巴删除字符比较
return Len(s1.substring(0,i-1),s2.substring(0,j-1))+1;
}else {
return Max(Len(s1.substring(0,i-1),s2),Len(s1,s2.substring(0,j-1))); //逐个字符添加对比
}
}
private static int Max(int a,int b) {
if(a>=b) {
return a;
}else {
return b;
}
参考文献
[1]. 王武, 数据清洗方法研究及工具设计, 2009, 上海交通大学.
[2].详解编辑距离(Edit Distance)及其代码实现:
作者:TSW1995