Skip to content

zacthinks/InteractiveTopicModel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Interactive Topic Model (ITM)

PyPI License: MIT Python Version

An interactive topic modeling framework inspired by BERTopic and designed for iterative refinement and human-in-the-loop validation. The goal is to enable better exploration of data with natural language processing tools and made accessible via a user-friendly interface. See below for details.

Features

  • Single-line functions: Perform complex operations with minimal coding skills required
  • Interactive visualizations: Explore text data quickly and intuitively
  • Interactive topic refinement: Split topics, merge topics, manually reassign documents
  • Hierarchical structures: Create topic hierarchies via splitting or grouping operations with support for multiple embedding spaces
  • Semantic search: Find documents with similar meanings without relying on them using the same words
  • Preview-then-commit workflow: Preview topic splits before committing changes
  • Full undo/redo support: Track and reverse all modeling operations
  • Document validation: Mark high-confidence assignments and optionally freeze them during refitting
  • Representative documents: Automatically identifies most representative documents for each topic
  • Rich topic metadata: Auto-generated labels, top terms via c-TF-IDF, centroid embeddings
  • Flexible scoring: Multiple modes for document-topic similarity (embedding, TF-IDF, harmonic mean)

Quick Start

Installation

pip install interactive-topic-model

Basic Use

Refer to vignette for more details.

import pandas as pd
from interactive_topic_model import InteractiveTopicModel

# Prepare your documents
texts = [
    "Machine learning is a subset of artificial intelligence...",
    "Deep neural networks have revolutionized computer vision...",
    # ... more documents
]

# Initialize model
itm = InteractiveTopicModel(texts)

# Fit initial model
itm.fit()

# View topic summary
print(itm.get_topic_info())

# Access individual topics
topic = itm.topics[0]
print(f"Topic {topic.topic_id}: {topic.label}")
print(f"Top terms: {topic.get_top_terms(n=5)}")
print(topic.get_examples(n=5))
print(topic.get_representative_docs(n=5))

# Interactive refinement
preview = topic.split()
print(preview)
topic.commit_split()

# Merge topics
itm.merge_topics([1, 2], into="new", new_label="Combined Topic")

# Reassign a document
itm.assign_doc(doc_id=42, topic_id=3, validated=True)

# Visualize
fig = visualize_documents(itm)
fig.show()

# Undo if needed
itm.undo()

# Check undo history
print(itm.get_history())

Slightly more detailed blurb

Topic modeling is commonly treated like an objective task, that is, one that has a correct answer. In that view, the task of designing a topic model is to make it as accurate as possible by making it increasingly sophisticated.

I have a different view. Because texts are so rich, the range of acceptable ways to group them is very large. The question then becomes less of "Is this the correct classification?" and more of "Is this a useful/interesting classification?" This is not a question that can be answered without interpretive input, as the question of what is useful or interesting is relative to one's values and purposes.

As such, I have kept topic modeling operations (in the strict sense) very basic. The outputs to these basic topic models then serve as a basis for further exploration through interaction. In other words, topic modeling (embedding -> dimension reduction -> clustering) along with other tools like semantic search (embedding -> cosine similarity) serve as tools to augment the interpretive process, not replace it.

In line with this reasoning, ITM is also very flexible, allowing for multiple pretrained embedding models to be used in concert since each model encodes different linguistic features differently.

In short, this approach empowers people to tailor topic models to their own questions and values, making ITM a tool for assisting the exploration/discovery process rather than automating it.

Architecture

Key Classes

InteractiveTopicModel

The main engine that orchestrates topic modeling operations:

  • Manages document assignments, strengths, and validation status
  • Coordinates semantic spaces via BasicTopicModel instances
  • Provides operations: fit, assign, split, merge, group, archive
  • Tracks undo/redo history

InteractiveTopic

Represents a single topic with:

  • Access to documents: get_doc_ids(), get_texts(), get_examples()
  • Representations: get_embedding(), get_ctfidf(), get_top_terms()
  • Representative documents: get_representative_doc_ids(), get_representative_docs()
  • Operations: split(), commit_split()
  • Metadata: label, parent, active status

BasicTopicModel

Manages a semantic space:

  • Embeds documents via embedder (e.g., sentence-transformers)
  • Reduces dimensions via reducer (e.g., UMAP)
  • Clusters via clusterer (e.g., HDBSCAN)
  • Caches embeddings and reduced representations
  • Can have its own vocabulary (for sub-splits with custom vectorizers)

