Python 在拼写检查器中,如何获得3次编辑后的单词(norvig)
我一直在尝试对我的数据库表使用拼写更正器来更正一个表中的地址,我使用了的引用 使用地址\u mast表作为字符串集合,我正在尝试更正并更新“客户\u master中更正的字符串 地址\u桅杆Python 在拼写检查器中,如何获得3次编辑后的单词(norvig),python,sql-server,nlp,spell-checking,spelling,Python,Sql Server,Nlp,Spell Checking,Spelling,我一直在尝试对我的数据库表使用拼写更正器来更正一个表中的地址,我使用了的引用 使用地址\u mast表作为字符串集合,我正在尝试更正并更新“客户\u master中更正的字符串 地址\u桅杆 ID Address 1 sonal plaza,harley road,sw-309012 2 rose apartment,kell road, juniper, la-293889 3 plot 16, queen's tower, subbden - 399081 4
ID Address
1 sonal plaza,harley road,sw-309012
2 rose apartment,kell road, juniper, la-293889
3 plot 16, queen's tower, subbden - 399081
4 cognizant plaza, abs road, ziggar - 500234
现在,从参考代码来看,它只针对那些“离word两次编辑”的单词进行了操作。但我尝试在3次或4次编辑之前进行操作,同时尝试将这些更正的单词更新到其他表中。以下是包含拼写错误的单词的表,将使用更正的单词进行更新
客户_-master
Address_1
josely apartmt,kell road, juneeper, la-293889
zoonal plaza, harli road,sw-309012
plot 16, queen's tower, subbden - 399081
cognejantt pluza, abs road, triggar - 500234
这是我试过的
import re
import pyodbc
import numpy as np
from collections import Counter
cnxn = pyodbc.connect('DRIVER={SQLServer};SERVER=localhost;DATABASE=DBM;UID=ADMIN;PWD=s@123;autocommit=True')
cursor = cnxn.cursor()
cursor.execute("select address as data from Address_mast")
data=[]
for row in cursor.fetchall():
data.append(row[0])
data = np.array(data)
def words(text): return re.findall(r'\w+', text.lower())
WORDS = Counter(words(open('data').read()))
def P(word, N=sum(WORDS.values())):
"Probability of `word`."
return WORDS[word] / N
def correction(word):
"Most probable spelling correction for word."
return max(candidates(word), key=P)
def candidates(word):
"Generate possible spelling corrections for word."
return (known([word]) or known(edits1(word)) or known(edits2(word)) or known(edits3(word)) or known(edits4(word)) or [word])
def known(words):
"The subset of `words` that appear in the dictionary of WORDS."
return set(w for w in words if w in WORDS)
def edits1(word):
"All edits that are one edit away from `word`."
letters = 'abcdefghijklmnopqrstuvwxyz'
splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [L + R[1:] for L, R in splits if R]
transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R)>1]
replaces = [L + c + R[1:] for L, R in splits if R for c in letters]
inserts = [L + c + R for L, R in splits for c in letters]
return set(deletes + transposes + replaces + inserts)
def edits2(word):
"All edits that are two edits away from `word`."
return (e2 for e1 in edits1(word) for e2 in edits1(e1))
def edits3(word):
return (e3 for e2 in edits2(word) for e3 in edits1(e2))
def edits4(word):
return (e4 for e3 in edits3(word) for e4 in edits1(e3))
sqlstr = ""
j=0
k=0
for i in data:
sqlstr=" update customer_master set Address='"+correction(data)+"' where data="+correction(data)
cursor.execute(sqlstr)
j=j+1
k=k+cursor.rowcount
cnxn.commit()
cursor.close()
cnxn.close()
print(str(k) +" Records Completed")
因此,我无法获得正确的输出,任何关于应该进行哪些更改的建议。提前感谢我们可以使用现有的1编辑列表,并对该列表中的成员进行1编辑 算法: 一个单词=编辑1(单词) 为每一个单词编辑一个单词 进行编辑1(每个)
def edit2(word):
new=edits1(word)#获取所有编辑的列表
对于edits1(word)中的i:#迭代一个编辑列表中的所有对象
new.update(edits1(i))#对每个对象和外接程序列表进行一次编辑
返回新的#返回包含所有编辑的列表
类似地,我们可以使用相同的方法获得任意数量的编辑,下面的函数将帮助您获得3个编辑
def edit3(word):
新建=编辑2(word)
对于edit2my中的i(word):
新.更新(第1(i)版)
还新
警告:
即使计算量很小(时间复杂度很高)上述答案也可以,但有一个比检查编辑距离k的按指数递增的字符串集更快的解决方案。假设我们有一个数据结构,它将所有单词的集合存储在一个树结构中。这很有用,因为我们知道,例如,我们不需要搜索没有单词的路径。这既节省内存,又节省计算 假设我们有一个存储在set、dict或collections.Counter对象中的词汇表,那么我们可以如下设置数据结构:
class VocabTreeNode:
def __init__(self):
self.children = {}
self.word = None
def build(self, vocab):
for w in vocab:
self.insert(w)
def insert( self, word):
node = self
for letter in word:
if letter not in node.children:
node.children[letter] = VocabTreeNode()
node = node.children[letter]
node.word = word
为了只搜索单词编辑距离为k的元素集,我们可以赋予此结构递归搜索
def search(self, word, maxCost):
currentRow = range( len(word) + 1 )
results = []
for letter in self.children:
self.searchRecursive(self.children[letter], letter,
word, currentRow, results,
maxCost)
return results
def searchRecursive(self, node, letter, word, previousRow,
results, maxCost):
columns = len( word ) + 1
currentRow = [ previousRow[0] + 1 ]
for column in range( 1, columns ):
insertCost = currentRow[column - 1] + 1
deleteCost = previousRow[column] + 1
if word[column - 1] != letter:
replaceCost = previousRow[ column - 1 ] + 1
else:
replaceCost = previousRow[ column - 1 ]
currentRow.append( min( insertCost, deleteCost, replaceCost ) )
if currentRow[-1] <= maxCost and node.word != None:
results.append( (node.word, currentRow[-1] ) )
if min( currentRow ) <= maxCost:
for next_letter in node.children:
self.searchRecursive( node.children[next_letter], next_letter, word,
currentRow, results, maxCost)
这相当于每0.175秒编辑该单词的距离3计算。编辑距离4可以在.377秒内完成,而使用edits1连续编辑距离将很快导致系统内存不足
需要注意的是,不容易处理换位,这是一种快速有效的方法,可以为高编辑距离实现Norvig类型的算法。这真的与sql server有关吗?它可能是您的底层RDBMS,但问题似乎与DB服务器无关。请仅使用适当的标记。您可以使用C#或其他编程语言中的模糊查找组件(SSIS)API,使用内置方式查找近似匹配项。您似乎忘记了在
候选项()中包含新的edits3
和edits4
函数。或者,您的输出在哪些方面不正确?@RachelAmbler yes customer_主表包含一些地址,其中包含一些拼写错误的单词(因为该列是从其他印度地区语言到英语的文本中派生出来的)。所以我尝试使用拼写更正器来更正我翻译错误的文本,并用更正后的文本替换。。我将地址数据作为参考或训练数据,这些数据由相似或正确的单词组成。我的问题仍然是:“正确输出”到底缺少什么?您修复了使算法无法生成ad LD 3和4变体的错误,那么还有什么问题吗?非常具体:生产什么,它与您想要的有什么不同?
sleep(1)
start = time()
for i in range(100):
x = V.search('elephant',3)
print(time()- start)
>>> 17.5