ds@mcpanalytics.aiEmail your data and your question and get an answer about your own data, with the method shown.Email your data and question. Get an answer.

K-Means Clustering: Discover Natural Groups in Your Data

By MCP Analytics Team | Published , updated

You have customers, products, or transactions, and you suspect there are distinct groups hiding in the data, but you do not have labels telling you what those groups are. K-Means clustering finds them automatically. Upload a CSV with numeric features, and the algorithm partitions your data into coherent segments with cluster profiles, visualizations, and silhouette scores. No statistics degree required, no labels needed.

What Is K-Means Clustering?

K-Means is an unsupervised machine learning algorithm that groups similar data points together, without you telling it what the groups should look like. You give it data and a number of clusters (k), and it iteratively assigns each data point to the nearest cluster center, then recalculates the centers based on the assignments. After a few rounds, the clusters stabilize and you have k groups where the members within each group are as similar to each other as possible.

To find the natural groups in your own data and what sets each apart, try the free cluster analysis tool.

The classic example is customer segmentation. Suppose you have an e-commerce dataset with thousands of customers and you want to know: who are my best customers, who is at risk of leaving, and who only bought once? You could slice the data manually by revenue thresholds, but those cutoffs would be arbitrary. K-Means looks at the actual patterns (recency of last purchase, how often someone buys, how much they spend) and finds natural breakpoints. A hypothetical result might be four segments: Champions who buy frequently and spend heavily, Loyal customers with steady mid-range spending, At-Risk customers who used to buy often but have gone quiet, and Lost customers who bought once a year ago and never returned.

The algorithm works by minimizing the total within-cluster variance. Think of it as finding k points in the feature space (the centroids) such that every data point is as close to its assigned centroid as possible. The result is compact, spherical clusters where each centroid represents the "average member" of that group. This makes interpretation straightforward. You can describe each cluster by looking at the centroid values and immediately understand what makes that group different.

A Worked Example With Real Numbers

Here is a small test you can run yourself. We made a fake customer file with 240 rows and three columns: days since last order (recency), orders per year (frequency), and dollars spent per year (monetary). The data is made up. We built it from four groups on purpose, so we know the right answer. The random seed is 42, so you get the same file we did.

set.seed(42)
library(cluster)
mk <- function(n,r,f,m) data.frame(
  recency   = round(pmax(1, rnorm(n, r, r*0.25))),
  frequency = round(pmax(1, rnorm(n, f, f*0.25))),
  monetary  = round(pmax(5, rnorm(n, m, m*0.25))))
d <- rbind(mk(60,10,20,900), mk(90,45,10,350),
           mk(50,120,8,300), mk(40,300,1,60))
x <- scale(d)
for (k in 2:7) {
  set.seed(1); km <- kmeans(x, k, nstart = 25)
  cat(k, round(km$tot.withinss,1),
      round(mean(silhouette(km$cluster, dist(x))[,3]),3), "\n")
}
set.seed(1); km3 <- kmeans(x, 3, nstart = 25)
print(table(km3$cluster))
print(aggregate(d, list(cluster = km3$cluster), function(v) round(mean(v), 1)))

We ran this in R. It printed these numbers (k, within-cluster sum of squares, average silhouette):

kWithin-cluster sum of squaresAverage silhouette
2337.30.546
3113.30.642
494.50.591
575.80.414
664.30.424
753.70.413

The elbow is at k = 3, where the sum of squares falls from 337.3 to 113.3 and then flattens. The silhouette is also highest at k = 3 (0.642). So the data says three groups, even though we built four. Why? Two of our groups (last order 45 days ago and 120 days ago) have similar spend and frequency, so after scaling they run together. The last three lines of the code print the k = 3 profile (change 3 to 4 there to see the k = 4 split):

ClusterRowsAvg recency (days)Avg orders per yearAvg dollars per yearPlain-language label
114070.29.4329.2Slipping regulars
240311.01.055.3Lapsed one-timers
36010.020.5868.6Champions

