Exploring Linguistic Features with spaCy

Exploring Linguistic Features with spaCy

Introduction

In this second article in our spaCy series, we’ll expand on spaCy’s core features by looking at advanced linguistic processing, including Part-of-speech (POS) tagging in greater detail), dependency parsing for understanding syntactic structure, and named entity recognition (NER) for extracting real-world objects, locations, etc.

These features are crucial for tasks like information extraction, text classification, and more complex text analytics. By understanding these linguistic elements, we can begin to unravel the complexities of human language and build smarter NLP applications. Whether you’re a beginner or an experienced practitioner, deepening your knowledge in these areas is essential for creating robust text analysis solutions. Let’s see how they work in practice.

POS Tagging Deep Dive

You’ve already seen a glimpse of how spaCy handles POS tags in our previous article. Now let’s take a closer look at part-of-speech tagging and its pivotal role in NLP. By analyzing the grammatical components of text, we can gain insights into sentence structure and word functions, which are fundamental for tasks such as text classification and information extraction.

POS tagging can be helpful in myriad scenarios. Knowing the distribution of parts of speech can sometimes help classify text by style or function. Likewise, identifying nouns and verbs in text can help isolate key concepts or actions. And that’s just for starters; the uses of linguistic feature identification in NLP tasks is limited quite literally only by your imagination.

This time we are going to use the Python library Tabulate alongside spaCy to be able to output our POS information in an easy-to-consume manner. Make sure both libraries are installed:

pip install spacy tabulate

Now let’s take a look at another spaCy script identifying POS along with its (better-looking) output.

import spacy
from tabulate import tabulate

nlp = spacy.load("en_core_web_sm")

text = "Apple is looking at buying a U.K. startup for $1 billion."
doc = nlp(text)

pos_output = [("Text\n----", "POS\n---", "TAG\n---", "Explanation\n-----------")]
for token in doc:
    pos_output.append((token.text, token.pos_, token.tag_, spacy.explain(token.tag_)))

print(tabulate(pos_output))

And here’s is our output:

-------  -----  ---  -----------------------------------------
Text     POS    TAG  Explanation
----     ---    ---  -----------
Apple    PROPN  NNP  noun, proper singular
is       AUX    VBZ  verb, 3rd person singular present
looking  VERB   VBG  verb, gerund or present participle
at       ADP    IN   conjunction, subordinating or preposition
buying   VERB   VBG  verb, gerund or present participle
a        DET    DT   determiner
U.K.     PROPN  NNP  noun, proper singular
startup  NOUN   NN   noun, singular or mass
for      ADP    IN   conjunction, subordinating or preposition
$        SYM    $    symbol, currency
1        NUM    CD   cardinal number
billion  NUM    CD   cardinal number
.        PUNCT  .    punctuation mark, sentence closer
-------  -----  ---  -----------------------------------------

This is far better than the generic unformatted output from spaCy, allowing us to get a better understanding of what’s being presented to us at a quick glance.

A short explanation of the important spaCy code above:

  • token.pos_ is the coarse-grained tag (e.g., NOUN, VERB)
  • token.tag_ is the fine-grained tag (e.g., VBG for a verb in the gerund or present participle)
  • spacy.explain(token.tag_) gives you a brief explanation of the tag

With the above short and simple code excerpt, spaCy demonstrates how powerful it can be when it comes to predicting what part of speech particular words are.

Dependency Parsing

Now let’s dive deeper into the mechanics of dependency parsing and its significance in understanding sentence structure. Dependency parsing reveals how words relate to each other in a sentence. By mapping the relationships between tokens, we can identify subject-object pairs and other grammatical dependencies, which are key to interpreting meaning in text. This process helps determine subject-object relationships, making it useful for tasks like question answering or information extraction. Dependency parsing also forms the backbone of many advanced NLP systems, leading to their deeper “understanding” of texts.

Here is an example we can append to the script from earlier:

dep_output = [("Text\n----", "DEP\n---", "Head Text\n---------", "Head Position\n-------------")]
for token in doc:
    dep_output.append((token.text, token.dep_, token.head.text, token.head.pos_))

print(tabulate(dep_output))

And the new output:

