NLTK 토크 나이저를 사용하여 구두점을 제거하는 방법은 무엇입니까?


125

방금 NLTK를 사용하기 시작했는데 텍스트에서 단어 목록을 얻는 방법을 잘 모르겠습니다. 을 사용하면 nltk.word_tokenize()단어 목록과 구두점을 얻습니다. 대신 단어 만 필요합니다. 구두점을 제거하려면 어떻게해야합니까? 또한 word_tokenize여러 문장에서 작동하지 않습니다. 점이 마지막 단어에 추가됩니다.


12
구두점을 직접 제거하지 않으시겠습니까? nltk.word_tokenize(the_text.translate(None, string.punctuation))python3에서 할 수있는 동안 python2에서 작동해야합니다 nltk.work_tokenize(the_text.translate(dict.fromkeys(string.punctuation))).
Bakuriu 2013 년

3
이것은 작동하지 않습니다. 텍스트에는 아무 일도 일어나지 않습니다.
lizarisk 2013 년

NLTK에서 가정하는 워크 플로는 먼저 문장으로 토큰 화 한 다음 모든 문장을 단어로 토큰 화하는 것입니다. 그렇기 때문에 word_tokenize()여러 문장에서 작동하지 않습니다. 구두점을 없애기 위해 정규식이나 파이썬의 isalnum()함수를 사용할 수 있습니다 .
Suzana 2013 년

2
그것은 않습니다 : 일 >>> 'with dot.'.translate(None, string.punctuation) 'with dot'(주 더 결과의 끝에 점)는 같은 것들이있는 경우에이 문제가 발생할 수 'end of sentence.No space'있는 경우에 대신이 작업을 수행 : the_text.translate(string.maketrans(string.punctuation, ' '*len(string.punctuation)))공백 모든 문장을 대체하는합니다.
Bakuriu 2013 년

죄송합니다. 실제로 작동하지만 유니 코드 문자열에서는 작동하지 않습니다.
lizarisk 2013 년

답변:


162

nltk가 여기에서 제공하는 다른 토큰 화 옵션을 살펴 보십시오 . 예를 들어 일련의 영숫자 문자를 토큰으로 선택하고 나머지는 모두 삭제하는 토크 나이저를 정의 할 수 있습니다.

from nltk.tokenize import RegexpTokenizer

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

산출:

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

55
이 옵션을 사용하면 word_tokenize축약 분할과 같은 특별한 자연어 기능을 잃게됩니다 . \w+NLTK 없이도 정규식에서 순진하게 분할 할 수 있습니다 .
sffc

3
@sffc 주석을 설명하기 위해 "Mr."과 같은 단어가 손실 될 수 있습니다.
geekazoid

'n't'를 't'로 대체하는 방법은 무엇입니까?
Md. Ashikur Rahman

46

구두점을 제거하기 위해 NLTK가 필요하지 않습니다. 간단한 파이썬으로 제거 할 수 있습니다. 문자열의 경우 :

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

또는 유니 코드의 경우 :

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

그런 다음 토크 나이저에서이 문자열을 사용합니다.

PS 문자열 모듈에는 제거 할 수있는 다른 요소 세트 (예 : 숫자)가 있습니다.


3
또한 작동하는 목록 표현식을 사용하여 모든 구두점을 제거하십시오. a = "*fa,fd.1lk#$" print("".join([w for w in a if w not in string.punctuation]))
Johnny Zhang

32

아래 코드는 모든 문장 부호와 알파벳이 아닌 문자를 제거합니다. 그들의 책에서 복사했습니다.

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)

산출

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

17
이 방법을 사용하면 문장을 이해하고 분류하는 데 매우 중요 할 수있는 "할 수 없음"또는 "하지 않음"과 같은 경우에 "not"이라는 단어를 잃게됩니다. sentence.translate (string.maketrans ( "", "",), chars_to_remove)를 사용하는 것이 더 좋습니다. 여기서 chars_to_remove는 "., ':;!?"가 될 수 있습니다.
MikeL

