cyberangles blog

How to Convert Simple Tense Verbs to Present, Past, or Past Participle Forms Using NLTK and WordNet: A Step-by-Step Guide

Verb conjugation—the process of modifying verbs to reflect tense, mood, or aspect—is a foundational aspect of English grammar. Whether you’re building a chatbot, developing a grammar-check tool, or processing text for NLP tasks, accurately converting verbs between tenses (present, past, past participle) is critical. Manually conjugating verbs, especially irregular ones (e.g., “eat” → “ate” → “eaten”), is error-prone and inefficient.

In this guide, we’ll explore how to automate verb conjugation using NLTK (Natural Language Toolkit) and WordNet, two powerful tools for natural language processing in Python. By the end, you’ll be able to convert simple tense verbs (base form) into their past tense and past participle forms, even handling many irregular verbs with ease.

2026-02

Table of Contents#

  1. Prerequisites
  2. Understanding Verb Conjugation Basics
  3. Overview of NLTK and WordNet
  4. Step-by-Step Guide to Conjugation
  5. Handling Irregular Verbs
  6. Limitations and Workarounds
  7. Practical Applications
  8. Conclusion
  9. References

Prerequisites#

Before diving in, ensure you have the following:

  • Python 3.x: Install from python.org.
  • Basic Python Knowledge: Familiarity with functions, dictionaries, and libraries.
  • NLTK Library: A Python toolkit for NLP. Install it via pip:
    pip install nltk  
  • WordNet: A lexical database for English (included in NLTK). Download it using NLTK’s downloader (see Step 1).

Understanding Verb Conjugation Basics#

English verbs have three primary forms relevant to this guide:

FormDefinitionExample (Regular Verb: “walk”)Example (Irregular Verb: “eat”)
Base (Present Simple)The root form (used for first/second person, plural: “I walk,” “they walk”).walkeat
Past TenseAction completed in the past: “She walked yesterday.”walkedate
Past ParticipleUsed with auxiliary verbs (e.g., “has,” “have”): “She has walked.”walkedeaten
  • Regular Verbs: Follow a pattern (base + “-ed” for past and past participle: “walk” → “walked” → “walked”).
  • Irregular Verbs: Do not follow “-ed” (e.g., “eat” → “ate” → “eaten”; “go” → “went” → “gone”).

Overview of NLTK and WordNet#

What is NLTK?#

The Natural Language Toolkit (NLTK) is a Python library for building NLP applications. It provides tools for tokenization, parsing, lemmatization, and more.

What is WordNet?#

WordNet is a lexical database for English, included in NLTK. It groups words into synonym sets (“synsets”) and provides semantic relationships (e.g., antonyms, hypernyms). For verbs, WordNet stores lemmas (base forms) and can help identify inflected forms (e.g., “running” → “run”).

Step-by-Step Guide to Conjugation#

In this section, we’ll use NLTK and WordNet to:

  1. Retrieve the base form of any verb.
  2. Generate past tense and past participle forms from the base.

Step 1: Set Up Your Environment#

First, install NLTK and download WordNet:

# Install NLTK (if not already installed)  
!pip install nltk  
 
# Import NLTK and download WordNet  
import nltk  
nltk.download('wordnet')  # WordNet lexical database  
nltk.download('averaged_perceptron_tagger')  # For part-of-speech tagging (optional)  
 
# Import required modules  
from nltk.corpus import wordnet as wn  
from nltk.stem import WordNetLemmatizer  

Step 2: Retrieve the Base Verb Form#

The base form (present simple) is the root of the verb (e.g., “running” → “run”). We use NLTK’s WordNetLemmatizer to extract the base form from any conjugated verb.

Code:#

# Initialize the lemmatizer  
lemmatizer = WordNetLemmatizer()  
 
def get_base_form(verb_form):  
    """Convert any verb form (e.g., 'ran', 'eating') to its base form."""  
    # Use WordNetLemmatizer with 'v' (verb) as the part-of-speech tag  
    base_form = lemmatizer.lemmatize(verb_form, pos='v')  
    return base_form  
 
# Examples  
print(get_base_form("running"))  # Output: run  
print(get_base_form("ate"))      # Output: eat  
print(get_base_form("written"))  # Output: write  

How It Works:#

WordNetLemmatizer.lemmatize() uses WordNet to map inflected verbs to their base lemmas. The pos='v' parameter ensures we treat the input as a verb.

Step 3: Identify Regular vs. Irregular Verbs#

To generate past and past participle forms, we first need to distinguish regular from irregular verbs:

  • Regular Verbs: Past/past participle = base + “-ed”.
  • Irregular Verbs: Require custom mappings (e.g., “eat” → “ate”).

We’ll use WordNet to check if a verb is regular by testing if the “-ed” form exists as a valid verb.

Code:#

def is_regular_verb(base_verb):  
    """Check if a base verb is regular (past/past participle = base + 'ed')."""  
    past_candidate = base_verb + "ed"  
    # Check if the "-ed" form exists as a verb in WordNet  
    return len(wn.synsets(past_candidate, pos=wn.VERB)) > 0  
 
# Examples  
print(is_regular_verb("walk"))  # Output: True (regular)  
print(is_regular_verb("eat"))   # Output: False (irregular)  
print(is_regular_verb("jump"))  # Output: True (regular)  

How It Works:#

wn.synsets(past_candidate, pos=wn.VERB) checks if the “-ed” form (e.g., “walked”) is a valid verb in WordNet. If it returns synsets (synonym sets), the verb is regular.

