2012-12-30 31 views
29

मैं कुछ क्लासिक ग्रंथों का विश्लेषण करने के लिए एनएलटीके का उपयोग कर रहा हूं और मैं वाक्य द्वारा पाठ को टोकन करने में परेशानी में हूं। उदाहरण के लिए, यहाँ है कि मैं क्या Moby Dick से एक टुकड़ा के लिए प्राप्त होते हैं:एनएलटीके वाक्य टोकनेज़र को कैसे ट्विक करें

import nltk 
sent_tokenize = nltk.data.load('tokenizers/punkt/english.pickle') 

''' 
(Chapter 16) 
A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but 
that's a rather cold and clammy reception in the winter time, ain't it, Mrs. Hussey?" 
''' 
sample = 'A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but that\'s a rather cold and clammy reception in the winter time, ain\'t it, Mrs. Hussey?"' 

print "\n-----\n".join(sent_tokenize.tokenize(sample)) 
''' 
OUTPUT 
"A clam for supper? 
----- 
a cold clam; is THAT what you mean, Mrs. 
----- 
Hussey? 
----- 
" says I, "but that\'s a rather cold and clammy reception in the winter time, ain\'t it, Mrs. 
----- 
Hussey? 
----- 
" 
''' 

मैं पूर्णता यहाँ उम्मीद नहीं है, यह देखते हुए कि मेलविल के वाक्य रचना थोड़ा दिनांकित है, लेकिन NLTK टर्मिनल दोहरे उद्धरण चिह्नों को संभालने के लिए सक्षम होना चाहिए और "श्रीमती" जैसे खिताब चूंकि टोकननाइज़र एक अप्रसन्न प्रशिक्षण अलगो का परिणाम है, हालांकि, मैं यह नहीं समझ सकता कि इसके साथ टिंकर कैसे करें।

किसी के पास बेहतर वाक्य टोकनेज़र के लिए सिफारिशें हैं? मैं एक साधारण ह्युरिस्टिक पसंद करूंगा कि मैं अपने खुद के पार्सर को प्रशिक्षित करने के बजाय हैक कर सकता हूं।

उत्तर

40

आप tokenizer को संक्षिप्त रूपों की एक सूची की आपूर्ति करने, इसलिए तरह की जरूरत है:

from nltk.tokenize.punkt import PunktSentenceTokenizer, PunktParameters 
punkt_param = PunktParameters() 
punkt_param.abbrev_types = set(['dr', 'vs', 'mr', 'mrs', 'prof', 'inc']) 
sentence_splitter = PunktSentenceTokenizer(punkt_param) 
text = "is THAT what you mean, Mrs. Hussey?" 
sentences = sentence_splitter.tokenize(text) 

वाक्य है:

['is THAT what you mean, Mrs. Hussey?'] 

