2013-03-21 9 views
70

Właśnie zaczynam używać NLTK i nie bardzo rozumiem, jak uzyskać listę słów z tekstu. Jeśli używam nltk.word_tokenize(), otrzymuję listę słów i znaków interpunkcyjnych. Potrzebuję tylko słów. Jak mogę pozbyć się interpunkcji? Również word_tokenize nie działa z wieloma zdaniami: kropki są dodawane do ostatniego słowa.Jak pozbyć się interpunkcji za pomocą tokenizera NLTK?

+10

Dlaczego nie można usunąć znaki interpunkcyjne siebie? 'nltk.word_tokenize (the_text.translate (None, string.punctuation))' powinien działać w python2 podczas gdy w python3 możesz zrobić 'nltk.work_tokenize (the_text.translate (dict.fromkeys (string.punctuation)))'. – Bakuriu

+2

To nie działa. Nic nie dzieje się z tekstem. – lizarisk

+0

Przepływ pracy przyjęty przez NLTK polega na tym, że najpierw dzielisz na zdania, a następnie każde zdanie na słowa. Dlatego 'word_tokenize()' nie działa z wieloma zdaniami. Aby pozbyć się interpunkcji, możesz użyć wyrażenia regularnego lub funkcji 'isalnum()' pytona. –

Odpowiedz

13

Jak zauważono w komentarzach, zacznij od sent_tokenize(), ponieważ word_tokenize() działa tylko w jednym zdaniu. Możesz odfiltrować interpunkcję za pomocą filtra(). A jeśli masz ciągi znaków Unicode, upewnij się, że jest to obiekt Unicode (a nie "Str" zakodowany za pomocą kodowania typu "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) 
+12

Większość złożoności związanej z tokenizatorem Penn Treebank ma związek z właściwą obsługą interpunkcji. Po co używać drogiego tokenizera, który dobrze obsługuje interpunkcja, jeśli chcesz tylko usunąć interpunkcję? – rmalouf

+2

'word_tokenize' to funkcja, która zwraca' [token dla wysłanego w sent_tokenize (tekst, język) dla tokena w _treebank_word_tokenize (wysłany)] '. Więc myślę, że twoja odpowiedź robi to, co robi nltk: używając 'sent_tokenize()' przed użyciem 'word_tokenize()'. Przynajmniej jest to dla nltk3. –

+2

@rmalouf, ponieważ nie potrzebujesz żetonów tylko po interpunkcji? Tak więc chcesz 'did' i' n't', ale nie '.' –

107

Zobacz inne opcje tokenizacji, które nltk zapewnia here. Na przykład, można zdefiniować tokenizera że wybiera sekwencje znaków alfanumerycznych jako tokenów i krople wszystkiego innego:

from nltk.tokenize import RegexpTokenizer 

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

wyjściowa:

['Eighty', 'seven', 'miles', 'to', 'go', 'yet', 'Onward'] 
+28

Pamiętaj, że jeśli użyjesz tej opcji, tracisz cechy języka naturalnego specjalne dla' word_tokenize', jak rozdzielanie skurczów. Możesz naiwnie podzielić się na wyrażenie '\ w +' bez potrzeby używania NLTK. – sffc

8

Właśnie używany następujący kod, który usuwa wszystkie znaki interpunkcyjne :

tokens = nltk.wordpunct_tokenize(raw) 

type(tokens) 

text = nltk.Text(tokens) 

type(text) 

words = [w.lower() for w in text if w.isalpha()] 
+1

dlaczego konwertowanie tokenów na tekst? – Sadik

4

używam tego kodu, aby usunąć znaki interpunkcyjne:

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 ") 

A jeśli chcesz sprawdzić, czy token jest ważny angielskie słowo lub nie, być może trzeba PyEnchant

Tutorial:

import enchant 
d = enchant.Dict("en_US") 
d.check("Hello") 
d.check("Helo") 
d.suggest("Helo") 
+0

Pamiętaj, że to rozwiązanie zabija skurcze. Dzieje się tak, ponieważ 'word_tokenize' używa standardowego tokenizera' TreebankWordTokenizer', który dzieli skurcze (np. 'Can't' to (' ca', 'n't'). Jednak' n't' nie jest alfanumeryczny i gubi się w tym procesie: –

25

Tak naprawdę nie potrzeba NLTK usunąć znaki interpunkcyjne. Możesz go usunąć za pomocą prostego pythona. Ciągów:

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

Albo dla Unicode:

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

a następnie wykorzystać ten ciąg w swoim tokenizera.

P.S. Moduł string ma kilka innych zestawów elementów, które można usunąć (np. Cyfry).

5

myślę, że trzeba jakiś dopasowywania wyrażeń regularnych (poniższy kod w Pythonie 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) 

wyjściowa:

['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'] 

powinien działać dobrze w większości przypadków, ponieważ usuwa interpunkcję jednocześnie zachowując tokeny typu "nie", których nie można uzyskać z tokenizatorów regex, takich jak wordpunct_tokenize.

7

Poniższy kod usunie wszystkie znaki interpunkcyjne oraz znaki nieliteryczne. Skopiowane z ich książki.

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) 

wyjście

['i', 'ca', 'do', 'this', 'now', 'because', 'i', 'so', 'tired', 'please', 'give', 'me', 'some', 'time', 'sd'] 
+3

Pamiętaj, że używając tej metody stracisz słowo "nie" w przypadkach "nie może" lub "nie", co może być bardzo ważne dla zrozumienia i klasyfikacji zdania. używając phrase.translate (string.maketrans ("", "",), chars_to_remove), gdzie chars_to_remove może być ".,":;!? " – MikeL

Powiązane problemy