2017-09-25 3 views
0

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!

Répondre

0

Pour ceux qui cherchent une réponse à cela, ci-dessous est ce qui a fonctionné pour moi:

def _words(df): 
    """Returns the total count of each word within a dataframe.""" 
    return df['query'].str.get_dummies(sep=' ').T.dot(df['count']) 


class _SpellCheckClient(object): 
    """Wraps functionality to check the spelling of a query.""" 

    def __init__(self, team, table, database_connection): 
    self.df = database_connection 
    self.words = _words(self.df) 

    def expected_word(self, query): 
    """Most probable spelling correction for word.""" 
    return max(self._candidates(query), key=self._probability) 

    def _probability(self, query): 
    """Probability of a given word within a query.""" 
    return self.words.pipe(lambda x: x/x.sum()).get(query, 0.0) 

    def _candidates(self, query): 
    """Generate possible spelling corrections for word.""" 
    return (self._known(self._one_edits_from_query(query)) 
      or self._known(self._two_edits_from_query(query)) 
      or [query]) 

    def _known(self, query): 
    """The subset of `query` that appear in the search console database.""" 
    return set(w for w in query if self.words.get(w)) 

    def _one_edits_from_query(self, query): 
    """All edits that are one edit away from `query`.""" 
    splits = [(query[:i], query[i:]) for i in xrange(len(query) + 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_query(self, query): 
    """All edits that are two edits away from `query`.""" 
    return (e2 for e1 in self._one_edits_from_query(query) 
      for e2 in self._one_edits_from_query(e1))