-------  --------  ---------  -------------
Text     DEP       Head Text  Head Position
----     ---       ---------  -------------
Apple    nsubj     looking    VERB
is       aux       looking    VERB
looking  ROOT      looking    VERB
at       prep      looking    VERB
buying   pcomp     at         ADP
a        det       U.K.       PROPN
U.K.     dobj      buying     VERB
startup  advcl     looking    VERB
for      prep      startup    NOUN
$        quantmod  billion    NUM
1        compound  billion    NUM
billion  pobj      for        ADP
.        punct     looking    VERB
-------  --------  ---------  -------------

Here’s what the spaCy attributes are doing:

  • token.dep_: The syntactic dependency label (e.g., nsubj, dobj, ROOT)
  • token.head: The token on which the current token is syntactically dependent

This is powerful understanding from a few lines of text.

Perhaps even more powerful, depending on your style of learning or understanding, you can also visualize dependency parsing with spaCy’s displaCy tool:

from spacy import displacy

displacy.serve(doc, style='dep', port=4200)

If you get this output:

Using the 'dep' visualizer
Serving on http://0.0.0.0:4200 ...

You should be able to open your browser to the address and port above and get this image:

XXX
Dependency parsing output via displaCy (click to enlarge)

This generates a simple diagram showing how tokens are linked in a sentence.

Named Entity Recognition

Named Entity Recognition detects real-world objects (entities) mentioned in text — such as persons, locations, organizations, and more. Let’s have a look at how identifying these entities can transform raw text into structured data. Recognizing names, dates, and places not only enhances information retrieval but also drives insights in diverse applications such as news analysis and customer sentiment tracking, as examples. By leveraging NER, you can bridge the gap between unstructured text and actionable intelligence.

Let’s add this to our existing script to see how spaCy predicts NERs.

ner_output = [("Text\n----", "Label\n-----", "Explanation\n-----------")]
for ent in doc.ents:
    ner_output.append((ent.text, ent.label_, spacy.explain(ent.label_)))
print(tabulate(ner_output))

Here’s our output:

Text        Label  Explanation
----        -----  -----------
Apple       ORG    Companies, agencies, institutions, etc.
U.K.        GPE    Countries, cities, states
$1 billion  MONEY  Monetary values, including unit
----------  -----  ---------------------------------------

And here’s what the spaCy attributes are and what they are doing:

  • ent.text: The textual representation of the entity
  • ent.label_: The label assigned by the model (e.g., PERSON, ORG, GPE)
  • spacy.explain(ent.label_): A short explanation of the label

spaCy’s pre-trained NER models can identify a wide range of entities. For domain-specific tasks (e.g., biomedical or legal text), you might consider training a custom model, which we’ll explore in later articles.

4. Applications in Real-World Tasks

How do theese discussed NLP techniques translate into practical applications? Understanding and applying POS tagging, dependency parsing, and named entity recognition can empower you to build systems that accurately extract, classify, and summarize text. These methods are the building blocks behind many real-world tools, from automated content summarization to intelligent information extraction systems.

Information extraction systems, for example, use POS tagging and dependency parsing to locate specific pieces of information (e.g., who did what to whom). Without these foundational techniques upon which to build, there would be no way to build these more complex NLP systems.

In text classification, entities can provide clues about the text’s topic or sentiment (e.g., frequent mentions of company names in news articles). Frequent mentions of athletes by name, along with team names, will indicate a sports article, while the mention of world leaders and capital cities, for instance, would more likely suggest that an article is politics-related.

Knowing the roles of words in a sentence can help produce more accurate summaries when considering content summarization. If a system cannot make out the difference between nouns, verbs, and prepositions, it would be ridiculous to think that it could then summarize what is happening in the text.

The usefulness of linguistic feature identification in systems knows no bounds. They are the foundation upon which every NLP system that can perform any task that we find to be helpful sits.

What’s Next?

Having mastered the intricacies of linguistic analysis, and having seen how spaCy’s linguistic features can enrich your text analytics, we can move onto preprocessing and feature engineering. Next time, we will explore how to transform text into numerical features that machine learning models can understand, and explore how to convert raw text into actionable data. Stay tuned.

Leave a Reply

Your email address will not be published. Required fields are marked *