With k = 4 the average silhouette drops to 0.591. The extra split cuts the champions, which we built as one group, into two (35 and 25 rows), while the slipping regulars stay merged. Lesson: k-means gives you a fair split, not the true one. Check the elbow, check the silhouette, and ask whether each group would get a different action. We ran the script three times and got identical output each time, because we set the seed.

Limits: this is synthetic data with clean, round groups. Real customer data is messier, and the silhouette numbers will usually be lower.

When to Use K-Means Clustering

K-Means is the right tool when you want to discover structure in data where no predefined categories exist. The most common business applications include customer segmentation (grouping buyers by purchasing behavior for targeted marketing), product categorization (grouping SKUs by sales velocity, margin, and seasonality), market research (identifying audience segments from survey responses), and inventory management (grouping products by demand patterns to optimize stocking).

Use K-Means when your goal is exploratory. You are not predicting a specific outcome, you are trying to understand what natural groupings exist in your data. This is fundamentally different from classification, where you already have labeled examples and want to predict the label for new cases. With clustering, the labels do not exist yet. You are asking the data to tell you what the groups are.

K-Means is also valuable as a preprocessing step before building predictive models. Once you have identified customer segments, you can build separate churn models for each segment, or tailor pricing strategies per cluster. The segments become a new feature that captures complex multi-dimensional patterns in a single categorical variable.

In practice, K-Means works best when your clusters are roughly spherical and similar in size. If you suspect your groups have irregular shapes: say, a dense core of loyal customers surrounded by a scattered ring of occasional buyers: consider DBSCAN instead, which handles non-spherical clusters naturally.

What Data Do You Need?

You need a CSV with numeric columns: the features you want to cluster on. The module takes up to three feature columns, mapped as feature_1, feature_2 and feature_3, and needs at least 10 complete rows. The report labels the three features recency, frequency and monetary, whatever they hold. Common setups include RFM features (recency, frequency, monetary value) for customer segmentation, or any set of numeric measurements that describe the entities you want to group.

Feature scaling matters. If one column is measured in dollars (range 0-10,000) and another in number of purchases (range 1-50), the dollar column will dominate the distance calculations and effectively ignore the purchase count. The module includes a scale_features parameter that standardizes all columns to the same scale before clustering. Leave this enabled unless your features are already on comparable scales.

The key decision is choosing k, how many clusters to create. If you do not know the right number, leave k_clusters empty (its default) and the module will evaluate a range from k_min to k_max (2 to 8 by default) and pick the k with the highest average silhouette. The elbow chart is shown alongside so you can check that choice. The elbow chart shows how the total within-cluster variance drops as k increases: the "elbow" where adding more clusters stops helping much is usually a good choice. The silhouette score measures how well-separated the clusters are, with higher scores indicating cleaner separation.

If you already know you want exactly four segments (say, based on business requirements), set k_clusters to 4 and the module will skip the search and cluster directly. The n_start parameter controls how many random starting configurations the algorithm tries: more starts reduce the chance of landing on a poor local solution. The module fixes the random seed, so the same file gives the same clusters each run.

There is no row count that guarantees a good result. As a rough starting point, we use a few dozen rows per cluster you expect (our worked example has 240 rows for 3 to 4 groups). This is our own rule of thumb, not a published threshold. With very few rows, one odd point can move a whole cluster, so run it with several seeds and see whether the groups hold. We have not published a tested maximum size. Above 2,000 rows the module clusters a random sample of 2,000 rows, so the report's tables describe that sample, not every row.

How to Read the Report

The report opens with an executive summary that states how many clusters it found, how many rows and features it used, the average silhouette, and the share of rows in the largest cluster. Clusters are numbered ("Cluster 1", "Cluster 2"), not named. You give them names from the profiles, as we did in the example above.

The Elbow Analysis shows total within-cluster sum of squares (WSS) on the y-axis and number of clusters on the x-axis. As k increases, WSS always decreases. More clusters means tighter groups. The useful signal is where the curve bends sharply. Before the elbow, each additional cluster captures meaningful structure. After the elbow, you are splitting natural groups into arbitrary pieces. The card text names the k the module chose.