Topic Representations

Topics are characterized by multiple representations:

  1. Representative documents: Documents with highest cluster membership strength
  2. c-TF-IDF vectors: Class-based TF-IDF distinguishing each topic from siblings
  3. Centroid embeddings: Mean embedding of representative documents
  4. Top terms: Highest-weighted terms from c-TF-IDF
  5. Auto-generated labels: Based on top terms

All representations are computed lazily and invalidated when assignments change.

Component Customization

ITM provides default components but allows full customization:

from interactive_topic_model import (
    InteractiveTopicModel,
    SentenceTransformerEmbedder,
    UMAPReducer,
    HDBSCANClusterer,
    custom_vectorizer,
    harmonic_scorer,
)

# Custom components
itm = InteractiveTopicModel(
    texts=texts,
    embedder=SentenceTransformerEmbedder("all-mpnet-base-v2"),
    reducer=UMAPReducer(n_components=5, n_neighbors=15),
    clusterer=HDBSCANClusterer(min_cluster_size=10),
    vectorizer=custom_vectorizer(
        ngram_range=(1, 3),
        min_df=3,
        max_df=0.85,
        use_en_stopwords=True,
    ),
    scorer=harmonic_scorer,
    n_representative_docs=5,
)

Available Components

Embedders:

  • SentenceTransformerEmbedder - sentence-transformers models
  • e5_base_embedder() - Convenience function for E5-base-v2

Reducers:

  • UMAPReducer - UMAP dimensionality reduction

Clusterers:

  • HDBSCANClusterer - Hierarchical DBSCAN clustering

Scorers:

  • embedding_scorer - Cosine similarity on embeddings
  • tfidf_scorer - Cosine similarity on TF-IDF vectors
  • harmonic_scorer - Harmonic mean of both (default)

Vectorizers:

  • default_vectorizer() - Balanced defaults for general use
  • custom_vectorizer() - Customizable n-grams, stopwords, etc.

API Reference

InteractiveTopicModel Methods

Fitting:

  • fit() - Fit initial topic model

Assignment Operations:

  • assign_doc(doc_id, topic_id, strength, validated) - Assign document to topic
  • validate_doc(doc_id) - Mark document as validated
  • suggest_assignment(doc_id, mode, threshold) - Suggest best topic

Topic Operations:

  • merge_topics(topic_ids, into, new_label, archive_sources, validate_refits) - Merge topics
  • archive_topic(topic_id) - Deactivate a topic
  • group_topics(topic_ids, label) - Create hierarchical grouping

Information Retrieval:

  • get_topic_info(top_words_n, show_inactive, show_outliers) - Summary DataFrame
  • get_representative_documents(topic_ids, n) - Representative docs per topic
  • get_examples(topics, n, include_descendants, random_state) - Sample documents
  • get_active_topics() - List of active topic IDs
  • get_outlier_count() - Count of outlier documents
  • get_validated_count() - Count of validated documents

Undo/Redo:

  • undo(steps) - Undo operations
  • redo(steps) - Redo operations
  • can_undo() - Check if undo is possible
  • can_redo() - Check if redo is possible
  • get_history(stack, reverse, include_timestamp) - View edit history

InteractiveTopic Methods

Document Access:

  • get_count(include_descendants) - Number of documents
  • get_doc_ids(include_descendants) - List of document IDs
  • get_texts(include_descendants) - List of document texts
  • get_examples(n, include_descendants, random_state) - Sample documents
  • get_representative_doc_ids() - IDs of representative documents
  • get_representative_docs() - Texts of representative documents

Representations:

  • get_embedding() - Centroid embedding
  • get_ctfidf() - c-TF-IDF vector
  • get_top_terms(n) - Top n terms with scores
  • get_auto_label(n) - Generate label from top terms

Operations:

  • split(clusterer, ...) - Preview topic split
  • commit_split() - Commit the split preview

Properties:

  • label - Topic label (get/set)
  • parent - Parent topic or ITM
  • active - Whether topic is active
  • semantic_space - Associated BasicTopicModel

To-do

  • Update vignette to demonstrate more features and navigation
  • Add serialization features
  • Add advanced semantic features (idea training, etc.)
  • Add assignment export/import features

License

MIT License

About

An interactive topic modeling framework designed for social science research, where interpretability, iterative refinement, and human-in-the-loop validation are made accessible via a user-friendly interface.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages