web-dev-qa-db-fra.com

Comment se débarrasser de la ponctuation en utilisant le tokenizer NLTK?

Je commence tout juste à utiliser NLTK et je ne comprends pas très bien comment obtenir une liste de mots à partir d'un texte. Si j'utilise nltk.Word_tokenize(), je reçois une liste de mots et de ponctuation. J'ai besoin que des mots à la place. Comment puis-je me débarrasser de la ponctuation? De plus, Word_tokenize ne fonctionne pas avec plusieurs phrases: des points sont ajoutés au dernier mot.

105
lizarisk

Jetez un coup d'oeil aux autres options de tokenizing fournies par nltk ici . Par exemple, vous pouvez définir un tokenizer qui sélectionne des séquences de caractères alphanumériques sous forme de jetons et supprime tout le reste:

from nltk.tokenize import RegexpTokenizer

tokenizer = RegexpTokenizer(r'\w+')
tokenizer.tokenize('Eighty-seven miles to go, yet.  Onward!')

Sortie:

['Eighty', 'seven', 'miles', 'to', 'go', 'yet', 'Onward']
142
rmalouf

Vous n'avez pas vraiment besoin de NLTK pour supprimer la ponctuation. Vous pouvez l'enlever avec un simple python. Pour les cordes:

import string
s = '... some string with punctuation ...'
s = s.translate(None, string.punctuation)

Ou pour l'unicode:

import string
translate_table = dict((ord(char), None) for char in string.punctuation)   
s.translate(translate_table)

puis utilisez cette chaîne dans votre tokenizer.

P.S. Le module chaîne contient d'autres ensembles d'éléments pouvant être supprimés (comme les chiffres).

41
Salvador Dali

Le code ci-dessous supprimera tous les signes de ponctuation ainsi que les caractères non alphabétiques. Copié de leur livre.

http://www.nltk.org/book/ch01.html

import nltk

s = "I can't do this now, because I'm so tired.  Please give me some time. @ sd  4 232"

words = nltk.Word_tokenize(s)

words=[Word.lower() for Word in words if Word.isalpha()]

print(words)

sortie

['i', 'ca', 'do', 'this', 'now', 'because', 'i', 'so', 'tired', 'please', 'give', 'me', 'some', 'time', 'sd']
23
Madura Pradeep

Comme indiqué dans les commentaires, commencez par sent_tokenize (), car Word_tokenize () ne fonctionne qu'avec une seule phrase. Vous pouvez filtrer la ponctuation avec filter (). Et si vous avez des chaînes unicode, assurez-vous qu'il s'agit bien d'un objet unicode (et non d'un "str" ​​codé avec un codage tel que "utf-8").

from nltk.tokenize import Word_tokenize, sent_tokenize

text = '''It is a blue, small, and extraordinary ball. Like no other'''
tokens = [Word for sent in sent_tokenize(text) for Word in Word_tokenize(sent)]
print filter(lambda Word: Word not in ',-', tokens)
15
palooh

Je viens d'utiliser le code suivant, qui supprime toute la ponctuation:

tokens = nltk.wordpunct_tokenize(raw)

type(tokens)

text = nltk.Text(tokens)

type(text)  

words = [w.lower() for w in text if w.isalpha()]
9
vish

Je pense que vous avez besoin d'une sorte de correspondance d'expression régulière (le code suivant se trouve dans Python 3):

import string
import re
import nltk

s = "I can't do this now, because I'm so tired.  Please give me some time."
l = nltk.Word_tokenize(s)
ll = [x for x in l if not re.fullmatch('[' + string.punctuation + ']+', x)]
print(l)
print(ll)

Sortie:

['I', 'ca', "n't", 'do', 'this', 'now', ',', 'because', 'I', "'m", 'so', 'tired', '.', 'Please', 'give', 'me', 'some', 'time', '.']
['I', 'ca', "n't", 'do', 'this', 'now', 'because', 'I', "'m", 'so', 'tired', 'Please', 'give', 'me', 'some', 'time']

Cela devrait bien fonctionner dans la plupart des cas, car il supprime la ponctuation tout en préservant les jetons tels que "net", ce qui ne peut pas être obtenu à partir de jetons de regex tels que wordpunct_tokenize.

6
Quan Gan

J'utilise ce code pour supprimer la ponctuation:

import nltk
def getTerms(sentences):
    tokens = nltk.Word_tokenize(sentences)
    words = [w.lower() for w in tokens if w.isalnum()]
    print tokens
    print words

getTerms("hh, hh3h. wo shi 2 4 A . fdffdf. A&&B ")

Et si vous voulez vérifier si un jeton est un mot anglais valide ou non, vous pouvez avoir besoin de PyEnchant

Didacticiel:

 import enchant
 d = enchant.Dict("en_US")
 d.check("Hello")
 d.check("Helo")
 d.suggest("Helo")
4
zhenv5

Supprimer la ponctuation (Cela supprimera. Ainsi qu'une partie de la gestion de la ponctuation en utilisant le code ci-dessous)

        tbl = dict.fromkeys(i for i in range(sys.maxunicode) if unicodedata.category(chr(i)).startswith('P'))
        text_string = text_string.translate(tbl) #text_string don't have punctuation
        w = Word_tokenize(text_string)  #now tokenize the string 

Exemple d'entrée/sortie:

direct flat in oberoi esquire. 3 bhk 2195 saleable 1330 carpet. rate of 14500 final plus 1% floor rise. tax approx 9% only. flat cost with parking 3.89 cr plus taxes plus possession charger. middle floor. north door. arey and oberoi woods facing. 53% paymemt due. 1% transfer charge with buyer. total cost around 4.20 cr approx plus possession charges. rahul soni

['direct', 'flat', 'oberoi', 'esquire', '3', 'bhk', '2195', 'saleable', '1330', 'carpet', 'rate', '14500', 'final', 'plus', '1', 'floor', 'rise', 'tax', 'approx', '9', 'flat', 'cost', 'parking', '389', 'cr', 'plus', 'taxes', 'plus', 'possession', 'charger', 'middle', 'floor', 'north', 'door', 'arey', 'oberoi', 'woods', 'facing', '53', 'paymemt', 'due', '1', 'transfer', 'charge', 'buyer', 'total', 'cost', 'around', '420', 'cr', 'approx', 'plus', 'possession', 'charges', 'rahul', 'soni']

1
ascii_walker

Sincèrement demander, qu'est-ce qu'un mot? Si vous supposez qu'un mot ne contient que des caractères alphabétiques, vous avez tort, car des mots tels que can't seront détruits en plusieurs morceaux (tels que can et t) si vous supprimez la ponctuation avant la tokenisation, ce qui affectera très probablement votre programme de manière négative.

Par conséquent, la solution consiste à tokenise et ensuite supprimer les jetons de ponctuation.

import string

from nltk.tokenize import Word_tokenize

tokens = Word_tokenize("I'm a southern salesman.")
# ['I', "'m", 'a', 'southern', 'salesman', '.']

tokens = list(filter(lambda token: token not in string.punctuation, tokens))
# ['I', "'m", 'a', 'southern', 'salesman']

... et si vous le souhaitez, vous pouvez remplacer certains jetons tels que 'm par am.

0
Bora M. Alper

En ajoutant simplement à la solution par @rmalouf, cela n'inclura aucun nombre car\w + est équivalent à [a-zA-Z0-9_]

from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer(r'[a-zA-Z]')
tokenizer.tokenize('Eighty-seven miles to go, yet.  Onward!')
0
Himanshu Aggarwal