NLTKトークナイザーを使用して句読点を取り除く方法は?


125

私はNLTKを使い始めたばかりで、テキストから単語のリストを取得する方法がよくわかりません。を使用するとnltk.word_tokenize()、単語と句読点のリストが表示されます。代わりに言葉だけが必要です。句読点を取り除くにはどうすればよいですか?またword_tokenize、複数の文では機能しません。ドットは最後の単語に追加されます。


12
句読点を自分で削除してみませんか?nltk.word_tokenize(the_text.translate(None, string.punctuation))python2では動作するはずですが、python3では動作しますnltk.work_tokenize(the_text.translate(dict.fromkeys(string.punctuation)))
Bakuriu 2013年

3
これは機能しません。テキストは何も起こりません。
lizarisk 2013年

NLTKが想定するワークフローでは、最初に文にトークン化し、次にすべての文を単語にトークン化します。これがword_tokenize()、複数の文では機能しない理由です。句読点を取り除くには、正規表現またはpythonの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年

おっと、実際には機能しますが、Unicode文字列では機能しません。
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 2015

3
@sffcコメントを説明するために、「Mr。」などの単語を失う可能性があります。
geekazoid

'n't'から 't'への置き換えは、これを取り除く方法ですか?
Ashikur Ra​​hman氏

46

句読点を削除するためにNLTKは実際には必要ありません。シンプルなpythonで削除できます。文字列の場合:

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]))
ジョニー・チャン

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
この方法を使用すると、「できない」または「できない」などの場合に「しない」という単語が失われることに注意してください。これは、文の理解と分類に非常に重要な場合があります。これは、sentence.translate(string.maketrans( ""、 ""、)、chars_to_remove)を使用することをお勧めします。chars_to_removeは "。、 ':;!?"にすることができます。
MikeL 2017

3
@MikeLトカナイズする前に、contractionsとcontractions.fix(sentence_here)をインポートすることで、「できない」や「できない」などの単語を回避することはできません。「できない」を「できない」に、「しない」を「しない」に変えます。
zipline86

16

コメントで気づいたように、word_tokenize()は1つの文でのみ機能するため、sent_tokenize()で始まります。filter()を使用して句読点を除外できます。また、Unicode文字列がある場合は、それがUnicodeオブジェクトであることを確認してください(「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がすでに行っていることをやっていると思います:を使うsent_tokenize()前に使うword_tokenize()。少なくともこれはnltk3用です。
カートブルバキ2015年

2
@rmalouf句読点のみのトークンが必要ないためですか?あなたがしたいので、didn'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
トークンをテキストに変換する理由
サディク

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などの単語が(canおよびなど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']

...そして、あなたが望むなら、次のような特定のトークンを置き換えることができます'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に(can'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!')

これは、文字ごとに1つのトークンを作成します。
リシャブグプタ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.