Skip to main content

Generic text classification library using Large Language Models with user-defined categories

Project description

Tagmatic - Generic Text Classification Library

Tagmatic Overview

[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Tagmatic is a flexible, user-defined text classification library that leverages Large Language Models (LLMs) to classify text into custom categories. Simply define your categories with descriptions, and Tagmatic handles all the complexity of prompt engineering and LLM interaction.

Key Features

  • User-Defined Categories: Define categories with simple names and descriptions
  • LLM Provider Agnostic: Works with any LangChain-compatible LLM
  • Voting Classifier: Run multiple classifications and use majority voting for improved accuracy
  • Batch Processing: Efficiently classify multiple texts at once
  • Type Safety: Full type hints throughout the codebase
  • Easy Integration: Simple API that requires minimal setup

📦 Installation

pip install tagmatic

🎯 Quick Start

from langchain_openai import ChatOpenAI
from tagmatic import Category, CategorySet, Classifier

# 1. Define your categories
categories = CategorySet(categories=[
    Category(
        name="positive",
        description="Text expressing positive emotions, satisfaction, or happiness",
        examples=["I love this!", "Great job!", "This is amazing!"]
    ),
    Category(
        name="negative", 
        description="Text expressing negative emotions, complaints, or dissatisfaction",
        examples=["I hate this", "This is terrible", "Very disappointed"]
    ),
    Category(
        name="neutral",
        description="Text that is factual or doesn't express strong emotions",
        examples=["The meeting is at 3 PM", "It's 72 degrees outside"]
    )
])

# 2. Initialize your LLM
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.1)

# 3. Create a classifier
classifier = Classifier(llm=llm, categories=categories)

# 4. Classify text
result = classifier.classify("I absolutely love this new feature!")
print(f"Category: {result.category}")  # Output: positive

# 5. Use voting for higher accuracy
voting_result = classifier.voting_classify(
    "This is amazing!", 
    voting_rounds=5
)
print(f"Category: {voting_result.category}")
print(f"Confidence: {voting_result.confidence}")
print(f"Vote distribution: {voting_result.vote_counts}")

🔧 Core Components

Categories

Categories are the foundation of Tagmatic. Each category consists of:

  • Name: A unique identifier for the category
  • Description: A clear description of what text belongs in this category
  • Examples (optional): Sample texts that belong to this category
from tagmatic import Category

category = Category(
    name="spam",
    description="Promotional content, advertisements, or repetitive messages",
    examples=[
        "Buy now! Limited time offer!",
        "Click here to win $1000!",
        "Make money fast with this one trick!"
    ]
)

CategorySet

A CategorySet manages a collection of categories and ensures they have unique names:

from tagmatic import CategorySet

categories = CategorySet(categories=[
    Category(name="urgent", description="Messages requiring immediate attention"),
    Category(name="normal", description="Regular messages that can be processed normally"),
    Category(name="low_priority", description="Messages that can be handled later")
])

# Access categories
print(categories.get_category_names())  # ['urgent', 'normal', 'low_priority']
urgent_cat = categories.get_category("urgent")

# Save/load categories
categories.save_to_file("my_categories.json")
loaded_categories = CategorySet.from_file("my_categories.json")

Classifier

The main interface for text classification:

from tagmatic import Classifier

# Basic classifier
classifier = Classifier(llm=llm, categories=categories)

# With structured output (includes confidence scores)
classifier = Classifier(
    llm=llm, 
    categories=categories,
    use_structured_output=True
)

# Single classification
result = classifier.classify("Hello world!")

# Batch classification
texts = ["Text 1", "Text 2", "Text 3"]
results = classifier.classify_batch(texts)

# Voting classification
voting_result = classifier.voting_classify(
    text="Ambiguous text here",
    voting_rounds=5
)

🗳️ Voting Classifier

The voting classifier is Tagmatic's "special sauce" - it runs the same classification multiple times and uses majority voting to improve accuracy:

# Run classification 5 times and use majority vote
result = classifier.voting_classify(
    text="This product is okay, I guess.",
    voting_rounds=5
)

print(f"Final category: {result.category}")
print(f"Confidence: {result.confidence}")  # Based on vote distribution
print(f"Individual votes: {result.votes}")  # ['neutral', 'positive', 'neutral', 'neutral', 'positive']
print(f"Vote counts: {result.vote_counts}")  # {'neutral': 3, 'positive': 2}
print(f"Unanimous: {result.is_unanimous}")  # False

