Natural Language Processing — Dependency Parsing | by Shivanee Jaiswal | Towards Data Science

Dependency Parsing is the process to analyze the grammatical structure in a sentence and find out related words as well as the type of the relationship between them.
Each relationship:
Has one head and a dependent that modifies the head.Is labeled according to the nature of the dependency between the head and the dependent. These labels can be found at Universal Dependency Relations.
Has one head and a dependent that modifies the head.
Is labeled according to the nature of the dependency between the head and the dependent. These labels can be found at Universal Dependency Relations.
In the above diagram, there exists a relationship between car and black because black modifies the meaning of car. Here, car acts as the head and black is a dependent of the head. The nature of the relationship here is amod which stands for “Adjectival Modifier”. It is an adjective or an adjective phrase that modifies a noun.
There are different ways to implement dependency parsing in Python. In this article, we will look at three ways.
spaCy is an open-source Python library for Natural Language Processing.
To get started, first install spaCy and load the required language model.
pip install -U pip setuptools wheelpip install -U spacypython -m spacy download en_core_web_sm
en_core_web_sm is the smallest English model available in spaCy with a size of 12MB. Refer spaCy English Models to view other available models.
spaCy also provides a built-in dependency visualizer called displaCy that you can use to generate dependency graph for sentences.
displacy.render() function will generate the visualization for the sentence.
Note: If you are running the code in Jupyter Notebook or Google Colab, use jupyter = True in render() function.
CoreNLP, created by Stanford NLP Group, provides NLP tools in Java. This Java library can be used with NLTK to parse dependencies in Python.
The first step is to download the Stanford CoreNLP zip file and Stanford CoreNLP model jar file from the CoreNLP website.
Running these three commands will download the required libraries and unzip the zip file.
wget https://nlp.stanford.edu/software/stanford-corenlp-4.2.2.zipwget https://nlp.stanford.edu/software/stanford-corenlp-4.2.2-models-english.jarunzip /content/stanford-corenlp-4.2.2.zip
Once these libraries are downloaded, we can import StanfordDependencyParser from NLTK.
from nltk.parse.stanford import StanfordDependencyParser
To visualize the dependency generated by CoreNLP, we can either extract a labeled and directed NetworkX Graph object using dependency.nx_graph() function or we can generate a DOT definition in Graph Description Language using dependency.to_dot() function. The DOT definition can be visualized as a graph using GraphViz.
Visualize using NetworkX
# importing networkximport networkx as nximport matplotlib.pyplot as plt# Using reverse() to reverse the direction of edges as nx_graph() returns inverted edgesG = dependency.nx_graph().reverse()# nx_graph() returns numeric node labels starting from 1# Create a dictionary to map numeric nodes and words in the sentencewords = sentence.split(" ")labels = {index + 1: words[index] for index in range(len(words))}nx.draw(G, with_labels=True, labels=labels, node_size=2500, node_color='#B5EAD7', font_size=10)
Visualize using DOT Definition
!pip install graphvizfrom graphviz import Sourcedot_def = dependency.to_dot()'''The below lines require graphviz executables to be installed to your system. If that does not work, print the dot_def object and paste the output on http://graphs.grevian.org/graph/'''source = Source(dot_def, filename="dependency_graph", format="png")source.view()
Stanford NLP Group have also developed Stanza. It provides a Neural Network NLP Pipeline that can be customized and a Python wrapper over Stanford CoreNLP package, making it easier to use the CoreNLP features without downloading the jar files.
To get started, install Stanza
pip install stanza
The next step is to import stanza and download the required language model. You can view all the available models here.
import stanzastanza.download('en')
Initialize the neural pipeline using stanza.Pipeline() function. The first parameter is the language to use. An optional parameter processors can be passed which can be a dictionary or a comma separated string to configure the processors to use in the pipeline.
nlp = stanza.Pipeline('en',                     processors = 'tokenize,mwt,pos,lemma,depparse')
You can find the list of all processors on Pipeline and Processors. Some of the processors might require to be preceded by some other processor in the pipeline, else they won’t work. For example, pos processor requires tokenizeand mwt processors, so we need to use these two processors in the pipeline as well if we want to use pos processor.
We will now pass our sentence through the pipeline and store all the results in doc variable.
doc = nlp(sentence)
If we print doc.sentences , we will see a list for each of the sentence that was passed through the pipeline. Each list contains result of all token information and linguistic features.
For example, each item in the list is an object with properties denoting lemma, universal part-of-speech, treebank-specific part-of-speech, morphological features, index of head, position in the sentence, etc.
{    "id": 1,   -----> index of word in the sentence, starting from 1    "text": "Deemed", -----> actual word    "lemma": "Deem",  -----> lemma of the word    "upos": "VERB", -----> universal POS    "xpos": "VBN", -----> treebank specific POS    "feats": "Tense=Past|VerbForm=Part",-----> morphological feature    "head": 2, -----> index of the head    "deprel": "amod", -----> dependency relationship nature    "start_char": 0, -----> start index of word in the sentence    "end_char": 6  -----> end index of word in the sentence}
For all the sentence in the doc object, we can call the print_dependencies() function. This function will print tuples with three values — the token, the index of the head and the relationship nature.
Note: In our case as we have only one sentence, we directly access it using doc.sentences[0]
Thus in this article, we saw three ways to implement dependency parsing for text in Python. Thank you for reading! :) You can connect with me on LinkedIn if you have questions about the implementation.
spaCy Dependency Parser — https://spacy.io/usage/linguistic-features#dependency-parseStanford CoreNLP — https://stanfordnlp.github.io/CoreNLP/index.htmlStanza Dependency Parser — https://stanfordnlp.github.io/stanza/depparse.html
spaCy Dependency Parser — https://spacy.io/usage/linguistic-features#dependency-parse
Stanford CoreNLP — https://stanfordnlp.github.io/CoreNLP/index.html
Stanza Dependency Parser — https://stanfordnlp.github.io/stanza/depparse.html