Step 4: Generate Past Tense and Past Participle#

With the base form and regularity check, we generate past tense and past participle forms.

4.1: Generate Past Tense#

For regular verbs, append “-ed” to the base. For irregular verbs, use a lookup table (see Section 5).

Code:#

def get_past_tense(base_verb, irregular_verbs=None):  
    """Generate past tense from the base verb."""  
    # Use irregular verbs dict if provided; else, use a default  
    irregular_verbs = irregular_verbs or {}  
 
    if base_verb in irregular_verbs:  
        return irregular_verbs[base_verb]["past"]  
    elif is_regular_verb(base_verb):  
        return base_verb + "ed"  
    else:  
        return f"Unknown past tense for '{base_verb}'. Add to irregular_verbs dict."  

4.2: Generate Past Participle#

Similarly, regular verbs use “-ed”, while irregular verbs require custom mappings.

Code:#

def get_past_participle(base_verb, irregular_verbs=None):  
    """Generate past participle from the base verb."""  
    irregular_verbs = irregular_verbs or {}  
 
    if base_verb in irregular_verbs:  
        return irregular_verbs[base_verb]["past_participle"]  
    elif is_regular_verb(base_verb):  
        return base_verb + "ed"  
    else:  
        return f"Unknown past participle for '{base_verb}'. Add to irregular_verbs dict."  

Full Example#

# Define a dictionary of common irregular verbs  
irregular_verbs = {  
    "eat": {"past": "ate", "past_participle": "eaten"},  
    "go": {"past": "went", "past_participle": "gone"},  
    "see": {"past": "saw", "past_participle": "seen"},  
    "run": {"past": "ran", "past_participle": "run"},  
    "write": {"past": "wrote", "past_participle": "written"},  
    "break": {"past": "broke", "past_participle": "broken"},  
}  
 
# Test with regular verb  
base_verb = "walk"  
print(f"Base: {base_verb}")  
print(f"Past Tense: {get_past_tense(base_verb, irregular_verbs)}")  # walked  
print(f"Past Participle: {get_past_participle(base_verb, irregular_verbs)}")  # walked  
 
# Test with irregular verb  
base_verb = "eat"  
print(f"\nBase: {base_verb}")  
print(f"Past Tense: {get_past_tense(base_verb, irregular_verbs)}")  # ate  
print(f"Past Participle: {get_past_participle(base_verb, irregular_verbs)}")  # eaten  
 
# Test with unrecognized verb (add to irregular_verbs dict)  
base_verb = "swim"  
print(f"\nBase: {base_verb}")  
print(f"Past Tense: {get_past_tense(base_verb, irregular_verbs)}")  # Unknown...  

Handling Irregular Verbs#

WordNet does not store all irregular verb forms (e.g., “ate” is not a lemma for “eat”). Thus, we use a lookup dictionary to map irregular verbs to their past and past participle forms.

Expand the Irregular Verbs Dictionary#

Add more entries to cover rare or domain-specific verbs:

irregular_verbs = {  
    # Common verbs  
    "be": {"past": "was/were", "past_participle": "been"},  
    "have": {"past": "had", "past_participle": "had"},  
    "do": {"past": "did", "past_participle": "done"},  
    "say": {"past": "said", "past_participle": "said"},  
    # Rare/technical verbs  
    "forbid": {"past": "forbade", "past_participle": "forbidden"},  
    "foresee": {"past": "foresaw", "past_participle": "foreseen"},  
}  

Limitations and Workarounds#

While NLTK and WordNet simplify conjugation, they have limitations:

1. Homonyms and Ambiguity#

Verbs with multiple meanings (homonyms) may be misclassified. For example:

  • “Lie” (to recline): Past = “lay”, Participle = “lain”.
  • “Lie” (to deceive): Past = “lied”, Participle = “lied”.

WordNet’s is_regular_verb("lie") returns True (since “lied” is a valid verb form), leading to incorrect results for “lie” (recline).

Workaround: Use context-aware POS tagging (e.g., NLTK’s pos_tag) to disambiguate meanings before conjugation.

2. Incomplete Irregular Verb Coverage#

WordNet does not list all irregular forms. For rare verbs (e.g., “shear” → “shore” → “shorn”), you must manually update the irregular_verbs dict.

Workaround: Use resources like EnglishClub’s Irregular Verbs List to expand the dictionary.

3. Over-Reliance on “-ed” for Regular Verbs#

Some regular verbs have spelling changes (e.g., “cry” → “cried”, “study” → “studied”). The current code appends “-ed” directly, which may fail for such verbs.

Workaround: Add logic to handle spelling rules (e.g., “y” → “ied” for consonant + “y” verbs).

Practical Applications#

  • Grammar Checkers: Automatically flag incorrect verb forms (e.g., “I have ate” → “I have eaten”).
  • Chatbots: Generate natural responses with properly conjugated verbs.
  • Text Summarization: Normalize verbs to their base form for consistent processing.
  • Language Learning Apps: Teach verb conjugation interactively.

Conclusion#

Verb conjugation is a cornerstone of English grammar, and automating it with NLTK and WordNet saves time and reduces errors. By combining WordNet’s lemmatization, regularity checks, and a custom irregular verb dictionary, you can efficiently convert verbs between present, past, and past participle forms.

While NLTK and WordNet have limitations (e.g., homonym ambiguity), they provide a robust foundation. For production-grade systems, consider augmenting with specialized libraries like pattern or spaCy, but for most use cases, this guide’s approach suffices.

References#