Benefits of Voting:

  • Reduces classification errors
  • Provides confidence scoring
  • Handles edge cases better
  • Identifies ambiguous content

Best Practices:

  • Use odd numbers (3, 5, 7) to avoid ties
  • More rounds = higher confidence but slower performance
  • Monitor confidence scores to identify problematic content

🎨 Use Cases

Sentiment Analysis

sentiment_categories = CategorySet(categories=[
    Category("positive", "Positive emotions, satisfaction, happiness"),
    Category("negative", "Negative emotions, complaints, dissatisfaction"), 
    Category("neutral", "Factual or emotionally neutral content")
])

Content Moderation

moderation_categories = CategorySet(categories=[
    Category("safe", "Appropriate content following community guidelines"),
    Category("spam", "Promotional or repetitive content"),
    Category("inappropriate", "Content violating community guidelines"),
    Category("suspicious", "Potentially misleading or false information")
])

Customer Support

support_categories = CategorySet(categories=[
    Category("technical_issue", "Problems with product functionality"),
    Category("billing_question", "Questions about payments, invoices, or pricing"),
    Category("feature_request", "Suggestions for new features or improvements"),
    Category("general_inquiry", "General questions about products or services")
])

Topic Classification

topic_categories = CategorySet(categories=[
    Category("technology", "Content about software, hardware, or digital topics"),
    Category("sports", "Content about athletics, games, or competitions"),
    Category("politics", "Content about government, elections, or policy"),
    Category("entertainment", "Content about movies, music, or celebrities")
])

🔌 LLM Provider Support

Tagmatic works with any LangChain-compatible LLM:

OpenAI

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="gpt-3.5-turbo",  # or "gpt-4", "gpt-4-turbo"
    temperature=0.1,
    api_key="your-api-key"
)

Anthropic

from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(
    model="claude-3-sonnet-20240229",
    temperature=0.1,
    api_key="your-api-key"
)

Local Models

from langchain_community.llms import Ollama

llm = Ollama(model="llama2")

📊 Performance Tips

  1. Use Batch Classification: More efficient for multiple texts

    results = classifier.classify_batch(texts)  # Better than individual calls
    
  2. Optimize Temperature: Lower values (0.1-0.3) for consistent results

    llm = ChatOpenAI(temperature=0.1)  # More deterministic
    
  3. Cache Categories: Reuse CategorySet objects

    categories.save_to_file("categories.json")  # Save for reuse
    
  4. Monitor Confidence: Use voting for low-confidence cases

    result = classifier.classify(text)
    if not result.confidence or result.confidence < 0.8:
        # Use voting for uncertain cases
        result = classifier.voting_classify(text, voting_rounds=3)
    

🧪 Testing

Run the test suite:

# Install development dependencies
pip install tagmatic

# Run tests
pytest

# Run tests with coverage
pytest --cov=tagmatic --cov-report=html

📚 Examples

Check out the examples/ directory for more detailed examples:

  • basic_usage.py - Simple classification examples
  • complaints_classification_demo.py - Demonstration of a real world example where Tagmatic thrive. Advanced voting classifier usage

🤝 Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

This project was inspired by real-world experience in data processing and classification at scale. Special thanks to the LangChain community for providing the foundation that makes LLM provider agnosticism possible.


Made with ❤️ by Vitor Sampaio

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tagmatic-0.1.0.tar.gz (2.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tagmatic-0.1.0-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file tagmatic-0.1.0.tar.gz.

File metadata

  • Download URL: tagmatic-0.1.0.tar.gz
  • Upload date:
  • Size: 2.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for tagmatic-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c8e498862adc1345a2ec85c2e34bbbfcd1a35c0e45da76d0c1ecf79b4edfbe98
MD5 82224a7403a38189aa6fbb2ae26754e4
BLAKE2b-256 04665a387eac6f8590c3ff85f6b378923f3aa5942e400c4ab519bc7c4440892a

See more details on using hashes here.

File details

Details for the file tagmatic-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: tagmatic-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for tagmatic-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 99bab17174641cd1eca59f0638c1a1dbd022894c8f638dac65c676f49b50ed26
MD5 67e19f554bb8cd3025e192ec3f7c6200
BLAKE2b-256 dd8afb25bac986cc3ea43c6f10029d6385a9aada8da6f31376435b31ca046bca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page