2017-07-16 13 views
32

मैं अजगर में दो NLP-परियोजनाओं पर काम कर रहा हूँ, और दोनों समान कार्य की तरह वाक्य से मूल्यों और तुलना ऑपरेटरों को निकालने के लिए है:संख्या (तुलना विशेषण या श्रेणियों के साथ) निकालने के लिए कैसे

"... greater than $10 ... ", 
"... weight not more than 200lbs ...", 
"... height in 5-7 feets ...", 
"... faster than 30 seconds ... " 

मैंने देखा इस समस्या को हल करने के दो अलग-अलग तरीके, एक बहुत जटिल नियमित अभिव्यक्तियों का उपयोग करते हुए, और एनईआर (और कुछ regexes भी) का उपयोग कर।

मैं कैसे मान ऐसे वाक्य से बाहर पार्स कर सकते हैं? मुझे लगता है कि यह एनएलपी में एक आम काम है।


वांछित आउटपुट होगा कुछ की तरह:

इनपुट:

"से अधिक $ 10"

आउटपुट:

{'value': 10, 'unit': 'dollar', 'relation': 'gt', 'position': 3} 
+0

उपयोग CogComp-परिमाणक पैकेज: https: // GitHub।com/CogComp/cogcomp-nlp/पेड़/मास्टर/पाइपलाइन यह मात्रा निकालने और उनकी इकाइयों को सामान्यीकृत कर सकते हैं। – Daniel

+1

फेसबुक डकलिंग इस कार्य के लिए अच्छा है https://github.com/facebookincubator/duckling –

उत्तर

24

मैं शायद एक बेडौल कार्य के रूप में इस दृष्टिकोण और भाषण अपने नियमित अभिव्यक्ति chunker के साथ संयुक्त टैगर के nltk के भाग का प्रयोग करेंगे। यह आपको शब्दों के बजाए अपने वाक्यों में शब्दों के भाषण के हिस्से के आधार पर नियमित अभिव्यक्ति को परिभाषित करने की अनुमति देगा। दिए गए वाक्य लिए, आप निम्न कर सकते हैं:

import nltk 

# example sentence 
sent = 'send me a table with a price greater than $100' 

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

$10 -> 10 dollars 
200lbs -> 200 lbs 
5-7 -> 5 - 7 OR 5 to 7 

तो हम पाते हैं:

sent = 'send me a table with a price greater than 100 dollars' 

अब आप प्राप्त कर सकते हैं अपने वाक्य से बोलने के भाग:

sent_pos = nltk.pos_tag(sent.split()) 
print(sent_pos) 

[('send', 'VB'), ('me', 'PRP'), ('a', 'DT'), ('table', 'NN'), ('with', 'IN'), ('a', 'DT'), ('price', 'NN'), ('greater', 'JJR'), ('than', 'IN'), ('100', 'CD'), ('dollars', 'NNS')] 

अब हम एक chunker जो हिस्सा अपने पीओएस एक (अपेक्षाकृत) सरल नियमित अभिव्यक्ति के अनुसार पाठ में चिह्नित करेंगे बना सकते हैं:

grammar = 'NumericalPhrase: {<NN|NNS>?<RB>?<JJR><IN><CD><NN|NNS>?}' 
parser = nltk.RegexpParser(grammar) 

यह एक व्याकरण है कि संख्यात्मक वाक्यांश (क्या हम अपने वाक्यांश प्रकार फोन करता हूँ) मात्रा के साथ एक पार्सर परिभाषित करता है। एक वैकल्पिक संज्ञा, एक वैकल्पिक क्रिया विशेषण के बाद, एक तुलनात्मक विशेषण, एक पूर्वसर्ग, एक नंबर, और एक वैकल्पिक संज्ञा के बाद: यह के रूप में अपने संख्यात्मक वाक्यांश परिभाषित करता है। यह सिर्फ कैसे आप अपने वाक्यांशों परिभाषित करने के लिए चाहते हो सकता है के लिए एक सुझाव है, लेकिन मुझे लगता है कि इस शब्द स्वयं पर रेगुलर एक्सप्रेशन के उपयोग तुलना में बहुत सरल हो जाएगा।

अपने वाक्यांशों प्राप्त करने के लिए आप कर सकते हैं:

print(parser.parse(sent_pos)) 
(S 
    send/VB 
    me/PRP 
    a/DT 
    table/NN 
    with/IN 
    a/DT 
    (NumericalPhrase price/NN greater/JJR than/IN 100/CD dollars/NNS)) 

या केवल अपने वाक्यांशों आप कर सकते हैं पाने के लिए:

print([tree.leaves() for tree in parser.parse(sent_pos).subtrees() if tree.label() == 'NumericalPhrase']) 

[[('price', 'NN'), 
    ('greater', 'JJR'), 
    ('than', 'IN'), 
    ('100', 'CD'), 
    ('dollars', 'NNS')]] 
संबंधित मुद्दे