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.algorithmpicks the algorithm; the default is"hdbscan".- HDBSCAN, DBSCAN and agglomerative are transductive: they cannot score new rows.
Pick
kmeans,minibatch_kmeans,gmmorbirchwhen the model must serve. n_clusters="auto"(default) sweeps k over[auto_k_min, auto_k_max](2 to 15) and keeps the best byauto_k_score(default"silhouette").to_pipeline()returns the deployableUnsupervisedPipeline.
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
¶
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
¶
The outputs_dir passed to the constructor, or None.
is_inductive
property
¶
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 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 ¶
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.
explain_rows ¶
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()).