3
@MikeL tokanizing 전에 import contractions 및 contractions.fix (sentence_here)로 "할 수 없습니다"및 "하지 마십시오"와 같은 단어를 사용할 수 없습니다. "할 수 없음"을 "할 수 없음"으로, "하지 않음"을 "하지 않음"으로 바꿉니다.
zipline86

16

주석에서 알 수 있듯이 word_tokenize ()는 단일 문장에서만 작동하기 때문에 sent_tokenize ()로 시작합니다. filter ()를 사용하여 구두점을 필터링 할 수 있습니다. 그리고 만약 당신이 유니 코드 문자열을 가지고 있다면 그것이 유니 코드 객체인지 확인하십시오 ( 'utf-8'과 같은 인코딩으로 인코딩 된 'str'이 아님).

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)

14
Penn Treebank 토크 나이저와 관련된 대부분의 복잡성은 적절한 구두점 처리와 관련이 있습니다. 구두점 만 제거하려는 경우 구두점을 잘 처리하는 값 비싼 토크 나이저를 사용하는 이유는 무엇입니까?
rmalouf 2013 년

3
word_tokenize을 반환하는 함수입니다 [token for sent in sent_tokenize(text, language) for token in _treebank_word_tokenize(sent)]. 그래서 나는 당신의 대답이 nltk가 이미하는 일을하고 있다고 생각합니다 : using sent_tokenize()before using word_tokenize(). 적어도 이것은 nltk3입니다.
Kurt Bourbaki

2
구두점 전용 토큰이 필요하지 않기 때문에 @rmalouf? 당신이 원하는 그래서 did하고 n't있지만.
치프 리안 Tomoiagă

11

방금 다음 코드를 사용하여 모든 구두점을 제거했습니다.

tokens = nltk.wordpunct_tokenize(raw)

type(tokens)

text = nltk.Text(tokens)

type(text)  

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

2
왜 토큰을 텍스트로 변환합니까?
Sadik

6

일종의 정규식 일치가 필요하다고 생각합니다 (다음 코드는 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)

산출:

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

"n't"와 같은 토큰을 보존하면서 구두점을 제거하기 때문에 대부분의 경우 잘 작동합니다 wordpunct_tokenize. 이는와 같은 정규식 토크 나이저에서 얻을 수 없습니다 .


이것은 또한 같은 것들을 제거 ...하고 --있는이 보존 수축하면서 s.translate(None, string.punctuation)하지 않습니다
CJ 잭슨

5

진심으로 묻는다, 단어는 무엇입니까? 단어가 알파벳 문자로만 구성되어 있다고 가정하는 경우 , 토큰 화 전에 구두점을 제거하면와 같은 단어 can't가 조각으로 파괴되므로 (예 : cant) 프로그램에 부정적인 영향을 미칠 가능성이 큽니다.

따라서 해결책은 구두점 토큰을 토큰 화 한 다음 제거하는 것 입니다.

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

... 원하는 경우,와 같은 특정 토큰 'mam.


4

이 코드를 사용하여 구두점을 제거합니다.

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

그리고 토큰이 유효한 영어 단어인지 확인하려면 PyEnchant 가 필요할 수 있습니다.

지도 시간:

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

2
이 솔루션은 수축을 죽입니다. 그 때문에 word_tokenize사용 표준 토크 나이, TreebankWordTokenizer그 분할 수축 (예 can't에 ( ca, n't) 그러나. n't영숫자 아닌 그 과정에서 손실됩니다.
디에고 페라이트

1

구두점 제거 (아래 코드를 사용하여 구두점 처리의 일부뿐만 아니라.도 제거합니다)

        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 

샘플 입력 / 출력 :

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

@rmalouf로 솔루션에 추가하기 만하면 \ w +가 [a-zA-Z0-9_]와 같기 때문에 숫자가 포함되지 않습니다.

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

이것은 각 문자에 대해 하나의 토큰을 생성합니다.
Rishabh Gupta

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.