Skip to content

ClusteringDetector

Unsupervised clustering over a curated sklearn roster, with structured + text-embedding fusion, c-TF-IDF keyword extraction, and UMAP visualisation. See the unsupervised guide.

In short

  • ClusteringConfig.algorithm picks the algorithm; the default is "hdbscan".
  • HDBSCAN, DBSCAN and agglomerative are transductive: they cannot score new rows. Pick kmeans, minibatch_kmeans, gmm or birch when the model must serve.
  • n_clusters="auto" (default) sweeps k over [auto_k_min, auto_k_max] (2 to 15) and keeps the best by auto_k_score (default "silhouette").
  • to_pipeline() returns the deployable UnsupervisedPipeline.

ClusteringDetector

ClusteringDetector(
    config: Optional[ClusteringConfig] = None,
    unsupervised_config: Optional[
        UnsupervisedConfig
    ] = None,
    preprocessor: Optional[
        UnsupervisedPreprocessor
    ] = DEFAULT_PREPROCESSOR,
    *,
    outputs_dir: Optional[str] = None,
    setup_file_logger: bool = True
)

Bases: BaseEstimator

Unsupervised clustering detector — sklearn algorithms behind a single wrapper. See module / plan docs for the design.

Parameters

config : ClusteringConfig, optional Algorithm + hyperparameter configuration. Defaults to ClusteringConfig(). unsupervised_config : UnsupervisedConfig, optional Preprocessor + embedding configuration. Defaults to UnsupervisedConfig(). Used verbatim — in particular numeric_scaler, which stays whatever the caller set; see :mod:parleml_ml4.unsupervised.config_checks. preprocessor : UnsupervisedPreprocessor, optional Override the default preprocessor (pass None to skip preprocessing entirely if your input is already a numeric matrix). outputs_dir : str, optional, keyword-only When provided, opt into the §M3 + §M4 outputs_dir discipline: fit() writes <outputs_dir>/{events.ndjson, manifest.json, CANCEL, ml4.log} and persists the deployable :class:UnsupervisedPipeline to <outputs_dir>/deploy/ under :data:~parleml_ml4.run_layout.UNSUPERVISED_ARTEFACT_NAME. When None (default), the runtime is identical to the legacy in-memory behaviour. setup_file_logger : bool, keyword-only, default True When True and outputs_dir is provided and the root logger has no handlers, install a rotating file handler at <outputs_dir>/ml4.log. Mirrors :class:AutoSupervised's gating.

DEPLOY_ARTIFACT_NAME class-attribute instance-attribute

DEPLOY_ARTIFACT_NAME = UNSUPERVISED_ARTEFACT_NAME

Filename inside <outputs_dir>/deploy/ that the saved :class:UnsupervisedPipeline lands in.

Deliberately the same name the platform's enriched re-save uses — see :data:parleml_ml4.run_layout.UNSUPERVISED_ARTEFACT_NAME for why one deploy/ directory must not end up holding two same-versioned artefacts that disagree (PIP-5).

outputs_dir property

outputs_dir: Optional[str]

The outputs_dir passed to the constructor, or None.

is_inductive property

is_inductive: bool

True when this algorithm supports predict(X_new).

Transductive algorithms (DBSCAN / HDBSCAN / Agglomerative) only label the training rows, so they cannot be served as a scorer.

fit

fit(X, y=None)

Fit the clustering algorithm.

Wraps the logical stages (preprocess / fit_algorithm / build_result, plus persist when outputs_dir was provided) with stage_* events. When outputs_dir is None the runtime is identical to the legacy synchronous path: no telemetry, no on-disk artefact.

fit_predict

fit_predict(X, y=None)

sklearn convention — equivalent to fit(X) then the fitted labels.

Not fit(X).predict(X): three of the seven algorithms are transductive and have no predict at all, so the labels the fit produced are the only answer that exists for every algorithm.

predict_proba

predict_proba(X) -> ndarray

Soft cluster probability — GMM only.

explain_rows

explain_rows(
    X, *, top_k_features: int = 3
) -> list[dict[str, Any]]

Per-row reason codes for inductive clustering on new rows.

Each entry carries the assigned cluster, the distance to its centroid (centroid models / GMM only), and the nearest_other_cluster. Feature-level attribution is not repeated here — the cluster profiles surface already explains clusters feature-by-feature. Transductive algorithms raise the same :class:NotImplementedError as :meth:predict.

to_pipeline

to_pipeline(
    *,
    compute_embedding: bool = False,
    X_for_embedding: Optional[Any] = None,
    metadata: Optional[dict[str, Any]] = None
) -> Any

Wrap this fitted detector into a self-contained :class:parleml_ml4.unsupervised.UnsupervisedPipeline.

Sugar over UnsupervisedPipeline.from_clustering_detector so plan §11.2 usage works (det.to_pipeline()).

Next: Unsupervised results · Example: clustering