Using the elbow method, I determine the correct number of clusters for the KMeans function. Having done that, I still have no idea how to interpret the clusters in a meaningful way. If someone asked me what any of the clusters represent, I have no idea how to answer that. Is there a way to use the results of KMeans to assign some sort of meaningful label to the clusters?
Clustering is descriptive: a central point in each cluster serves as a surrogate, or approximate descriptor of, the points in the cluster. Use the coordinates of these central points for labels.
As an idea for consideration--certainly not as the only or even the best approach--you could assess how far each central coordinate is from a center of all the data. Do this on a relative basis, as with a z score. Characterize the coordinates according to whether they are smaller or larger than average. Maybe modify those characterizations according to how far from average they are.
Here is an example using the four-dimensional "Iris" dataset of 150 observations with two k-means clusters. First, the cluster centers (heavily rounded):
Sepal Length Sepal Width Petal Length Petal Width 1 6 3 5 2.0 2 5 3 2 0.3
Next, their (rounded) Z-scores. These are defined, as usual, as the difference between a coordinate and the dataset mean for that coordinate, all divided by the standard deviation in the dataset:
Sepal Length Sepal Width Petal Length Petal Width 1 0.6 -0.4 0.7 0.7 2 -1.0 0.7 -1.0 -1.0
Using (arbitrarily) a rounded threshold of $1$ to intensify the characterizations of "high" or "low" values produces this summary:
Cluster Sepal Length Sepal Width Petal Length Petal Width 1 High --- High High 2 Very Low High Very Low Very Low
The "labels" are the lines--but now each line is highly interpretable in a qualitative sense. Cluster 1 consists of observations with relatively high sepal lengths and petal sizes. Cluster 2 consists of observations with extremely low sepal lengths and petal sizes (and, incidentally, somewhat high sepal widths). Thus, going just a little further, we might say the clusters are distinguished by sepal shape and petal size.
This is the
R code that produced these results, automatically. Apart from the initial data-input block, it generalizes to any numerical array of data like
iris. It was written in a relatively straightforward manner to assist porting it to other platforms.
# # Data. # data(iris) iris <- iris[, -5] colnames(iris) <- paste(" ", gsub("[.]", " ", colnames(iris))) # # K-means. # x <- kmeans(iris, 2) # # Automatic label assignment. # threshold <- 1 # Adjust as desired. s <- apply(iris, 2, sd) # Column standard deviations m <- colMeans(iris) # Column means z <- t((t(x$centers) - m) / s) # Z-scores of the centers pos <- sapply(round(z), function(u) switch(2+sign(u), "Low", "---", "High")) mod <- ifelse(abs(z) >= threshold, "Very ", "") # Intensifiers labels <- paste0(mod, pos) # # Output. `signif` rounds its first argument to the given number of decimals. # print(signif(x$centers, 1)) print(signif(z, 1)) print(array(labels, dim(z), list(Cluster=rownames(z), colnames(z))), quote=FALSE, right=TRUE)