一个简单的基于编辑距离的英文单词查错(Python) - Muilpin.Miao的日志 - 网易博客
2012-10-10 14:23
375 查看
一个简单的基于编辑距离的英文单词查错(Python) - Muilpin.Miao的日志 - 网易博客
输入:测试文档,具有一定规模的字典输出:测试本当可能错误的单词并推荐可能正确的单词思路:统计测试文档中每个单词的频度,如果单词的频度小于一定阈值,则遍历字典,进行相似度计算并推荐相似度最强的那个正确单词。这样的思路的优点是简单易懂,取得的效果也较好,但存在以下缺点:1.前提假设不够充分;我们假设认为一个人不会重复写错的某个单词,但这种假设不能概括所有的情况;2.阈值的选取;阈值应该随着测试文档单词的数量进行自适应,而非固定;3.时间复杂度高;查错阶段每次需要遍历字典;
首先,对测试文档进行预处理。可以针对读取数据的特征采用正则表达式进行预处理,例如:#读取测试文档,计算词频test=open('test.txt','r') #打开测试文件contend=test.read()words=re.sub(r'[^\w]','|',contend).split('|') #使用正则表达式,匹配非字母与下划线的字符,使用’|‘代替其次,统计测试文档的词频。wc={}for word in words: word=word.lower() wc.setdefault(word,0) wc[word]+=1最后,将词频小于阈值的单词进入词典查错并推荐相似度高的单词。for d in wc: if wc[d]<2: #假设阈值为2,即当频度为1时,将单词进入字典里匹配 if d not in train: if d.rstrip("s ing") not in train: #基于规则再筛选,增加规则可以在这里增加 rec_word='' mind=999999999 for w in train: #查找字典与其最相似的单词进行推荐 dis=word_similarity(d,w) if dis<mind: mind=dis rec_word=w print "The wrong word is \"%s\" --> %s" % (d,rec_word)注意,里面还可以使用正则表达式扩展一些规则,提高准确率与效率以某篇英语6级作文作为输入文档进行测试,输出结果为:The wrong word is "quicker" --> quickenThe wrong word is "achieving" --> chewingUsed Time: 10.750000s 显然:时间复杂度是非常高的,但效果还是挺好的!编辑距离:用来计算两个字符串的相似度,可以理解为步骤数,步骤数=通过三个基本字符操作(增加,删除,更改)将源字符串转化成目标字符串的步骤数;如abc转化为abcd只需增加一个d,因此,步骤数=1,详细请参考具体文献;Python实现的具体代码如下:def word_similarity(word1,word2): if len(word1)==0 | len(word2)==0:return 99999999 juzhen=[[0 for j in range(len(word1)+1)] for i in range(len(word2)+1)] for i in range(len(word2)+1): juzhen[i][0]=i for j in range(len(word1)+1): juzhen[0][j]=j for i in range(1,len(word2)+1): for j in range(1,len(word1)+1): if word2[i-1]==word1[j-1]:cost=0 else:cost=1 juzhen[i][j]=min(juzhen[i-1][j]+1,juzhen[i][j-1]+1,juzhen[i-1][j-1]+cost)
return juzhen[len(word2)][len(word1)]非常神奇的编辑距离算法,感谢俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念;
后记1--加速:最后时间复杂度太高了,经过发现,消耗支出在于纠错:每个单词都需要与字典中6万多个单词计算编辑距离。因此,采取了一种措施:先将6万多个单词按照首字母分类,这样,出错单词就不需要将字典所有单词进行匹配,只匹配与自己首字母一样的那一块即可,速度定性估计提高了26倍。缺点是:如果第一个字母出错,那么纠错的正确率就会降低,因为纠错时假设首字母是对的;后记2--提高准确率:另外,增加了一些普遍通用的规则,如以'ing'结尾的单词用'e'代替'ing',再进入词典查找。并没有增加不规则单词变换的检查;普遍通用规则代码如下:if d not in first_word[d[0]]: if re.sub(r'es,'',d) not in first_word[d[0]] and re.sub(r's ,'',d) not in first_word[d[0]] and\
re.sub(r'd ,'',d) not in first_word[d[0]] and\ re.sub(r'er ,'',d) not in first_word[d[0]] and\ re.sub(r'ing ,'',d) not in first_word[d[0]] and\ re.sub(r'ed ,'',d) not in first_word[d[0]] and\ re.sub(r'ed ,'',d) not in first_word[d[0]] and\ re.sub(r'ied ,'y',d) not in first_word[d[0]] and\ re.sub(r'ing ,'e',d) not in first_word[d[0]] and re.sub(r'ies ,'y',d) not in first_word[d[0]]:
一个简单的基于编辑距离的英文单词查错(Python)
2011-06-10 20:15:26| 分类: 数据挖掘 | 标签:单词拼错 编辑距离 python 规则 |字号 大中小 订阅输入:测试文档,具有一定规模的字典输出:测试本当可能错误的单词并推荐可能正确的单词思路:统计测试文档中每个单词的频度,如果单词的频度小于一定阈值,则遍历字典,进行相似度计算并推荐相似度最强的那个正确单词。这样的思路的优点是简单易懂,取得的效果也较好,但存在以下缺点:1.前提假设不够充分;我们假设认为一个人不会重复写错的某个单词,但这种假设不能概括所有的情况;2.阈值的选取;阈值应该随着测试文档单词的数量进行自适应,而非固定;3.时间复杂度高;查错阶段每次需要遍历字典;
首先,对测试文档进行预处理。可以针对读取数据的特征采用正则表达式进行预处理,例如:#读取测试文档,计算词频test=open('test.txt','r') #打开测试文件contend=test.read()words=re.sub(r'[^\w]','|',contend).split('|') #使用正则表达式,匹配非字母与下划线的字符,使用’|‘代替其次,统计测试文档的词频。wc={}for word in words: word=word.lower() wc.setdefault(word,0) wc[word]+=1最后,将词频小于阈值的单词进入词典查错并推荐相似度高的单词。for d in wc: if wc[d]<2: #假设阈值为2,即当频度为1时,将单词进入字典里匹配 if d not in train: if d.rstrip("s ing") not in train: #基于规则再筛选,增加规则可以在这里增加 rec_word='' mind=999999999 for w in train: #查找字典与其最相似的单词进行推荐 dis=word_similarity(d,w) if dis<mind: mind=dis rec_word=w print "The wrong word is \"%s\" --> %s" % (d,rec_word)注意,里面还可以使用正则表达式扩展一些规则,提高准确率与效率以某篇英语6级作文作为输入文档进行测试,输出结果为:The wrong word is "quicker" --> quickenThe wrong word is "achieving" --> chewingUsed Time: 10.750000s 显然:时间复杂度是非常高的,但效果还是挺好的!编辑距离:用来计算两个字符串的相似度,可以理解为步骤数,步骤数=通过三个基本字符操作(增加,删除,更改)将源字符串转化成目标字符串的步骤数;如abc转化为abcd只需增加一个d,因此,步骤数=1,详细请参考具体文献;Python实现的具体代码如下:def word_similarity(word1,word2): if len(word1)==0 | len(word2)==0:return 99999999 juzhen=[[0 for j in range(len(word1)+1)] for i in range(len(word2)+1)] for i in range(len(word2)+1): juzhen[i][0]=i for j in range(len(word1)+1): juzhen[0][j]=j for i in range(1,len(word2)+1): for j in range(1,len(word1)+1): if word2[i-1]==word1[j-1]:cost=0 else:cost=1 juzhen[i][j]=min(juzhen[i-1][j]+1,juzhen[i][j-1]+1,juzhen[i-1][j-1]+cost)
return juzhen[len(word2)][len(word1)]非常神奇的编辑距离算法,感谢俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念;
后记1--加速:最后时间复杂度太高了,经过发现,消耗支出在于纠错:每个单词都需要与字典中6万多个单词计算编辑距离。因此,采取了一种措施:先将6万多个单词按照首字母分类,这样,出错单词就不需要将字典所有单词进行匹配,只匹配与自己首字母一样的那一块即可,速度定性估计提高了26倍。缺点是:如果第一个字母出错,那么纠错的正确率就会降低,因为纠错时假设首字母是对的;后记2--提高准确率:另外,增加了一些普遍通用的规则,如以'ing'结尾的单词用'e'代替'ing',再进入词典查找。并没有增加不规则单词变换的检查;普遍通用规则代码如下:if d not in first_word[d[0]]: if re.sub(r'es
re.sub(r'd ,'',d) not in first_word[d[0]] and\ re.sub(r'er ,'',d) not in first_word[d[0]] and\ re.sub(r'ing ,'',d) not in first_word[d[0]] and\ re.sub(r'ed ,'',d) not in first_word[d[0]] and\ re.sub(r'ed ,'',d) not in first_word[d[0]] and\ re.sub(r'ied ,'y',d) not in first_word[d[0]] and\ re.sub(r'ing ,'e',d) not in first_word[d[0]] and re.sub(r'ies ,'y',d) not in first_word[d[0]]:
相关文章推荐
- 一个简单的程序,统计文本文档中的单词和汉字数,逆序排列(出现频率高的排在最前面)。python实现。
- [Python]任一个英文的纯文本文件,统计其中的单词出现的个数。(考虑单词-分行)
- "输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。 句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。 例如输入“I am a student.”,则输出“student
- Python基于动态规划算法计算单词距离
- 从Apache的日志文件收集和提供统计数据(一个Python插件架构的简单实现)
- 基于java:读写一个英文的txt文件,记录单词个数,并输出十个出现最多的单词及出现的个数;
- 基于C#中的Trace实现一个简单的日志系统
- 一个基于python简单的装饰器实例
- 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。(笔试题) 句子中单词以空格符隔开。为简单起见,没有标点符号。 例如输入“I am a student”,则输出“student a
- 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍 一、pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主
- 一个简单的Python3爬虫获取两城市间铁路距离程序
- 一个简单的Python日志程序代码,支持按天滚动,限制备份保留个数
- Python每日练习 05 任一个英文的纯文本文件,统计其中的单词出现的个数
- 任意一个英文的纯文本文件,统计其中的单词出现的个数(shell python 两种语言实现)
- 一个基于Python3.6的方便简单的API测试工具类(支持将结果以JSON格式打印)
- 题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如输入“I am a student.”,则输出“student
- python判断一个单词是否为有效的英文单词?——三种方法
- python将一个英文语句以单词为单位逆序排放
- 一个基于log4cplus的简单日志类
- 基于Python的一个简单爬虫(糗事百科爬虫)