J'essaie d'implémenter Peter Norvig's spell checker dans une classe pandas avec des mots tirés d'une base de données SQL. Les données contiennent des requêtes utilisateur qui contiennent souvent un certain nombre d'erreurs d'orthographe, et j'espère que cette classe renverra la requête la plus probable (orthographiée correctement).Vérificateur d'orthographe dans les pandas
La classe est initialisée avec une requête de base de données qui renvoie une trame de données pandas. Par exemple:
query count
0 foo bar 1864
1 super foo 73
2 bar of foos 1629
3 crazy foos 940
La plupart des ci-dessous est tiré directement du travail de Peter, mais les modifications que j'ai fait à la classe ne semblent pas fonctionner correctement. Je suppose que cela a quelque chose à voir avec la suppression de la fonctionnalité de compteur (WORDS = Counter(words(open('big.txt').read()))
) mais je ne suis pas sûr de la meilleure façon d'obtenir cette fonctionnalité à partir d'une base de données.
classe actuelle ci-dessous:
class _SpellCheckClient(object):
"""Wraps functionality to check the spelling of a query."""
def __init__(self, team, table, dremel_connection):
self.df = database_connection.ExecuteQuery(
'SELECT query, COUNT(query) AS count FROM table GROUP BY 1;'
def expected_word(self, word):
"""Most probable spelling correction for word."""
return max(self._candidates(word), key=self._probability)
def _probability(self, query):
"""Probability of a given word within a query."""
query_count = self.df.loc[self.df['query'] == query]['count'].values
return query_count/self.df['count'].sum()
def _candidates(self, word):
"""Generate possible spelling corrections for word."""
return (self._known([word])
or self._known(self._one_edits_from_word(word))
or self._known(self._two_edits_from_word(word))
or [word])
def _known(self, query):
"""The subset of `words` that appear in the dictionary of WORDS."""
# return set(w for w in query if w in WORDS)
return set(w for w in query if w in self.df['query'].value_counts)
def _one_edits_from_word(self, word):
"""All edits that are one edit away from `word`."""
splits = [(word[:i], word[i:]) for i in xrange(len(word) + 1)]
deletes = [left + right[1:] for left, right in splits if right]
transposes = [left + right[1] + right[0] + right[2:]
for left, right in splits
if len(right) > 1]
replaces = [left + center + right[1:]
for left, right in splits
if right for center in LETTERS]
inserts = [left + center + right
for left, right in splits
for center in LETTERS]
return set(deletes + transposes + replaces + inserts)
def _two_edits_from_word(self, word):
"""All edits that are two edits away from `word`."""
return (e2 for e1 in self._one_edits_from_word(word)
for e2 in self._one_edits_from_word(e1))
Merci à l'avance!