| Title: | Clustering and Consensus Meta-Clustering |
|---|---|
| Description: | Tools for clustering, consensus meta-clustering, validation, exploratory interpretation, cluster prediction, and plotting. The package provides a clustering workflow with consensus clustering following Strehl and Ghosh (2002) <https://www.jmlr.org/papers/v3/strehl02a.html>. |
| Authors: | Imad El Badisy [aut, cre] |
| Maintainer: | Imad El Badisy <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.6.2 |
| Built: | 2026-10-10 07:36:47 UTC |
| Source: | https://github.com/ielbadisy/phynotype |
phynotype provides tools for unsupervised phenotyping workflows.
The six-step pipeline is:
Cluster: fit a single clustering solution with cluster().
Meta-cluster: aggregate candidate solutions into a consensus
partition with metacluster().
Validate: score a solution with internal and external metrics
using validate().
Explore: summarize cluster sizes, feature profiles, and
two-dimensional embeddings with explore().
Predict: assign new observations to learned clusters with
predict.cluster_fit().
Interpret: explain the clustering rule with
feature_importance(), lime_explain(), and
ceteris_paribus().
All steps operate through S3 generic functions and return structured objects
with print(), summary(), and plot() methods.
"kmeans"Lloyd's k-means algorithm for numeric data.
"pam"Partitioning Around Medoids for numeric data.
"hclust"Hierarchical clustering via stats::hclust().
"agnes"Agglomerative nesting via cluster::agnes().
"dbscan"Density-based spatial clustering via dbscan::dbscan().
"gmm"Gaussian mixture models via mclust::Mclust().
"kproto"K-prototypes for mixed numeric/categorical data.
"kmm"K-Mixed-Modes, a native mixed-data algorithm.
Internal metrics: silhouette width (Rousseeuw, 1987), Calinski-Harabasz index (Calinski and Harabasz, 1974), Davies-Bouldin index (Davies and Bouldin, 1979), total within-cluster sum of squares, and bootstrap ARI. External metrics (when reference labels are available): adjusted Rand index (Hubert and Arabie, 1985) and normalized mutual information (Strehl and Ghosh, 2002).
Use prepare_mixed_data() to encode mixed-type data frames into a numeric
matrix before distance-based methods. Use mixed_distance() to build a
Gower distance matrix (Gower, 1971) before hierarchical methods. The
exploratory embedding layer automatically selects PCA for numeric data,
FAMD for mixed numeric/categorical data, MCA for categorical data, and
classical MDS for distance objects.
Maintainer: Imad EL BADISY [email protected]
Rousseeuw, P.J. (1987). Silhouettes: A graphical aid to the interpretation and validation of cluster analysis. Journal of Computational and Applied Mathematics, 20, 53–65.
Calinski, T. and Harabasz, J. (1974). A dendrite method for cluster analysis. Communications in Statistics, 3(1), 1–27.
Davies, D.L. and Bouldin, D.W. (1979). A cluster separation measure. IEEE Transactions on Pattern Analysis and Machine Intelligence, 1(2), 224–227.
Hubert, L. and Arabie, P. (1985). Comparing partitions. Journal of Classification, 2(1), 193–218.
Strehl, A. and Ghosh, J. (2002). Cluster ensembles: A knowledge reuse framework for combining multiple partitions. Journal of Machine Learning Research, 3, 583–617.
Gower, J.C. (1971). A general coefficient of similarity and some of its properties. Biometrics, 27(4), 857–874.
cluster(), metacluster(), validate(), explore(),
predict.cluster_fit(), feature_importance(), lime_explain(),
ceteris_paribus()
Computes the Adjusted Rand Index (ARI) between two partitions, correcting the Rand Index for chance agreement (Hubert and Arabie, 1985). ARI equals 1 for identical partitions and has expectation 0 under independent random labelings.
adjusted_rand_index(x, y)adjusted_rand_index(x, y)
x |
Integer or factor vector of cluster labels (first partition). |
y |
Integer or factor vector of cluster labels (second partition).
Must have the same length as |
A single numeric value in .
Hubert, L. and Arabie, P. (1985). Comparing partitions. Journal of Classification, 2(1), 193–218.
adjusted_rand_index(c(1, 1, 2, 2), c(1, 1, 2, 3))adjusted_rand_index(c(1, 1, 2, 2), c(1, 1, 2, 3))
Extract the numeric cluster center matrix. Available for k-means and
hierarchical methods trained on numeric data; returns NULL for PAM,
k-prototypes, and GMM (use prototypes() or membership() instead).
centers(x, ...)centers(x, ...)
x |
A |
... |
Unused. |
A numeric matrix with one row per cluster and one column per
feature, or NULL.
prototypes(), clusters(), membership()
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) centers(fit)fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) centers(fit)
Compute individual conditional profiles for a fitted clustering rule. A ceteris paribus profile varies one feature over a grid while holding all other features fixed at an observed profile. It describes how the predicted cluster assignment or a cluster score changes locally as a single feature is perturbed.
ceteris_paribus( object, new_data, features = NULL, grid = NULL, grid_size = 25L, target = c("cluster", "score"), cluster = NULL, parallel = FALSE, cores = NULL, workers = NULL, progress = FALSE, ... )ceteris_paribus( object, new_data, features = NULL, grid = NULL, grid_size = 25L, target = c("cluster", "score"), cluster = NULL, parallel = FALSE, cores = NULL, workers = NULL, progress = FALSE, ... )
object |
A |
new_data |
Row-by-feature data containing observations to explain. |
features |
Optional character vector or numeric column index specifying features to profile. |
grid |
Optional vector or named list of vectors giving profile values.
If |
grid_size |
Number of grid values per feature when |
target |
Output target. |
cluster |
Optional cluster whose score should be profiled when
|
parallel |
Logical; if |
cores |
Optional positive integer number of cores passed to
|
workers |
Optional number of workers passed to |
progress |
Logical; if |
... |
Reserved for future extensions. |
For observation , feature , and grid value , define
as all coordinates of except feature . The
ceteris paribus profile is
where is the fitted clustering rule and extracts either the
predicted cluster label or a cluster-specific score. For methods that return
membership probabilities, the score is the predicted membership. For
distance-based methods, phynotype converts distances into normalized radial
similarity scores so that larger values indicate stronger association with a
cluster prototype.
These profiles are local diagnostic curves. They should be interpreted as behavior of the fitted clustering rule under controlled perturbation, not as causal effects.
A ceteris_paribus object with a tidy profiles data frame. Each
row records: the observation index, the feature being varied, the grid
value at that step, the predicted target (cluster label or score), the
observed feature value, and the baseline prediction.
Biecek, P. and Burzykowski, T. (2021). Explanatory Model Analysis. Chapman and Hall/CRC, Boca Raton. https://ema.drwhy.ai/
Gosiewska, A. and Biecek, P. (2019). iBreakDown: Uncertainty of model explanations for non-additive predictive models. arXiv:1903.11420.
Apley, D.W. and Zhu, J. (2020). Visualizing the effects of predictor variables in black box supervised learning models. Journal of the Royal Statistical Society: Series B, 82(4), 1059–1086.
lime_explain() for local linear surrogate explanations,
feature_importance() for global permutation importance,
predict.cluster_fit() which is used internally.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) cp <- ceteris_paribus(fit, iris[1:3, 1:4], features = 1:2, grid_size = 10) head(cp$profiles)fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) cp <- ceteris_paribus(fit, iris[1:3, 1:4], features = 1:2, grid_size = 10) head(cp$profiles)
Fit a single clustering solution using a supported method.
cluster( x, method = "kmeans", ..., k = NULL, scale = FALSE, center = TRUE, seed = NULL )cluster( x, method = "kmeans", ..., k = NULL, scale = FALSE, center = TRUE, seed = NULL )
x |
Numeric matrix/data frame for numeric methods, a |
method |
Clustering method. Supported values are |
... |
Additional method-specific arguments passed to the underlying
engine (e.g. |
k |
Number of clusters for methods that require it ( |
scale |
Logical; if |
center |
Logical; if |
seed |
Optional integer random seed for reproducible results. |
cluster() is the single entry point for all supported methods. It
dispatches to a method-specific backend registered via the internal
cluster_registry, validates inputs, applies any requested preprocessing,
and returns a cluster_fit object with a uniform interface regardless of
the underlying engine.
Method-specific notes:
"kmeans"Minimizes total within-cluster sum of squares
(Lloyd, 1982).
Requires numeric x and k.
"pam"Partitioning Around Medoids: minimizes
over actual observations (Kaufman and
Rousseeuw, 1990). Requires the cluster package.
"hclust" / "agnes"
Hierarchical agglomerative methods. Accept
a precomputed dist object or raw numeric data. Specify linkage to
choose the merging criterion (default "complete" for hclust,
"average" for agnes). "agnes" requires the cluster package.
"dbscan"Density-Based Spatial Clustering of Applications with
Noise (Ester et al., 1996). Requires eps (neighborhood radius) and
minPts. Observations in sparse regions are labeled noise (cluster 0).
Requires the dbscan package.
"gmm"Gaussian Mixture Model fitted via the EM algorithm (Fraley
and Raftery, 2002). Returns soft membership probabilities. Requires the
mclust package.
"kproto"K-prototypes for mixed numeric/categorical data (Huang,
1998). Use lambda to control the numeric-vs-categorical trade-off.
Requires the clustMixType package.
"kmm"K-Mixed-Modes: a native mixed-data algorithm that
minimizes a weighted prototype distance combining squared Euclidean and
Hamming contributions controlled by lambda.
A cluster_fit object with components:
methodCharacter; the method used.
clustersInteger vector of cluster assignments.
n_clustersInteger; number of clusters found.
centersCluster centers (numeric methods) or NULL.
prototypesCluster prototypes (mixed methods) or NULL.
membershipSoft membership matrix (GMM) or NULL.
data_infoList of input metadata for downstream use.
Lloyd, S.P. (1982). Least squares quantization in PCM. IEEE Transactions on Information Theory, 28(2), 129–137.
Kaufman, L. and Rousseeuw, P.J. (1990). Finding Groups in Data: An Introduction to Cluster Analysis. John Wiley & Sons, New York.
Ester, M., Kriegel, H.-P., Sander, J. and Xu, X. (1996). A density-based algorithm for discovering clusters in large spatial databases with noise. Proceedings of the 2nd ACM SIGKDD, pp. 226–231.
Fraley, C. and Raftery, A.E. (2002). Model-based clustering, discriminant analysis, and density estimation. Journal of the American Statistical Association, 97(458), 611–631.
Huang, Z. (1998). Extensions to the k-means algorithm for clustering large data sets with categorical values. Data Mining and Knowledge Discovery, 2(3), 283–304.
validate() to score the fit, explore() to summarize cluster
structure, predict.cluster_fit() to assign new observations,
metacluster() for consensus clustering,
feature_importance(), lime_explain(), ceteris_paribus() for
interpretability.
# Numeric data: k-means fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) fit clusters(fit) centers(fit) # PAM (requires the cluster package) if (requireNamespace("cluster", quietly = TRUE)) { fit_pam <- cluster(iris[, 1:4], method = "pam", k = 3) fit_pam } # Hierarchical clustering from a distance object d <- mixed_distance(iris[, 1:4]) fit_hc <- cluster(d, method = "hclust", k = 3) fit_hc # Mixed data: k-prototypes if (requireNamespace("clustMixType", quietly = TRUE)) { fit_kp <- cluster(iris, method = "kproto", k = 3, seed = 1) fit_kp }# Numeric data: k-means fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) fit clusters(fit) centers(fit) # PAM (requires the cluster package) if (requireNamespace("cluster", quietly = TRUE)) { fit_pam <- cluster(iris[, 1:4], method = "pam", k = 3) fit_pam } # Hierarchical clustering from a distance object d <- mixed_distance(iris[, 1:4]) fit_hc <- cluster(d, method = "hclust", k = 3) fit_hc # Mixed data: k-prototypes if (requireNamespace("clustMixType", quietly = TRUE)) { fit_kp <- cluster(iris, method = "kproto", k = 3, seed = 1) fit_kp }
Extract the integer cluster assignment vector from a fitted clustering object.
clusters(x, ...)clusters(x, ...)
x |
A |
... |
Unused. |
Integer vector of length equal to the number of training observations.
sizes(), n_clusters(), centers(), membership()
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) clusters(fit)fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) clusters(fit)
Summarize cluster sizes, feature profiles, feature separation, and a two-dimensional embedding for a fitted clustering solution.
explore( x, data = NULL, embedding = c("auto", "pca", "famd", "mca", "mds"), ... )explore( x, data = NULL, embedding = c("auto", "pca", "famd", "mca", "mds"), ... )
x |
A |
data |
Optional numeric matrix, data frame, or distance object.
Defaults to the training data stored in |
embedding |
Embedding method. |
... |
Unused. |
explore() computes four summaries:
Number of observations per cluster.
Per-cluster mean, standard deviation, median, min, and max for each feature.
The eta-squared statistic for each feature,
, measuring
how much between-cluster variance each feature explains.
Two-dimensional projection for visualization
(see plot_clusters()).
A cluster_explore object with components:
size_tableData frame with cluster sizes.
feature_summaryData frame with per-cluster descriptive statistics for each feature.
separation_tableData frame with per-feature eta-squared values.
embeddingData frame with two embedding coordinates and cluster labels.
cluster() to fit, plot_clusters() to plot the embedding,
plot_feature_profiles() to plot feature profiles.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) exp <- explore(fit) exp$size_table head(exp$feature_summary) exp$separation_tablefit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) exp <- explore(fit) exp$size_table head(exp$feature_summary) exp$separation_table
Estimate global feature importance by measuring how much a fitted clustering
solution changes when each feature is independently permuted. The method is
model-agnostic: it uses the fitted object's predict() method and therefore
applies to clustering engines with native prediction support.
feature_importance( object, data = NULL, features = NULL, metric = c("instability", "silhouette", "total_within"), loss = NULL, n_repeats = 10L, seed = NULL, parallel = FALSE, cores = NULL, workers = NULL, progress = FALSE, ... )feature_importance( object, data = NULL, features = NULL, metric = c("instability", "silhouette", "total_within"), loss = NULL, n_repeats = 10L, seed = NULL, parallel = FALSE, cores = NULL, workers = NULL, progress = FALSE, ... )
object |
A |
data |
Optional row-by-feature data used for evaluation. Defaults to the
training data stored in |
features |
Optional character vector or numeric column index specifying features to evaluate. |
metric |
Built-in importance metric. |
loss |
Optional custom loss function with signature
|
n_repeats |
Number of independent permutations per feature. |
seed |
Optional integer random seed. |
parallel |
Logical; if |
cores |
Optional positive integer number of cores passed to
|
workers |
Optional number of workers passed to |
progress |
Logical; if |
... |
Reserved for future extensions. |
Let denote the fitted clustering rule, the evaluation data,
the baseline predicted partition, and
the data matrix where feature has been
permuted in repetition . For the default instability metric, feature
importance is
This quantity estimates the expected fraction of assignments that change
when the marginal information in feature is broken. Larger values
indicate that the fitted clustering rule relies more strongly on that
feature.
For score-style internal metrics, the package computes a baseline score
and a permuted score
. For silhouette, larger is better and
For total within-cluster sum of squares, smaller is better and
Users can pass a custom loss function for domain-specific objectives. It
must accept (data, clusters, object) and return a numeric scalar where
larger values mean worse fit.
A feature_importance object with components:
resultsData frame with one row per (feature, repeat) combination recording the baseline loss, the permuted loss, and the computed importance.
summaryData frame with one row per feature, containing the mean importance, standard error, and number of repeats.
Breiman, L. (2001). Random forests. Machine Learning, 45(1), 5–32. (Permutation importance concept introduced in the context of random forests.)
Fisher, A., Rudin, C. and Dominici, F. (2019). All models are wrong, but many are useful: Learning a variable's importance by studying an entire class of prediction models simultaneously. Journal of Machine Learning Research, 20(177), 1–81.
lime_explain() for local explanations, ceteris_paribus() for
individual conditional profiles, predict.cluster_fit() which is used
internally.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) imp <- feature_importance(fit, n_repeats = 3, seed = 1) imp$summaryfit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) imp <- feature_importance(fit, n_repeats = 3, seed = 1) imp$summary
Explain individual cluster assignments or cluster scores with a locally weighted surrogate model. The method builds a synthetic neighborhood around each observation, predicts the fitted clustering behavior in that neighborhood, weights perturbed samples by proximity to the explained observation, and fits a simple weighted linear model.
lime_explain( object, new_data, n_features = 5L, n_permutations = 500L, kernel_width = NULL, target = c("cluster", "score"), cluster = NULL, seed = NULL, parallel = FALSE, cores = NULL, workers = NULL, progress = FALSE, ... )lime_explain( object, new_data, n_features = 5L, n_permutations = 500L, kernel_width = NULL, target = c("cluster", "score"), cluster = NULL, seed = NULL, parallel = FALSE, cores = NULL, workers = NULL, progress = FALSE, ... )
object |
A |
new_data |
Row-by-feature data containing observations to explain. |
n_features |
Maximum number of local effects returned per observation. |
n_permutations |
Number of perturbed neighborhood samples per observation. |
kernel_width |
Positive numeric kernel width. If |
target |
Output target. |
cluster |
Optional cluster to explain. If |
seed |
Optional integer random seed. |
parallel |
Logical; if |
cores |
Optional positive integer number of cores passed to
|
workers |
Optional number of workers passed to |
progress |
Logical; if |
... |
Reserved for future extensions. |
For an observation , perturbed samples , fitted clustering
rule , target extractor , local surrogate , and kernel
, the LIME objective is
phynotype uses a weighted linear surrogate for . Feature ranking is
based on the absolute fitted local coefficients after standardizing features
by the training-data scale. The penalty term is represented
operationally by returning the largest n_features effects, which keeps the
explanation sparse and readable without adding a heavy modeling dependency.
For target = "cluster", is an indicator that the
predicted cluster equals the cluster being explained. For target = "score",
it is the cluster-specific membership or similarity score.
A lime_explanation object with components:
explanationsTidy data frame with one row per (observation, feature) pair, containing the local surrogate coefficient, absolute effect size, direction, and rank.
neighborhoodsData frame with all perturbed samples, their predicted responses, kernel weights, and distances to the explained observation.
Ribeiro, M.T., Singh, S. and Guestrin, C. (2016). "Why should I trust you?": Explaining the predictions of any classifier. Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining, pp. 1135–1144.
ceteris_paribus() for individual conditional profiles,
feature_importance() for global importance, predict.cluster_fit()
which is used internally.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) lx <- lime_explain(fit, iris[1:2, 1:4], n_permutations = 50, seed = 1) lx$explanationsfit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) lx <- lime_explain(fit, iris[1:2, 1:4], n_permutations = 50, seed = 1) lx$explanations
Extract the soft membership (posterior probability) matrix. Only methods
that return probabilistic assignments (e.g. GMM) populate this slot; all
other methods return NULL.
membership(x, ...)membership(x, ...)
x |
A |
... |
Unused. |
A numeric matrix with one row per observation and one column per
cluster, or NULL.
clusters(), centers(), prototypes()
if (requireNamespace("mclust", quietly = TRUE)) { fit <- cluster(iris[, 1:4], method = "gmm", k = 3, seed = 1) head(membership(fit)) }if (requireNamespace("mclust", quietly = TRUE)) { fit <- cluster(iris[, 1:4], method = "gmm", k = 3, seed = 1) head(membership(fit)) }
Fit several candidate clustering solutions and summarize their agreement
through a co-association consensus matrix. The consensus partition is
obtained by hierarchical clustering of the dissimilarity matrix
, where is the proportion of candidate
partitions that place observations and in the same cluster.
metacluster( x, methods = c("kmeans", "pam", "hclust"), k = 2:6, consensus = "coassoc", scale = FALSE, center = TRUE, seed = NULL, ... )metacluster( x, methods = c("kmeans", "pam", "hclust"), k = 2:6, consensus = "coassoc", scale = FALSE, center = TRUE, seed = NULL, ... )
x |
Numeric matrix or numeric data frame. |
methods |
Character vector of candidate clustering methods. Any method
supported by |
k |
Integer vector of candidate cluster counts. All combinations of
|
consensus |
Consensus strategy. Currently only |
scale |
Logical; if |
center |
Logical; if |
seed |
Optional integer random seed. Each candidate is given a deterministic offset seed so results are jointly reproducible. |
... |
Additional arguments passed through to |
For candidate partitions, the co-association matrix is
This estimator is related to the Evidence Accumulation Clustering framework
(Fred and Jain, 2002). The consensus dissimilarity is then
hierarchically clustered (average linkage), and the optimal number of
clusters is chosen by maximizing the mean silhouette width.
Stability of the ensemble is summarized by the mean pairwise partition agreement (PPA) across all candidate pairs:
A metacluster_fit object with components:
final_clustersInteger vector of final consensus assignments.
final_kInteger; the selected number of clusters.
coassoc_matrixThe co-association matrix.
candidate_tableData frame listing all fitted candidate solutions.
stability_summaryMean, min, and max pairwise partition agreement.
selection_summaryPer- silhouette scores used for
selection.
Fred, A.L.N. and Jain, A.K. (2002). Data clustering using evidence accumulation. Proceedings of the 16th International Conference on Pattern Recognition (ICPR'02), Vol. 4, pp. 276–280.
Strehl, A. and Ghosh, J. (2002). Cluster ensembles: A knowledge reuse framework for combining multiple partitions. Journal of Machine Learning Research, 3, 583–617.
cluster() for single solutions, validate() to score the
consensus partition, plot_coassoc() to visualize the agreement matrix,
plot_consensus() for a 2-D embedding of the final clusters.
mfit <- metacluster(iris[, 1:4], methods = c("kmeans", "hclust"), k = 2:4, seed = 1) mfit # Inspect the co-association matrix mfit$coassoc_matrix[1:4, 1:4] # Score the consensus partition validate(mfit)$metrics_tablemfit <- metacluster(iris[, 1:4], methods = c("kmeans", "hclust"), k = 2:4, seed = 1) mfit # Inspect the co-association matrix mfit$coassoc_matrix[1:4, 1:4] # Score the consensus partition validate(mfit)$metrics_table
Return the name of the clustering method used to fit the object.
method_used(x, ...)method_used(x, ...)
x |
A |
... |
Unused. |
Character scalar (e.g. "kmeans", "pam", "hclust").
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) method_used(fit)fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) method_used(fit)
Build a Gower dissimilarity matrix for mixed-type data using
cluster::daisy(). This is the recommended first step before hierarchical
clustering ("hclust" or "agnes") when the input contains categorical
variables.
mixed_distance(x, metric = "gower", ...)mixed_distance(x, metric = "gower", ...)
x |
Data frame containing numeric and/or categorical columns. |
metric |
Distance metric passed to |
... |
Additional arguments passed to |
For two observations and , the Gower coefficient
(Gower, 1971) is
where indicates whether feature is comparable
(not missing), is an optional weight, and is the
partial similarity: the scaled absolute difference for numeric features and 0
(match) or 1 (mismatch) for categorical features.
A dist object.
Gower, J.C. (1971). A general coefficient of similarity and some of its properties. Biometrics, 27(4), 857–874.
prepare_mixed_data() for converting mixed data to a numeric
matrix, cluster() for fitting with the resulting distance object.
d <- mixed_distance(iris) fit <- cluster(d, method = "hclust", k = 3) fitd <- mixed_distance(iris) fit <- cluster(d, method = "hclust", k = 3) fit
Return the number of clusters in a fitted clustering object. For DBSCAN, this excludes the noise cluster (label 0).
n_clusters(x, ...)n_clusters(x, ...)
x |
A |
... |
Unused. |
Integer scalar.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) n_clusters(fit)fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) n_clusters(fit)
theme_phynotype
Colorblind-friendly discrete color and fill scales (Okabe-Ito palette, recycled/interpolated beyond 8 levels) for consistent group colors across phynotype figures.
scale_color_phynotype(...) scale_fill_phynotype(...)scale_color_phynotype(...) scale_fill_phynotype(...)
... |
Additional arguments passed to |
A ggplot2 discrete scale object.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_clusters(fit) + scale_color_phynotype()fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_clusters(fit) + scale_color_phynotype()
A self-contained reimplementation of factoextra's fviz_pca_biplot()
and fviz_mca_biplot() geometry (individual points/arrows, variable
arrows or category points, axis percentage labels, dashed origin lines),
producing the same plots without depending on factoextra. Only the
"pca" and "mca" embeddings are supported, matching the biplot
functions factoextra itself provides; there is no FAMD biplot
equivalent, and MDS has no variable space to project.
plot_biplot( x, data = NULL, embedding = c("auto", "pca", "mca"), variant = c("cluster", "cos2", "label"), top_n = NULL, ... )plot_biplot( x, data = NULL, embedding = c("auto", "pca", "mca"), variant = c("cluster", "cos2", "label"), top_n = NULL, ... )
x |
A |
data |
Optional numeric matrix, data frame, or distance object used to
compute the embedding. Defaults to the training data stored in |
embedding |
Embedding method. |
variant |
Display variant: |
top_n |
Optional integer; if supplied, only the |
... |
Reserved for future extensions. |
Three display variants, matching factoextra's own documented examples
(?factoextra::fviz_pca):
"cluster"Individuals colored and shaped by cluster assignment. The default.
"cos2"Individuals colored by their quality of representation
(cos2) on a white-blue-orange gradient.
"label"Individuals shown as text labels (observation names or row numbers) instead of points.
For a "pca" embedding, variables are drawn as arrows from the origin,
scaled so their spread matches that of the individuals (factoextra's own
scaling rule (ratio * 0.7), where ratio is the ratio of the individuals' to
variables' coordinate ranges). For a "mca" embedding, variable
categories are drawn as unscaled points (matching
factoextra::fviz_mca_biplot()'s default arrows = c(FALSE, FALSE)).
A ggplot object.
plot_clusters(), explore() for the underlying embedding.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_biplot(fit) plot_biplot(fit, variant = "cos2") plot_biplot(fit, variant = "label")fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_biplot(fit) plot_biplot(fit, variant = "cos2") plot_biplot(fit, variant = "label")
Display a bar chart of the number of observations per cluster.
plot_cluster_sizes(x, ...)plot_cluster_sizes(x, ...)
x |
A |
... |
Unused. |
A ggplot object.
sizes(), plot_clusters(), plot_feature_profiles()
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_cluster_sizes(fit)fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_cluster_sizes(fit)
Project observations onto a two-dimensional embedding and color them by
cluster assignment. For metacluster_fit objects, delegates to
plot_consensus().
plot_clusters( x, data = NULL, embedding = c("auto", "pca", "famd", "mca", "mds"), ... )plot_clusters( x, data = NULL, embedding = c("auto", "pca", "famd", "mca", "mds"), ... )
x |
A |
data |
Optional numeric matrix, data frame, or distance object used to
compute the embedding. Defaults to the training data stored in |
embedding |
Embedding method. |
... |
Unused. |
A ggplot object.
explore() for the underlying embedding, plot_cluster_sizes(),
plot_feature_profiles()
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_clusters(fit)fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_clusters(fit)
Display the co-association matrix as a heatmap. High values
(near 1) indicate pairs of observations that were consistently co-clustered
across candidate partitions.
plot_coassoc(x, ...)plot_coassoc(x, ...)
x |
A |
... |
Unused. |
A ggplot object.
metacluster(), plot_consensus()
mfit <- metacluster(iris[, 1:4], methods = c("kmeans", "hclust"), k = 2:3, seed = 1) plot_coassoc(mfit)mfit <- metacluster(iris[, 1:4], methods = c("kmeans", "hclust"), k = 2:3, seed = 1) plot_coassoc(mfit)
Project the consensus cluster assignments onto a two-dimensional embedding.
plot_consensus( x, data = NULL, embedding = c("auto", "pca", "famd", "mca", "mds"), ... )plot_consensus( x, data = NULL, embedding = c("auto", "pca", "famd", "mca", "mds"), ... )
x |
A |
data |
Optional numeric matrix, data frame, or distance object used to
compute the embedding. Defaults to the training data stored in |
embedding |
Embedding method. |
... |
Unused. |
A ggplot object.
mfit <- metacluster(iris[, 1:4], methods = c("kmeans", "hclust"), k = 2:3, seed = 1) plot_consensus(mfit)mfit <- metacluster(iris[, 1:4], methods = c("kmeans", "hclust"), k = 2:3, seed = 1) plot_consensus(mfit)
Draw the dendrogram from a hierarchical cluster_fit (fitted via
"hclust" or "agnes") or the consensus hierarchical tree from a
metacluster_fit.
plot_dendrogram(x, ...)plot_dendrogram(x, ...)
x |
A hierarchical |
... |
Additional arguments passed to the base |
The underlying hclust object, invisibly.
cluster(), metacluster(), plot_consensus()
d <- mixed_distance(iris[, 1:4]) fit <- cluster(d, method = "hclust", k = 3) plot_dendrogram(fit) mfit <- metacluster(iris[, 1:4], methods = c("kmeans", "hclust"), k = 2:3, seed = 1) plot_dendrogram(mfit)d <- mixed_distance(iris[, 1:4]) fit <- cluster(d, method = "hclust", k = 3) plot_dendrogram(fit) mfit <- metacluster(iris[, 1:4], methods = c("kmeans", "hclust"), k = 2:3, seed = 1) plot_dendrogram(mfit)
Display per-cluster mean values for each feature as a grouped bar chart.
plot_feature_profiles(x, features = NULL, ...)plot_feature_profiles(x, features = NULL, ...)
x |
A |
features |
Optional character vector of feature names to include. Defaults to all features. |
... |
Unused. |
A ggplot object.
explore(), plot_clusters(), plot_cluster_sizes()
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) exp <- explore(fit) plot_feature_profiles(exp) plot_feature_profiles(exp, features = c("Sepal.Length", "Petal.Length"))fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) exp <- explore(fit) plot_feature_profiles(exp) plot_feature_profiles(exp, features = c("Sepal.Length", "Petal.Length"))
Display observation-level silhouette widths colored by cluster. Observations with negative widths lie closer to a neighboring cluster than to their own and may be misclassified.
plot_silhouette(x, ...)plot_silhouette(x, ...)
x |
A |
... |
Unused. |
A ggplot object.
if (requireNamespace("cluster", quietly = TRUE)) { fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_silhouette(fit) }if (requireNamespace("cluster", quietly = TRUE)) { fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_silhouette(fit) }
Assign new observations to the clusters of a fitted cluster_fit object.
The prediction strategy is method-dependent: k-means, PAM, and hierarchical
methods use nearest-centroid or nearest-prototype rules; GMM uses the
posterior mode; DBSCAN uses a density-based rule falling back to the nearest
core point.
## S3 method for class 'cluster_fit' predict(object, new_data, ...)## S3 method for class 'cluster_fit' predict(object, new_data, ...)
object |
A |
new_data |
Row-by-feature data compatible with the training data.
Numeric methods expect a numeric matrix or data frame; |
... |
Additional arguments passed to method-specific predictors. |
A cluster_prediction object with components:
clustersInteger vector of predicted cluster assignments.
distancesDistance matrix to each cluster center/prototype,
or NULL for methods that do not produce distances.
membershipSoft membership matrix (GMM only), or NULL.
cluster() to fit, feature_importance(), lime_explain(),
and ceteris_paribus() which all use predict() internally.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) # Predict on the training data pred <- predict(fit, iris[1:10, 1:4]) pred$clusters # Predict on new data new_obs <- data.frame( Sepal.Length = c(5.0, 7.0), Sepal.Width = c(3.5, 3.0), Petal.Length = c(1.5, 5.0), Petal.Width = c(0.3, 1.8) ) predict(fit, new_obs)$clustersfit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) # Predict on the training data pred <- predict(fit, iris[1:10, 1:4]) pred$clusters # Predict on new data new_obs <- data.frame( Sepal.Length = c(5.0, 7.0), Sepal.Width = c(3.5, 3.0), Petal.Length = c(1.5, 5.0), Petal.Width = c(0.3, 1.8) ) predict(fit, new_obs)$clusters
Convert a data frame containing numeric, logical, character, or factor
columns into a numeric design matrix suitable for methods such as
"kmeans", "pam", "dbscan", and "gmm".
prepare_mixed_data( x, center = TRUE, scale = TRUE, drop_first = FALSE, na_action = c("keep", "fail") )prepare_mixed_data( x, center = TRUE, scale = TRUE, drop_first = FALSE, na_action = c("keep", "fail") )
x |
Data frame, matrix, or vector-like object coercible to a data frame. |
center |
Logical; if |
scale |
Logical; if |
drop_first |
Logical; if |
na_action |
Missing-value strategy. |
Categorical variables are one-hot encoded (full-rank by default), numeric variables are optionally centered and scaled, and missingness can be preserved as an explicit level or trigger an error.
This is intentionally a manual first step. Clustering algorithms that use
Euclidean distances or Gaussian models should not silently coerce mixed data.
For hierarchical methods on mixed data, use mixed_distance() instead.
A numeric matrix with preprocessing metadata stored in the attribute
"phynotype_preprocess".
mixed_distance() for Gower-distance computation before
hierarchical clustering.
# Mixed data frame df <- data.frame( x1 = c(1.2, 0.5, 3.1), x2 = factor(c("A", "B", "A")) ) mat <- prepare_mixed_data(df) mat# Mixed data frame df <- data.frame( x1 = c(1.2, 0.5, 3.1), x2 = factor(c("A", "B", "A")) ) mat <- prepare_mixed_data(df) mat
Extract the cluster prototype table. Prototypes are actual observations
(PAM medoids) or mixed-type representatives (k-prototypes, KMM); returns
NULL for methods that use centroids rather than prototypes.
prototypes(x, ...)prototypes(x, ...)
x |
A |
... |
Unused. |
A matrix or data frame with one row per cluster, or NULL.
if (requireNamespace("cluster", quietly = TRUE)) { fit <- cluster(iris[, 1:4], method = "pam", k = 3) prototypes(fit) }if (requireNamespace("cluster", quietly = TRUE)) { fit <- cluster(iris[, 1:4], method = "pam", k = 3) prototypes(fit) }
Return the number of observations assigned to each cluster.
sizes(x, ...)sizes(x, ...)
x |
A |
... |
Unused. |
Named integer vector, where names are the cluster labels.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) sizes(fit)fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) sizes(fit)
The single ggplot2 theme used consistently across every phynotype plot
function (plot_clusters(), plot_cluster_sizes(),
plot_feature_profiles(), plot_consensus(), plot_coassoc(),
plot_biplot(), plot() methods for feature_importance,
ceteris_paribus, and lime_explanation objects, and plot_validation()).
Built on ggplot2::theme_classic() with an Okabe-Ito colorblind-safe
palette, matching the style used by the funcml package's theme_funcml().
theme_phynotype(base_size = 11)theme_phynotype(base_size = 11)
base_size |
Base font size. |
A ggplot2 theme object.
scale_color_phynotype(), scale_fill_phynotype()
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_clusters(fit) + theme_phynotype()fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) plot_clusters(fit) + theme_phynotype()
Compute internal and external validation metrics for a fitted clustering object or over a grid of candidate cluster counts.
validate( x, ..., method = "kmeans", k = NULL, truth = NULL, metrics = NULL, n_boot = 10 )validate( x, ..., method = "kmeans", k = NULL, truth = NULL, metrics = NULL, n_boot = 10 )
x |
A |
... |
Additional arguments passed to methods. |
method |
Clustering method used when |
k |
Candidate values of |
truth |
Optional integer or factor vector of reference labels. When supplied, the adjusted Rand index and normalized mutual information are appended to the metric table. |
metrics |
Optional character vector selecting a subset of metrics to
return (e.g. |
n_boot |
Number of bootstrap resamples for bootstrap ARI stability
(only for |
Silhouette width (Rousseeuw, 1987):
where is the mean intra-cluster distance and is the
minimum mean distance to any other cluster. Values near 1 indicate dense,
well-separated clusters.
Calinski-Harabasz index (Calinski and Harabasz, 1974):
where BSS is the between-cluster sum of squares and WSS is the within-cluster sum of squares. Higher values indicate better separation.
Davies-Bouldin index (Davies and Bouldin, 1979):
where is the mean intra-cluster scatter. Lower values are better.
Total within-cluster sum of squares:
Bootstrap ARI (Fang and Wang, 2012): mean adjusted Rand index between the reference partition and partitions fitted on bootstrap resamples.
Adjusted Rand index (Hubert and Arabie, 1985):
where is the expected index under random partitions. Values near 1
indicate agreement close to the reference.
Normalized mutual information (Strehl and Ghosh, 2002):
A cluster_validation object with components:
metrics_tableData frame with columns metric, value,
scale, direction.
per_cluster_tablePer-cluster mean silhouette widths, or
NULL.
Rousseeuw, P.J. (1987). Silhouettes: A graphical aid to the interpretation and validation of cluster analysis. Journal of Computational and Applied Mathematics, 20, 53–65.
Calinski, T. and Harabasz, J. (1974). A dendrite method for cluster analysis. Communications in Statistics, 3(1), 1–27.
Davies, D.L. and Bouldin, D.W. (1979). A cluster separation measure. IEEE Transactions on Pattern Analysis and Machine Intelligence, 1(2), 224–227.
Hubert, L. and Arabie, P. (1985). Comparing partitions. Journal of Classification, 2(1), 193–218.
Strehl, A. and Ghosh, J. (2002). Cluster ensembles: A knowledge reuse framework for combining multiple partitions. Journal of Machine Learning Research, 3, 583–617.
Fang, Y. and Wang, J. (2012). Selection of the number of clusters via the bootstrap method. Computational Statistics and Data Analysis, 56(3), 468–477.
cluster() to fit a solution, plot_silhouette() to visualize
per-observation silhouette widths, explore() for structural summaries.
fit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) # Internal metrics val <- validate(fit) val$metrics_table # External metrics with known labels val_ext <- validate(fit, truth = iris$Species) val_ext$metrics_table # Grid search over k values grid_val <- validate(iris[, 1:4], method = "kmeans", k = 2:5) grid_val$metrics_tablefit <- cluster(iris[, 1:4], method = "kmeans", k = 3, seed = 1) # Internal metrics val <- validate(fit) val$metrics_table # External metrics with known labels val_ext <- validate(fit, truth = iris$Species) val_ext$metrics_table # Grid search over k values grid_val <- validate(iris[, 1:4], method = "kmeans", k = 2:5) grid_val$metrics_table