ClusteringModel¶
class ClusteringModel(**kwargs)
Bases: MetaModel
Subclass of MetaModel for handling clustering-related data processing.
Owns the clustering computation itself, rather than
ClusteringView, which had been importing hdbscan,
sklearn.mixture.GaussianMixture and pandas.api.types.is_float_dtype into a
QWidget; none of those names appears in the View any more.
The View asks for a result by emitting cluster_requested;
ClusteringController calls cluster() and hands what comes back to
ClusteringView.set_clustering_result; RawDataController.calculate_psd is
the same shape.
Public Methods¶
- ClusteringModel.build_clustering_frame(plot_data: DataFrame, frame_columns: List[str], log_flags: List[bool]) DataFrame¶
Filter and log-scale the loaded rows into the frame that gets clustered.
The View still reads the settings dialog, since the per-column flags are strings the user typed; deciding what the numbers mean is this layer’s.
logscale_and_filter_columnsmasks rows across every array it is handed at once, which is what keeps the columns aligned - so"id"is passed through the filter with the rest rather than reattached afterwards, or it would index rows that are no longer there.- Parameters:
- Returns:
the filtered, log-scaled frame to cluster
- Return type:
pd.DataFrame
- Raises:
KeyError – If a requested column is missing from the loaded rows.
- ClusteringModel.cluster(frame: DataFrame, exclude_cols: List[str], method: str, params: Dict[str, Any]) Tuple[DataFrame, ndarray, ndarray]¶
Normalize the given columns and cluster the frame by the named method.
The single entry point the Controller calls.
paramscarries values the View has already parsed and validated - integers and floats, not the raw strings from the settings dialog - so a malformed entry is reported to the user where they typed it rather than raised from in here.- Parameters:
- Returns:
the normalized frame, the cluster labels, and the confidences
- Return type:
Tuple[pd.DataFrame, np.ndarray, np.ndarray]
- Raises:
ValueError – if the method is not one this model implements
- ClusteringModel.cluster_gaussian_mixture(df: DataFrame, n_components: int) Tuple[ndarray, ndarray]¶
Fit a Gaussian mixture to the data and return its labels and confidences.
Seeded (
random_state=42,n_init=100) so that re-running on the same rows gives the same answer, which 1.9.0 fixed and this move preserves.- Parameters:
df (pd.DataFrame) – DataFrame to cluster.
n_components (int) – Number of mixture components to fit.
- Returns:
Cluster labels and per-row confidences.
- Return type:
Tuple[np.ndarray, np.ndarray]
- ClusteringModel.cluster_hdbscan(df: DataFrame, min_cluster_size: int = 30, min_samples: int = 1, cluster_selection_epsilon: float = 1) Tuple[ndarray, ndarray]¶
Performs HDBSCAN clustering on the provided data.
- Parameters:
- Returns:
Cluster labels and probabilities.
- Return type:
Tuple[np.ndarray, np.ndarray]
- ClusteringModel.commit_cluster_columns(loader: str, cluster_data: DataFrame, table_name: str) bool¶
Write the cluster labels and confidences into the database.
The two new columns are unitless, which is what the
[None, None]says. It belongs with the call it describes rather than with the widget that asks.
- ClusteringModel.drop_cluster_columns(loader: str, table: str) bool¶
Delete an existing clustering result so a new one can replace it.
Owns the SQL, rather than
ClusteringView- authoringALTER TABLEstatements is not a widget’s job.DECISIONS.md(2026-08-25) accepts the f-string interpolation itself, because the database is a local file owned by the user running the app; this is about where the SQL lives.
- ClusteringModel.find_cluster_column_table(loader: str) str | None¶
Return the table already holding cluster columns, or None if there is none.
- ClusteringModel.normalize_column_data(df: DataFrame, exclude_cols: List[str] | None = None) DataFrame¶
Applies MAD-based normalization to float columns in the dataframe.
- Parameters:
df (pd.DataFrame) – Input DataFrame.
exclude_cols (Optional[List[str]]) – Columns to exclude from normalization. None means exclude nothing.
- Returns:
Normalized DataFrame.
- Return type:
pd.DataFrame
Private Methods¶
- ClusteringModel._init() None¶
Perform additional initialization specific to the algorithm being implemented. Must be implemented by subclasses.
This function is called at the end of the class constructor to perform additional initialization specific to the algorithm being implemented. kwargs provided to the base class constructor are available as class attributes.