将包含单词的行与排列进行匹配

时间:2009-04-08 22:12:18

标签: nlp information-retrieval

假设您有一个包含varchar列的大表。

如何匹配varchar col中包含“preferred”一词的行但是数据有点嘈杂并且偶尔会出现拼写错误,例如:

['$2.10 Cumulative Convertible Preffered Stock, $25 par value',
'5.95% Preferres Stock',
'Class A Preffered',
'Series A Peferred Shares',
'Series A Perferred Shares',
'Series A Prefered Stock',
'Series A Preffered Stock',
'Perfered',
'Preffered  C']

上述拼写错误中“首选”一词的排列似乎表现出family resemblance,但它们的共同点很少。请注意,拆分每个单词并在每行中的每个单词上运行levenshtein将会非常昂贵。

更新:

还有其他一些例子,例如:与'限制':

['Resticted Stock Plan',
'resticted securities',
'Ristricted Common Stock',
'Common stock (restrticted, subject to vesting)',
'Common Stock (Retricted)',
'Restircted Stock Award',
'Restriced Common Stock',]

4 个答案:

答案 0 :(得分:1)

您是否可以尝试在桌子的一小部分样本上进行训练,以找到可能的拼写错误(使用split + Levenshtein),然后在整个表格中使用生成的单词列表?

答案 1 :(得分:1)

尝试用TSQL或用什么语言来做?

你可以使用正则表达式击中大部分。

以下

的一些变体
"p(er|re|e)f{1,2}er{1,2}ed"

"r(e|i)s?t(ri|ir|rti|i)ct?ed"

你想确保它不是上限敏感的......

答案 2 :(得分:1)

再创建两个表格,拼写和可能的拼写:

- 你可以找出类型

create table spelling ( id, word ) ; 
create table possible_spelling 
( id, spelling_id references spelling(id), spelling ) 
-- possible spelling also includes the correct spelling
-- all values are lowercase

insert into spelling( word ) values ('preferred');
insert into possible_spelling( spelling_id, spelling ) 
 select 1, '%preferred%' union select 1, '%prefered%' union ....;

select * 
from bigtable a 
join possible_spelling b
on (lower(a.data) like b.spelling )
join spelling c on (b.spelling_id = c.id) 
where c.word = 'preferred';

异议:这会很慢,需要设置。 答:不是那么慢,这应该是分类和修复数据的一次性事情。一次设置,每个传入行一次进行分类。

答案 3 :(得分:1)

我可能会做这样的事情 - 如果你能一次离开Levenshtein - 这里是an amazing spellchecker implementation by Peter Norvig

import re, collections

def words(text): return re.findall('[a-z]+', text.lower()) 

def train(features):
    model = collections.defaultdict(lambda: 1)
    for f in features:
        model[f] += 1
    return model

NWORDS = train(words(file('big.txt').read()))

alphabet = 'abcdefghijklmnopqrstuvwxyz'

def edits1(word):
   s = [(word[:i], word[i:]) for i in range(len(word) + 1)]
   deletes    = [a + b[1:] for a, b in s if b]
   transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b)>1]
   replaces   = [a + c + b[1:] for a, b in s for c in alphabet if b]
   inserts    = [a + c + b     for a, b in s for c in alphabet]
   return set(deletes + transposes + replaces + inserts)

def known_edits2(word):
    return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)

def known(words): return set(w for w in words if w in NWORDS)

def correct(word):
    candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
    return max(candidates, key=NWORDS.get)

他提供了一套训练集here: http://norvig.com/big.txt以下是示例输出:

>>> correct('prefferred')
'preferred'
>>> correct('ristricted')
'restricted'
>>> correct('ristrickted')
'restricted'

在您的情况下,您可以将原始列复制到新列,但在执行时将其传递给拼写检查程序。然后在拼写正确的列上添加fulltext索引,并将查询与其匹配,但返回原始列的结果。您只需要执行一次,而不是每次都计算距离。您也可以拼写检查输入,或仅将更正后的版本检查为后备。无论哪种方式,值得研究Norvig的例子。