2015-09-29 5 views
11

मैं पाइथन द्वारा निर्भरता पेड़ में दो शब्दों के बीच निर्भरता पथ खोजने का प्रयास करता हूं।पायथन में दो शब्दों के बीच सबसे कम निर्भरता पथ कैसे प्राप्त करें?

वाक्य

के लिए लोकप्रिय संस्कृति में

रोबोट वहाँ हमें अनबाउंड मानव एजेंसी के awesomeness की याद दिलाने के लिए कर रहे हैं।

मैं practnlptools (https://github.com/biplab-iitb/practNLPTools) का इस्तेमाल किया तरह निर्भरता पार्स परिणाम प्राप्त करने के:

nsubj(are-5, Robots-1) 
xsubj(remind-8, Robots-1) 
amod(culture-4, popular-3) 
prep_in(Robots-1, culture-4) 
root(ROOT-0, are-5) 
advmod(are-5, there-6) 
aux(remind-8, to-7) 
xcomp(are-5, remind-8) 
dobj(remind-8, us-9) 
det(awesomeness-12, the-11) 
prep_of(remind-8, awesomeness-12) 
amod(agency-16, unbound-14) 
amod(agency-16, human-15) 
prep_of(awesomeness-12, agency-16) 

जो भी (https://demos.explosion.ai/displacy/ से लिया चित्र) के बीच " enter image description here

पथ की लंबाई के रूप में देखे जा सकते हैं रोबोट "और" हैं "1 है," रोबोट "और" उत्कृष्टता "के बीच पथ की लंबाई 4.

मेरा प्रश्न निर्भरता पार्स परिणाम से ऊपर दिया गया है, मैं दो शब्दों के बीच निर्भरता पथ या निर्भरता पथ की लंबाई कैसे प्राप्त कर सकता हूं?

मेरे वर्तमान खोज परिणाम से, nltk की ParentedTree मदद करेगा?

धन्यवाद!

+0

हाय @ सेन, मैं nltk का उपयोग करके वाक्य के लिए एक समान वृक्ष संरचना कैसे प्राप्त कर सकता हूं? मेरे पास वर्तमान में कोई ग्रामर नहीं है, और 'पेड़बैंक' व्याकरण का उपयोग करके, मुझे कुछ शब्दों की त्रुटि देता है जो उत्पादन सूची में मौजूद नहीं हैं। धन्यवाद। – skadoosh

+0

@skadoosh Acutally, एनएलटीके का उपयोग करके ऐसी अच्छी प्रस्तुति मिल रही है मुश्किल है। मैं स्पासी का उपयोग करने का सुझाव देता हूं। – Sean

उत्तर

7

आपकी समस्या आसानी से एक ग्राफ समस्या के रूप में कल्पना की जा सकती है जहां हमें दो नोड्स के बीच सबसे छोटा रास्ता खोजना है।

ग्राफ में अपने निर्भरता पार्स को बदलने के लिए, हमें पहले इस तथ्य से निपटना होगा कि यह एक स्ट्रिंग के रूप में आता है। आप इस प्राप्त करना चाहते हैं:

'nsubj(are-5, Robots-1)\nxsubj(remind-8, Robots-1)\namod(culture-4, popular-3)\nprep_in(Robots-1, culture-4)\nroot(ROOT-0, are-5)\nadvmod(are-5, there-6)\naux(remind-8, to-7)\nxcomp(are-5, remind-8)\ndobj(remind-8, us-9)\ndet(awesomeness-12, the-11)\nprep_of(remind-8, awesomeness-12)\namod(agency-16, unbound-14)\namod(agency-16, human-15)\nprep_of(awesomeness-12, agency-16)' 

इस तरह देखने के लिए:

[('are-5', 'Robots-1'), ('remind-8', 'Robots-1'), ('culture-4', 'popular-3'), ('Robots-1', 'culture-4'), ('ROOT-0', 'are-5'), ('are-5', 'there-6'), ('remind-8', 'to-7'), ('are-5', 'remind-8'), ('remind-8', 'us-9'), ('awesomeness-12', 'the-11'), ('remind-8', 'awesomeness-12'), ('agency-16', 'unbound-14'), ('agency-16', 'human-15'), ('awesomeness-12', 'agency-16')] 

इस तरह आप networkx मॉड्यूल से एक ग्राफ निर्माता को टपल सूची फ़ीड कर सकते हैं कि सूची का विश्लेषण करेगा और एक ग्राफ का निर्माण आपके लिए, प्लस आपको एक साफ विधि प्रदान करता है जो आपको दो दिए गए नोड्स के बीच सबसे कम पथ की लंबाई देता है।

आवश्यक आयात

import re 
import networkx as nx 
from practnlptools.tools import Annotator 

वांछित टपल सूची प्रारूप में अपने स्ट्रिंग प्राप्त करने के लिए कैसे

annotator = Annotator() 
text = """Robots in popular culture are there to remind us of the awesomeness of unbound human agency.""" 
dep_parse = annotator.getAnnotations(text, dep_parse=True)['dep_parse'] 

dp_list = dep_parse.split('\n') 
pattern = re.compile(r'.+?\((.+?), (.+?)\)') 
edges = [] 
for dep in dp_list: 
    m = pattern.search(dep) 
    edges.append((m.group(1), m.group(2))) 

ग्राफ निर्माण कैसे

graph = nx.Graph(edges) # Well that was easy 

कैसे की गणना करने के कम से कम पथ की लंबाई

print(nx.shortest_path_length(graph, source='Robots-1', target='awesomeness-12')) 

यह स्क्रिप्ट, पता चलता है कि कम से कम पथ निर्भरता पार्स दिया लंबाई 2 की वास्तव में है जब से तुम remind-8

माध्यम से जा रहा द्वारा awesomeness-12 को Robots-1 से प्राप्त कर सकते हैं
1. xsubj(remind-8, Robots-1) 
2. prep_of(remind-8, awesomeness-12) 

यदि आपको यह परिणाम पसंद नहीं है, तो आप कुछ निर्भरताओं को फ़िल्टर करने के बारे में सोचना चाहेंगे, इस मामले में ग्राफ में xsubj निर्भरता को जोड़ने की अनुमति नहीं है।

4

ह्यूगोमेलॉटशॉट answer बहुत अच्छा है। मैं spacy उपयोगकर्ताओं के लिए कुछ समान लिखूंगा जो दो शब्दों के बीच सबसे कम निर्भरता पथ खोजना चाहते हैं (जबकि ह्यूगोमेलॉट का उत्तर practNLPTools पर निर्भर करता है)।

वाक्य:

लोकप्रिय संस्कृति में

रोबोट वहाँ हमें अनबाउंड मानव एजेंसी के awesomeness की याद दिलाने के लिए कर रहे हैं।

है following dependency tree:

import networkx as nx 
import spacy 
nlp = spacy.load('en') 

# https://spacy.io/docs/usage/processing-text 
document = nlp(u'Robots in popular culture are there to remind us of the awesomeness of unbound human agency.', parse=True) 

print('document: {0}'.format(document)) 

# Load spacy's dependency tree into a networkx graph 
edges = [] 
for token in document: 
    # FYI https://spacy.io/docs/api/token 
    for child in token.children: 
     edges.append(('{0}-{1}'.format(token.lower_,token.i), 
         '{0}-{1}'.format(child.lower_,child.i))) 

graph = nx.Graph(edges) 

# https://networkx.github.io/documentation/networkx-1.10/reference/algorithms.shortest_paths.html 
print(nx.shortest_path_length(graph, source='robots-0', target='awesomeness-11')) 
print(nx.shortest_path(graph, source='robots-0', target='awesomeness-11')) 
print(nx.shortest_path(graph, source='robots-0', target='agency-15')) 

आउटपुट::

4 
['robots-0', 'are-4', 'remind-7', 'of-9', 'awesomeness-11'] 
['robots-0', 'are-4', 'remind-7', 'of-9', 'awesomeness-11', 'of-12', 'agency-15'] 

enter image description here

यहाँ दो शब्दों के बीच कम से कम निर्भरता पथ को खोजने के लिए कोड है

sudo pip install networkx 
sudo pip install spacy 
sudo python -m spacy.en.download parser # will take 0.5 GB 

कुछ spacy की निर्भरता पार्स के बारे में मानक: https://spacy.io/docs/api/

enter image description here

1

इस उत्तर स्टैनफोर्ड CoreNLP पर निर्भर करता है एक वाक्य की निर्भरता पेड़ प्राप्त करने के लिए 03,210 spacy और networkx स्थापित करने के लिए। नेटवर्कक्स का उपयोग करते समय यह ह्यूगोमेलॉट के answer से काफी कुछ कोड उधार देता है।

कोड चलाने से पहले, एक की जरूरत के लिए:

  1. sudo pip install pycorenlp (स्टैनफोर्ड CoreNLP के लिए अजगर इंटरफेस)
  2. डाउनलोड Stanford CoreNLP
  3. एक स्टैनफोर्ड CoreNLP सर्वर प्रारंभ करें इस प्रकार है:

    java -mx4g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -port 9000 -timeout 50000 
    

फिर कोई भी कर सकता है दो शब्दों के बीच सबसे कम निर्भरता रास्ता ढूंढने के लिए निम्न कोड चलाएँ:

import networkx as nx 
from pycorenlp import StanfordCoreNLP 
from pprint import pprint 

nlp = StanfordCoreNLP('http://localhost:{0}'.format(9000)) 
def get_stanford_annotations(text, port=9000, 
          annotators='tokenize,ssplit,pos,lemma,depparse,parse'): 
    output = nlp.annotate(text, properties={ 
     "timeout": "10000", 
     "ssplit.newlineIsSentenceBreak": "two", 
     'annotators': annotators, 
     'outputFormat': 'json' 
    }) 
    return output 

# The code expects the document to contains exactly one sentence. 
document = 'Robots in popular culture are there to remind us of the awesomeness of'\ 
      'unbound human agency.' 
print('document: {0}'.format(document)) 

# Parse the text 
annotations = get_stanford_annotations(document, port=9000, 
             annotators='tokenize,ssplit,pos,lemma,depparse') 
tokens = annotations['sentences'][0]['tokens'] 

# Load Stanford CoreNLP's dependency tree into a networkx graph 
edges = [] 
dependencies = {} 
for edge in annotations['sentences'][0]['basic-dependencies']: 
    edges.append((edge['governor'], edge['dependent'])) 
    dependencies[(min(edge['governor'], edge['dependent']), 
        max(edge['governor'], edge['dependent']))] = edge 

graph = nx.Graph(edges) 
#pprint(dependencies) 
#print('edges: {0}'.format(edges)) 

# Find the shortest path 
token1 = 'Robots' 
token2 = 'awesomeness' 
for token in tokens: 
    if token1 == token['originalText']: 
     token1_index = token['index'] 
    if token2 == token['originalText']: 
     token2_index = token['index'] 

path = nx.shortest_path(graph, source=token1_index, target=token2_index) 
print('path: {0}'.format(path)) 

for token_id in path: 
    token = tokens[token_id-1] 
    token_text = token['originalText'] 
    print('Node {0}\ttoken_text: {1}'.format(token_id,token_text)) 

उत्पादन होता है:

document: Robots in popular culture are there to remind us of the awesomeness of unbound human agency. 
path: [1, 5, 8, 12] 
Node 1 token_text: Robots 
Node 5 token_text: are 
Node 8 token_text: remind 
Node 12 token_text: awesomeness 

ध्यान दें कि स्टैनफोर्ड CoreNLP ऑनलाइन परीक्षण किया जा सकता: http://nlp.stanford.edu:8080/parser/index.jsp

इस उत्तर परीक्षण किया गया था स्टैनफोर्ड कोरएनएलपी 3.6.0 के साथ, विंडोज 7 एसपी 1 एक्स 64 अल्टीमेट पर pycorenlp 0.3.0 और पायथन 3.5 x64।

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