Python 如何使用NLTK标记器去除标点符号?

Python 如何使用NLTK标记器去除标点符号?,python,nlp,tokenize,nltk,Python,Nlp,Tokenize,Nltk,我刚刚开始使用NLTK,我不太明白如何从文本中获取单词列表。如果我使用nltk.word\u tokenize(),我会得到一个单词和标点的列表。我只需要这些词。我怎样才能去掉标点符号?另外,word\u tokenize不适用于多个句子:点将添加到最后一个单词。如注释中所述,以sent\u tokenize()开头,因为word\u tokenize()只适用于单个句子。您可以使用filter()过滤掉标点符号。如果您有一个unicode字符串,请确保它是一个unicode对象(而不是使用诸如

我刚刚开始使用NLTK,我不太明白如何从文本中获取单词列表。如果我使用
nltk.word\u tokenize()
,我会得到一个单词和标点的列表。我只需要这些词。我怎样才能去掉标点符号?另外,
word\u tokenize
不适用于多个句子:点将添加到最后一个单词。

如注释中所述,以sent\u tokenize()开头,因为word\u tokenize()只适用于单个句子。您可以使用filter()过滤掉标点符号。如果您有一个unicode字符串,请确保它是一个unicode对象(而不是使用诸如“utf-8”之类的编码编码的“str”)


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

我刚刚使用了以下代码,删除了所有标点符号:

tokens = nltk.wordpunct_tokenize(raw)

type(tokens)

text = nltk.Text(tokens)

type(text)  

words = [w.lower() for w in text if w.isalpha()]
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 ")

我使用以下代码删除标点符号:

tokens = nltk.wordpunct_tokenize(raw)

type(tokens)

text = nltk.Text(tokens)

type(text)  

words = [w.lower() for w in text if w.isalpha()]
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 ")
如果您想检查令牌是否是有效的英语单词,您可能需要

教程:

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

删除标点符号并不需要NLTK。您可以使用简单的python删除它。对于字符串:

import string
s = '... some string with punctuation ...'
s = s.translate(None, string.punctuation)
或对于unicode:

import string
translate_table = dict((ord(char), None) for char in string.punctuation)   
s.translate(translate_table)
然后在标记器中使用此字符串


p.S.字符串模块还有一些可以删除的元素集(如数字)。

我认为您需要某种正则表达式匹配(以下代码在Python 3中):

导入字符串
进口稀土
导入nltk
s=“我现在不能这样做,因为我太累了。请给我一些时间。”
l=nltk.word\u标记化
ll=[x代表l中的x,如果不是re.fullmatch('['+string.标点符号+']+',x)]
印刷品(l)
打印(ll)
输出:

['Eighty', 'seven', 'miles', 'to', 'go', 'yet', 'Onward']
['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”这样的标记,而“n't”不能从正则表达式标记器(如下面的
wordpunct_tokenize
)中获得。代码将删除所有标点符号以及非字母字符。抄袭他们的书

输出

['i', 'ca', 'do', 'this', 'now', 'because', 'i', 'so', 'tired', 'please', 'give', 'me', 'some', 'time', 'sd']
删除点状符号(它将删除。以及使用以下代码处理的部分标点符号)

输入/输出示例:

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','地毯','rate','14500','final','plus','1','floor','rise','tax','About','9','flat','cost','parking','389','cr','plus','taxes','sPlus','Poverage','middle','floor','north','door','arey','oberoi woods','Fa“到期”、“1”、“转让”、“费用”、“买方”、“总计”、“成本”、“大约”、“420”、“cr”、“大约”、“加上”、“占有”、“费用”、“rahul”、“soni”]

诚恳地问,什么是单词?如果你的假设是一个单词只由字母组成,那么你就错了,因为像
不能
这样的单词会被销毁成碎片(比如
可以
t
如果在标记化之前删除标点符号,很可能会对程序产生负面影响

因此,解决方案是标记化,然后删除标点符号

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

…然后,如果您愿意,您可以用
am
替换某些令牌,例如
'm
,只需通过@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!')

不用nltk(Python3.x),您可以在一行中完成


你为什么不自己删除标点符号呢?
nltk.word\u标记化(the\u text.translate(None,string.percentration))
应该在python2中工作,而在python3中你可以执行
nltk.work\u标记化(the\u text.translate(dict.fromkeys(string.percentration)))
。这不起作用。文本不会发生任何变化。NLTK假设的工作流程是先将每个句子标记为句子,然后将每个句子标记为单词。这就是为什么
word\u tokenize()
不能处理多个句子的原因。要去除标点符号,可以使用正则表达式或python的
isalnum()
函数。它确实起作用:
>>“带点”。.translate(无,string.标点符号)“带点”
(注意结果末尾没有点)如果您有
“句尾.无空格”
,则可能会导致问题,在这种情况下,请改为:
文本.translate(string.maketrans(string.标点符号),*len(string.标点符号))
它用空格替换所有标点符号方法与Unicode一起工作。Penn Treebank标记器涉及的大部分复杂性与正确处理标点有关。如果您只想去掉标点,为什么要使用处理标点的昂贵标记器呢?
word\u tokenize
是一个返回
[token for sent in sent\u tokenize]的函数(文本,语言)用于_treebank\u word\u tokenize(sent)]
。因此,我认为您的答案是在使用
word\u tokenize()之前先使用
sent\u tokenize()
。至少这是针对nltk3的。@rmalouf因为你不需要标点符号,所以你想要
did
n
但不是
注意,如果你使用这个选项,你会失去
word\u标记化
所特有的自然语言功能,比如拆分收缩。你可以在正则表达式上天真地拆分
>\w+
不需要NLTK。为了说明@sffc注释,您可能会丢失诸如“Mr”之类的单词。它将“t”替换为“t”如何消除此问题?为什么要将标记转换为文本?请注意,使用此方法时,在“不能”或“不”等情况下,您将丢失“not”一词,这对理解和分类句子可能非常重要。最好使用句子。翻译(string.maketrans(“,”),chars_to_remove),其中chars_to_remove可以是“,:;!?”@MikeL你不能通过导入缩略来避开像“不能”和“不”这样的词