Skip to content

Add create_topic_taxonomy() method to _bertopic (#2526) - #2527

Open
TheItCrOw wants to merge 1 commit into
MaartenGr:masterfrom
TheItCrOw:master
Open

Add create_topic_taxonomy() method to _bertopic (#2526)#2527
TheItCrOw wants to merge 1 commit into
MaartenGr:masterfrom
TheItCrOw:master

Conversation

@TheItCrOw

@TheItCrOw TheItCrOw commented Jul 30, 2026

Copy link
Copy Markdown

Hey @MaartenGr,

first off: great repository! It was really easy to get into it and we're using BERTopic extensively, which brings me to my PR:

What does this PR do?

create_topic_taxonomy(): controllable multi-level topic hierarchies

We've been building topic taxonomies for our use case and ran into a gap between the existing options:

  • hierarchical_topics() gives a full dendrogram but no control over the number of levels
  • reduce_topics() can reduce to a target count but isn't really designed for building hierarchies - calling it repeatedly works but produces a lot of single-child branches and the quality of the hiearchy is questionable.

What we needed was a way to say "give me 3 levels with roughly X, Y, Z topics each, and make sure every parent has at least N children."

So we built create_topic_taxonomy(), which:

  • Takes nr_topics_per_level (e.g. [20, 5]) to define the shape
  • Enforces a min_children constraint per parent (default 2) to avoid degenerate branches
  • Optionally blends document centroids with topic embeddings (configurable weight) for richer topic vectors when building the hierarchy, which works really well for us.
  • Clusters bottom-up using agglomerative clustering + a repair step for undersized clusters
  • Labels parents via c-TF-IDF on merged documents
  • Returns a clean DataFrame with Topic_ID, Level, Parent_ID, etc.
  • Does not touch the fitted model - it's a read-only lookup table on top of the leaves

The method sits right next to hierarchical_topics() and follows existing code patterns. Feel free to checkout the Topic Taxonomy mkdocs page I have on my own Fork, which would be merged as well :)

Example

If you want to run it, just do:

from sklearn.datasets import fetch_20newsgroups
from bertopic import BERTopic

# Load dataset
docs = fetch_20newsgroups(subset="all", remove=("headers", "footers", "quotes"))["data"]

# Train BERTopic
topic_model = BERTopic(verbose=True)
topics, probs = topic_model.fit_transform(docs)

nr_topics = len([t for t in topic_model.topic_sizes_.keys() if t != -1])
print(f"\nLeaf topics discovered: {nr_topics}")

# Build 3-level taxonomy: leaves -> parents -> grandparents
level_1 = max(nr_topics // 3, 2)
level_2 = max(level_1 // 3, 2)

print(f"Target topics per level: [{level_1}, {level_2}]")

hierarchy = topic_model.create_topic_taxonomy(
    docs,
    nr_topics_per_level=[level_1, level_2],
    min_children=1,
)

# Print topics per level
print("\n--- Topics per level ---")
for level in sorted(hierarchy.Level.unique()):
    count = (hierarchy.Level == level).sum()
    label = {0: "Leaves", 1: "Parents", 2: "Grandparents", 3: "Great-grandparents"}.get(level, f"Level {level}")
    print(f"  Level {level} ({label}): {count} topics")

# Print full hierarchy
print("\n--- Full taxonomy ---")
print(hierarchy.to_string(index=False))

We've added a dedicated documentation page to the mkdocs (Topic Taxonomy), the actual implementation is only a single method. :)

Before submitting

  • This PR fixes a typo or improves the docs (if yes, ignore all other checks!).
  • Did you read the contributor guideline?
  • Was this discussed/approved via a Github issue? Please add a link to it if that's the case. (It wasn't discussed yet, we just opened the issue)
  • Did you make sure to update the documentation with your changes (if applicable)?
  • Did you write any new necessary tests?

@TheItCrOw

TheItCrOw commented Jul 30, 2026

Copy link
Copy Markdown
Author

Woops, 2 checks failed, let me fix them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant