From 713c911fd9ed67c4df14de3080c4c07de8225cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Kardos=C3=98?= Date: Tue, 7 Jul 2026 15:07:51 +0200 Subject: [PATCH 1/2] Added progress tracking to dynamic fitting and removed convergence criterion from partial_fit as it clearly doesn't work --- turftopic/models/_snmf.py | 24 +++++++++---------- turftopic/models/senstopic.py | 45 ++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/turftopic/models/_snmf.py b/turftopic/models/_snmf.py index 22b327e..701ff61 100644 --- a/turftopic/models/_snmf.py +++ b/turftopic/models/_snmf.py @@ -172,18 +172,18 @@ def fit_new_components(self, X: np.ndarray, n_new_components: int): ): G, F, error = _step(G, F) difference = prev_error - error - if (error < self.error_at_init) and ( - (prev_error - error) / self.error_at_init - ) < self.tol: - if self.verbose: - print(f"Converged after {i} iterations") - self.n_iter_ = i - break - prev_error = error - if self.verbose: - print( - f"Iteration: {i}, Error: {error}, init_error: {self.error_at_init}, difference from previous: {difference}" - ) + # if (error < self.error_at_init) and ( + # (prev_error - error) / self.error_at_init + # ) < self.tol: + # if self.verbose: + # print(f"Converged after {i} iterations") + # self.n_iter_ = i + # break + # prev_error = error + # if self.verbose: + # print( + # f"Iteration: {i}, Error: {error}, init_error: {self.error_at_init}, difference from previous: {difference}" + # ) self.components_ = np.array(F.T) self.n_iter_ = i self.n_components = old_n_components + n_new_components diff --git a/turftopic/models/senstopic.py b/turftopic/models/senstopic.py index 016543d..69a259a 100644 --- a/turftopic/models/senstopic.py +++ b/turftopic/models/senstopic.py @@ -4,7 +4,7 @@ import numpy as np from rich.console import Console -from sentence_transformers import SentenceTransformer +from rich.progress import track from sklearn.base import copy from sklearn.exceptions import NotFittedError from sklearn.feature_extraction.text import CountVectorizer @@ -455,26 +455,39 @@ def fit_transform_dynamic( document_topic_matrix = self.transform( raw_documents, embeddings=embeddings ) - time_labels, self.time_bin_edges = self.bin_timestamps( - timestamps, bins - ) - n_comp, n_vocab = self.components_.shape - n_bins = len(self.time_bin_edges) - 1 - self.axial_temporal_components_ = np.full( - (n_bins, n_comp, n_vocab), - np.nan, - dtype=self.components_.dtype, - ) - self.temporal_importance_ = np.zeros((n_bins, n_comp)) - for i_timebin in np.unique(time_labels): + console = Console() + with console.status("Fitting temporally conditioned topics") as status: + status.update("Labelling documents based on time bins.") + time_labels, self.time_bin_edges = self.bin_timestamps( + timestamps, bins + ) + console.log("Documents binned.") + status.update("Initializing components.") + n_comp, n_vocab = self.components_.shape + n_bins = len(self.time_bin_edges) - 1 + self.axial_temporal_components_ = np.full( + (n_bins, n_comp, n_vocab), + np.nan, + dtype=self.components_.dtype, + ) + console.log("Components initialized.") + self.temporal_importance_ = np.zeros((n_bins, n_comp)) + for i_timebin in track( + np.unique(time_labels), + description="Calculating temporal components for each time slice.", + console=console, + ): t_dt = document_topic_matrix[time_labels == i_timebin] t_X = self.embeddings[time_labels == i_timebin] t_imp, t_comp = self._fit_timebin(t_X, t_dt) self.temporal_importance_[i_timebin, :] = t_imp self.axial_temporal_components_[i_timebin, :, :] = t_comp - self.estimate_components( - self.feature_importance, - ) + console.log("Temporal components computed.") + with console.status("Post-processing components."): + self.estimate_components( + self.feature_importance, + ) + console.log("Temporal fitting done.") return document_topic_matrix @property From 67315af53b81392705fea20030df6bb036a8a135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Kardos=C3=98?= Date: Tue, 7 Jul 2026 15:08:15 +0200 Subject: [PATCH 2/2] Version bump --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index db3cc10..14c5626 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ profile = "black" [project] name = "turftopic" -version = "0.27.0" +version = "0.27.1" description = "Topic modeling with contextual representations from sentence transformers." authors = [ { name = "Márton Kardos ", email = "martonkardos@cas.au.dk" }