अद्यतन: यह काम नहीं करता है अगर वाक्य के अंतिम शब्द में एस्ट्रोफ़ेफ़ या उसके साथ जुड़ा उद्धरण चिह्न है (जैसे हसी? ')। तो यह चारों ओर एक त्वरित और गंदा तरीका अक्षर लोप और उद्धरण उस वाक्य के अंत में प्रतीकों का पालन के सामने रिक्त स्थान डाल करने के लिए है (।!?):

text = text.replace('?"', '? "').replace('!"', '! "').replace('."', '. "') 
+0

से ऊपर के साथ इस उत्तर का समेकित हिस्सा आह, जानना अच्छा है। आश्चर्यजनक रूप से, यह काम नहीं करता है अगर मैं आपके समाधान में अपने प्रश्न में पूरी वाक्य चलाता हूं। कोई विचार क्यों? –

+0

बस उत्तर में कुछ और जानकारी जोड़ा गया। – vpekar

+3

मैं आम तौर पर 'धन्यवाद' टिप्पणियों से बचता हूं, लेकिन यहां वास्तव में यह जगह है: धन्यवाद! – Private

7

आप PunktSentenceTokenizer.tokenize विधि को realign_boundaries पैरामीटर True पर realign_boundaries पैरामीटर सेट करके शेष वाक्य के साथ "टर्मिनल" डबल कोट्स को शामिल करने के लिए बता सकते हैं। उदाहरण के लिए नीचे दिए गए कोड को देखें।

मुझे Mrs. Hussey जैसे पाठ को दो वाक्यों में विभाजित करने से रोकने के लिए एक साफ तरीका नहीं पता है। हालांकि, यहां एक हैक जो

  • Mrs._Hussey को Mrs. Hussey की सभी घटनाओं mangles,
  • तो वाक्य में पाठ sent_tokenize.tokenize साथ विभाजन,
  • प्रत्येक वाक्य तो
  • है, Mrs._Hussey unmangles Mrs. Hussey
करने के लिए वापस

मेरी इच्छा है कि मैं एक बेहतर तरीका जानता हूं, लेकिन यह चुटकी में काम कर सकता है।


import nltk 
import re 
import functools 

mangle = functools.partial(re.sub, r'([MD]rs?[.]) ([A-Z])', r'\1_\2') 
unmangle = functools.partial(re.sub, r'([MD]rs?[.])_([A-Z])', r'\1 \2') 

sent_tokenize = nltk.data.load('tokenizers/punkt/english.pickle') 

sample = '''"A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but that\'s a rather cold and clammy reception in the winter time, ain\'t it, Mrs. Hussey?"'''  

sample = mangle(sample) 
sentences = [unmangle(sent) for sent in sent_tokenize.tokenize(
    sample, realign_boundaries = True)]  

print u"\n-----\n".join(sentences) 

पैदावार

"A clam for supper? 
----- 
a cold clam; is THAT what you mean, Mrs. Hussey?" 
----- 
says I, "but that's a rather cold and clammy reception in the winter time, ain't it, Mrs. Hussey?" 
+0

देखें जो मुझे चाहिए - धन्यवाद! –

+0

अद्यतन: –

2

तो मैं ने वही समस्या थी और vpekar के समाधान की कोशिश की ऊपर।

शायद मेरा कुछ प्रकार का एज केस है, लेकिन मैंने प्रतिस्थापन लागू करने के बाद एक ही व्यवहार देखा, हालांकि, जब मैंने विराम चिह्न को उनके सामने रखे उद्धरणों के साथ बदलने की कोशिश की, तो मुझे वह आउटपुट मिला जो मैं ढूंढ रहा था। मूल वाक्य को एक वाक्य के रूप में बनाए रखने की तुलना में आम तौर पर विधायक के अनुपालन की कमी कम महत्वपूर्ण है।

अधिक स्पष्ट है:

text = text.replace('?"', '"?').replace('!"', '"!').replace('."', '".') 

तो विधायक महत्वपूर्ण है कि आप कभी भी वापस जाकर जहां कहीं भी मायने रखता है इन परिवर्तनों को उल्टा कर सकते हैं।

24

आप एनएलटीके के पूर्व-प्रशिक्षित अंग्रेजी वाक्य टोकनेज़र को संशोधित कर सकते हैं ताकि उन्हें _params.abbrev_types पर जोड़कर अधिक संक्षेपों को पहचान सकें।

extra_abbreviations = ['dr', 'vs', 'mr', 'mrs', 'prof', 'inc', 'i.e'] 
sentence_tokenizer = nltk.data.load('tokenizers/punkt/english.pickle') 
sentence_tokenizer._params.abbrev_types.update(extra_abbreviations) 

ध्यान दें कि संक्षिप्त रूपों अंतिम अवधि के बिना निर्दिष्ट किया जाना चाहिए, लेकिन इसके बाद के संस्करण 'i.e' में के रूप में किसी भी आंतरिक अवधि शामिल है: उदाहरण के लिए। अन्य टोकनेज़र पैरामीटर के बारे में विवरण के लिए, the relevant documentation.

+1

देखें यह शीर्ष उत्तर होना चाहिए। यदि आप अभी एक नया टोकननाइज़र बनाते हैं तो आपको अंग्रेजी टोकननाइज़र की सभी मौजूदा सुविधाएं नहीं मिलेंगी। –

+0

यह मेरे लिए काम नहीं कर रहा था, जबकि शीर्ष जवाब किया था। – Alter

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^