The Silhouette Analysis measures cluster quality. Each data point gets a silhouette coefficient between -1 and 1. A value near 1 means the point fits its cluster well and is far from neighboring clusters. A value near 0 means the point sits on the boundary between clusters. A negative value means the point may be assigned to the wrong cluster. The average silhouette score across all points summarizes overall cluster quality. Kaufman and Rousseeuw (1990) suggest rough bands: above 0.7 strong structure, 0.5 to 0.7 reasonable, 0.25 to 0.5 weak and possibly artificial, and below 0.25 no real structure. The report's own wording is looser: it calls an average above 0.5 strong and 0.25 to 0.5 moderate. These cut-offs are guides, not laws, and what counts as good depends on your data.

The Cluster Visualization (PCA) card is the most visual section. Since your data may have many features, the report uses Principal Component Analysis to project everything down to two dimensions for plotting. Each point is a data record, colored by cluster assignment. Well-separated clusters appear as distinct clouds with minimal overlap. Overlapping clusters suggest the groups share many characteristics and may be hard to treat differently in practice.

The Cluster Profiles card is where interpretation happens. It shows each cluster's average of each feature, standardized across the clusters (a z-score), as a grouped bar chart. This is how you understand what makes each cluster different, Cluster A has high recency and low frequency (lapsed customers), Cluster B has low recency and high monetary value (active big spenders), and so on. The Cluster Summary provides the size of each cluster (number and percentage of data points), with the raw average of each feature, and the Customer Segments card lists up to 500 rows with their cluster and raw values. Its customer column is a row number, not your ID. It counts the rows the module kept (rows with a missing feature are dropped, and above 2,000 rows only the sample is listed), so it lines up with your file's row order only when no rows were dropped or sampled.

When to Use Something Else

If your clusters are not roughly spherical: for example, you have a dense core of normal transactions surrounded by scattered outliers: DBSCAN is a better fit. DBSCAN finds clusters of arbitrary shape and automatically identifies noise points (outliers) without requiring you to specify k upfront. It discovers the number of clusters from the data itself.

If you want a hierarchy of clusters, understanding not just "there are four segments" but how those segments relate to each other (are segments A and B more similar to each other than to C?): hierarchical clustering with a dendrogram gives you that tree structure. You can cut the tree at different levels to get different numbers of clusters.

If your data has many features (dozens or hundreds of columns), consider running PCA first to reduce dimensionality, then clustering on the first two or three principal components (this module takes at most three features). This removes noise from redundant features and often produces cleaner clusters. The K-Means report already uses PCA for visualization, but running PCA as a preprocessing step and clustering on fewer components can improve results with high-dimensional data.

If you want "soft" cluster assignments, where each data point gets a probability of belonging to each cluster rather than a hard assignment, Gaussian Mixture Models (GMM) are the natural extension. GMM treats each cluster as a Gaussian distribution and returns membership probabilities, which is useful when boundaries between groups are genuinely fuzzy.

For anomaly detection specifically, consider Isolation Forest instead. While K-Means can surface outliers (points far from any centroid), Isolation Forest is purpose-built for finding anomalies and handles them more robustly.

The R Code Behind the Analysis

Every report names its method and includes the R code that produced it, so you can reproduce, audit and cite it. The method code is fixed, not rewritten for each run. K-Means starts from random centers, so repeat runs only match when the random seed is fixed, as in the example above. The module fixes it. More starts (n_start) make a poor result less likely, but a different seed can still shift borderline points.

The analysis uses kmeans() from base R for the core clustering, with scale() for feature normalization. The k is chosen by the highest average silhouette() (from the cluster package, computed on a sample of up to 300 rows), and the within-cluster sum of squares is reported for the elbow chart. The PCA projection is built with prcomp() from base R. These are standard, widely used R functions, not custom implementations. The n_start parameter runs the algorithm several times from different random starts and keeps the best result, which makes a poor local solution less likely. Every step is visible in the code tab of your report, so you or a data scientist can check exactly what was done.

Sources

Your turn

Bring your own data and the question you actually need answered.

MCP AnalyticsData science by email Send us your data and your question, and we will reply. ds@mcpanalytics.ai