2010-02-01 2 views
12

Y a-t-il une bonne bibliothèque capable de détecter et de séparer les mots d'une chaîne combinée?Détecter les mots les plus probables du texte sans espaces/mots combinés

Exemple:

"cdimage" -> ["cd", "image"] 
"filesaveas" -> ["file", "save", "as"] 
+1

Je n'ai aucune expérience dans ce domaine, mais vous voudrez peut-être commencer par jeter un oeil à la boîte à outils du langage naturel. http://www.nltk.org/ –

+3

Et FileSaveAs pourraient être divisés * ave fichiers comme * pas simplement le fichier * Enregistrer sous * Il serait difficile simplement de partager sur les possibilités de mot, sauf si vous avez un vocabulaire spécialisé. – Sparky

+4

Et ["c", "dim", "age"], ["cd", "i", "mage"], etc ... ce n'est pas facile de le faire correctement sans connaître le contexte. Il devient encore plus difficile de choisir la bonne option lorsqu'il existe de nombreux termes et abréviations propres au domaine qui sont rares dans le texte normal mais communs dans les entrées attendues typiques. Vous auriez probablement besoin de former l'algorithme. –

Répondre

11

est ici une solution de programmation dynamique (mis en œuvre en fonction memoized).Étant donné un dictionnaire de mots avec leurs fréquences, il divise le texte d'entrée aux positions qui donnent la phrase la plus probable. Vous devrez trouver une vraie liste de mots, mais j'ai inclus quelques fréquences inventées pour un test simple.

WORD_FREQUENCIES = { 
    'file': 0.00123, 
    'files': 0.00124, 
    'save': 0.002, 
    'ave': 0.00001, 
    'as': 0.00555 
} 

def split_text(text, word_frequencies, cache): 
    if text in cache: 
     return cache[text] 
    if not text: 
     return 1, [] 
    best_freq, best_split = 0, [] 
    for i in xrange(1, len(text) + 1): 
     word, remainder = text[:i], text[i:] 
     freq = word_frequencies.get(word, None) 
     if freq: 
      remainder_freq, remainder = split_text(
        remainder, word_frequencies, cache) 
      freq *= remainder_freq 
      if freq > best_freq: 
       best_freq = freq 
       best_split = [word] + remainder 
    cache[text] = (best_freq, best_split) 
    return cache[text] 

print split_text('filesaveas', WORD_FREQUENCIES, {}) 

--> (1.3653e-08, ['file', 'save', 'as']) 
7

Je ne connais pas de bibliothèque, mais il ne devrait pas être difficile à mettre en œuvre les fonctionnalités de base.

  1. Obtenez une liste de mots, comme words UNIX.
  2. Remplissez le contenu de votre liste de mots dans un fichier.
  3. Prenez la chaîne que vous voulez diviser et suivez son chemin dans le trie. Chaque fois que vous atteignez un mot valide, créez une nouvelle branche qui recherche un mot à partir du point de la chaîne que vous avez. Une fois que vous avez terminé votre branche actuelle, revenez à celle que vous avez créée, comme dans une première recherche approfondie.
  4. Désambiguque les listes résultantes manuellement, en utilisant des heuristiques ou via un analyseur de langage naturel.

Exemple:

  1. Parole: "filesaveasstring"
  2. Le premier mot est valide "fichier". Essayez de faire correspondre "saveas". Le premier mot valide est "enregistrer". Essayez de faire correspondre "asstring". Le premier mot valide est "as". Essayez de faire correspondre "chaîne". Le premier mot valide est "chaîne". Matched jusqu'à la fin; Mettez le [enregistrer le fichier sous forme de chaîne] dans votre liste de résultats.
  3. Retour à la "chaîne" correspondante - pas d'autres possibilités. Revenir à "asserter". Le premier mot valide non visité est "ass". Essayez de faire correspondre "tring". Pas de correspondance possible Revenir à "asserter". Pas de correspondance possible Retour à "filesaveasstring".
  4. La première correspondance non consultée est "fichiers". Essayez de faire correspondre "aveasstring". Le premier match est "ave". Essayez de faire correspondre "asstring" (mêmes résultats qu'aux étapes 2/3), en ajoutant [files ave as string] à votre liste de résultats et revenir en arrière au début.
  5. Essayez de trouver "filesaveasstring". Pas de correspondance non visitée Terminé.
  6. Sélectionnez le fichier le plus probable parmi [[enregistrer le fichier sous forme de chaîne] [fichiers ave sous forme de chaîne]] à l'aide d'un heuristique ou d'un analyseur de langage naturel.
+0

Quel est le temps d'exécution de ceci? Je ne suis pas en mesure de généraliser suffisamment ce problème pour trouver sa complexité Big-O précise. –

2

Je ne sais pas une bibliothèque qui fait cela, mais il est pas trop difficile d'écrire si vous avez une liste de mots:

wordList = file('words.txt','r').read().split() 
words = set(s.lower() for s in wordList) 

def splitString(s): 
    found = [] 

    def rec(stringLeft, wordsSoFar): 
     if not stringLeft: 
      found.append(wordsSoFar) 
     for pos in xrange(1, len(stringLeft)+1): 
      if stringLeft[:pos] in words: 
       rec(stringLeft[pos:], wordsSoFar + [stringLeft[:pos]]) 

    rec(s.lower(), []) 
    return found 

Ceci renverra toutes les façons possibles pour diviser la chaîne en les mots donnés.

Exemple:

>>> splitString('filesaveas') 
[['file', 'save', 'as'], ['files', 'ave', 'as']] 
-1

si vous ne faites pas cela pour le plaisir, mais il est en train de faire quelque chose pour le travail etc, mon conseil est d'aborder ce à la source. Pourquoi avez-vous ces chaînes combinées comme ça? Où avez-vous eu ces ficelles? Si c'est possible, insérez des espaces à la source de l'origine de ces chaînes.

+1

désolé, mais c'est une réponse à tous les problèmes. (Q: "comment peindre la maison en blanc?" -> A: "ajouter du calcium blanc à la terre et venir 1 million d'années plus tard et creuser des briques blanches en premier lieu") –

3

Amener les gens à les résoudre comme un captcha sur votre site :)

-1

Je sais que cette question est marquée pour Python mais j'avais besoin d'une implémentation JavaScript. En quittant les réponses précédentes, je me suis dit que je partagerais mon code. Semble travailler décemment.

Remarque: "_dictionary" devrait être un tableau de mots triés par fréquence. J'utilise une liste de mots du projet Gutenberg.

Questions connexes