Cursus
After you've trained a clustering model, how do you know if the clusters are any good?
There's no universal answer. In traditional supervised learning, you can compare predictions against actual labels and get an accuracy number. You can't do that with clustering. You picked k=5, but would a different k value be better? Without labels, you can't tell if the algorithm found the structure or just divided the data into random chunks.
The silhouette score is the metric you're looking for. It shows how well each point fits its assigned cluster relative to the next-closest one, and it's one of the most widely used metrics. It works without labels and it's easy to interpret.
In this article, I'll walk you through the formula and how to read it, show you a Python example with scikit-learn, and cover scenarios when it is and isn't an ideal solution.
Are you new to clustering? Read our Introduction to k-Means Clustering with scikit-learn tutorial to learn how the algorithm works and how to use it in Python.
What Is the Silhouette Score?
The silhouette score is a number between -1 and 1 that tells you how well each point fits its cluster.
The number shows you two things:
- How close a point is to the other points in its own cluster
- How far it is from the nearest cluster it doesn't belong to
If the point is well inside its own group and far from any other, the score is high. If it's on the edge, closer to a neighboring cluster than to its own, the score is low.
In a nutshell, that's the balance the silhouette score shows you. It includes both how closely points are grouped within each cluster and how well the clusters are separated from one another. Both are equally relevant. A clustering that groups points well but places clusters right on top of each other isn't useful, and neither is clustering that separates clusters well but scatters points loosely within them.

Well-separated clusters compared with overlapping clusters
Higher scores mean better-defined clusters. A score near 1 means points are positioned tightly inside their cluster and far from others. A score near 0 means the clusters overlap or the boundaries are ambiguous. A negative score means the point is closer to a different cluster than the one it was assigned to.
How Does the Silhouette Score Work?
Every point gets its own silhouette score, and that score comes from two distances.
The first is how far the point is from the other points in its assigned cluster, on average. If it's small, the point is near the others in the cluster. If it's large, the point is loosely attached to its cluster.
The second is how far the point is from the points in the nearest neighboring cluster, on average. If it's large, the point is clearly separated from other clusters. If it's small, the point is close to the boundary.

Distance of a point to the clusters
The silhouette value compares these two numbers. A point well inside its cluster and far from any other gets a high score. A point on the edge (close to another cluster) gets a low score. A point that's closer to a different cluster than its own gets a negative score.
A thing to remember here is that neither distance is enough alone.
A tight cluster can be positioned right next to another one. A well-separated cluster can be internally scattered. You need both distances to trust the assignment.
Silhouette Score Formula
Here's the formula for a single point:

Silhouette score formula
Where:
-
ais the average distance from the point to all other points in the same cluster -
bis the average distance from the point to all points in the nearest neighboring cluster
The formula divides the gap between b and a by whichever of the two is larger.
In general, you can use these guidelines to interpret the score:
-
When
bis much larger thana: The point is far from any other cluster and close to its own. The numerator is close tob, the denominator is alsob, and the score is close to 1 -
When
ais much larger thanb: The point is closer to another cluster than to its own. The numerator is a large negative number close to-a, the denominator isa, and the score is close to -1 -
When
aandbare roughly equal: The point is on the boundary between two clusters. The numerator is close to 0, and so is the score
More on the specifics next.
How to Interpret the Silhouette Score
Here's a rough guide for reading the silhouette score:
- Close to 1: Points are well inside their clusters and far from any others
- Around 0.7: Good clustering, groups are distinct and points are near the other points in their cluster
- Around 0.5: Reasonable clustering, there's some overlap between clusters, but they're still distinguishable
- Near 0: Clusters overlap or the boundaries are unclear. The structure may not be real
- Below 0: Points are closer to the wrong cluster. This can happen when you choose the wrong number of clusters or the data doesn't cluster well in the first place.
The cutoffs above are just rough guides. What counts as a good silhouette score depends on the dataset.
Sparse and high-dimensional data often produces lower scores even when the clusters are good. Densely packed, well-separated data can produce scores above 0.7. You should compare scores across models on the same dataset, not against a universal threshold.
How to Calculate the Silhouette Score
You calculate the silhouette score one point at a time. Here's how it works for a single point.
Step 1: Calculate a, the average distance from the point to every other point in its own cluster. If the point is in a cluster with 4 other points, and the distances to those points are 1.2, 1.5, 1.0, and 1.3:

Silhouette score calculation (1)
Step 2: Find the nearest neighboring cluster (the one, other than the point's own, with the lowest average distance from the point). Then calculate b, the average distance from the point to every point in that cluster. If the nearest cluster has 5 points at distances 2.4, 2.8, 3.0, 2.6, and 2.7:

Silhouette score calculation (2)
Step 3: Add a and b into the formula:

Silhouette score calculation (3)
Step 4: Repeat this for every point in the dataset. The overall silhouette score for the clustering is the average of all point scores.
Silhouette Score Example in Python
Scikit-learn gives you two functions for computing the silhouette score, both inside sklearn.metrics:
-
silhouette_score()returns the average score for the whole clustering -
silhouette_samples()returns the score for each individual point
Here's how to use them with KMeans on a synthetic dataset:
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score, silhouette_samples
# Synthetic data with 4 clusters
X, _ = make_blobs(n_samples=500, centers=4, cluster_std=1.0, random_state=42)
# Clustering model
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
# Overall silhouette score
score = silhouette_score(X, labels)
print(f"Overall silhouette score: {score:.3f}")
# Per-point silhouette values
sample_scores = silhouette_samples(X, labels)
print(f"First 5 point scores: {sample_scores[:5]}")
You'll get this output when you run the above code snippet:

Python example output
The overall score of 0.791 means the four clusters are well-defined and separated.
The per-point scores let you analyze every data point.
Points with high individual scores are well inside their clusters. Points with low or negative scores are on the boundary or misassigned, which is handy for spotting outliers or reviewing borderline points.
Choosing the Optimal Number of Clusters
One of the most common uses of the silhouette score is picking the right k for KMeans.
Doing so includes three steps:
- Fit KMeans for a range of k values
- Calculate the silhouette score for each fit
- Pick the
kwith the highest score
Here's the code for it:
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score
X, _ = make_blobs(n_samples=500, centers=4, cluster_std=1.0, random_state=42)
# Fit KMeans for k=2 to k=10 and keep track of the silhouette score for each
k_values = range(2, 11)
scores = []
for k in k_values:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
scores.append(silhouette_score(X, labels))
print(f"k={k}: silhouette = {scores[-1]:.3f}")
This is the output score you'll see for each k:

Silhouette score across different values of k
The highest score is at k=4. That's the value you'd want to pick.
A thing to keep in mind is that the silhouette score doesn't replace domain knowledge. If your business problem calls for 5 customer segments and the silhouette is the highest at 4, don't automatically go with 4. The metric shows you where the data has the cleanest structure, but sometimes the right number of clusters is the one that corresponds with something meaningful in your problem.
Silhouette Score vs. Other Clustering Metrics
The silhouette score is probably the most common metric to evaluate clustering, but it isn't the only one. Here's how it compares to the alternatives.
Silhouette score vs. elbow method
The elbow method is a visual technique for choosing k in KMeans. You fit models for a range of k values, plot the inertia (within-cluster sum of squares) against k, and pick the value where the curve has a sharp bend.
The elbow method has the advantage here because it's fast and easy to run. But the "elbow" isn't always obvious. On messy data, the curve can sometimes look smooth and you can't tell where it bends.
The silhouette score gives you an actual number for each k, so you can make a more meaningful comparison. It's slower to compute, but doesn't leave the decision up to visual interpretation.
Use the elbow method for a quick sanity check. Use the silhouette score when you need an answer you can stand behind.
Silhouette score vs. Davies-Bouldin index
The Davies-Bouldin index (DBI) measures the average similarity between each cluster and its most similar one. Lower DBI means better clustering, and a perfect score is 0.
DBI uses cluster centroids to calculate similarity, which makes it faster to compute than the silhouette score on large datasets. It also uses a similar intuition in regards to rewarding tight and well-separated clusters.
The catch is that DBI only tells you about the clustering as a whole. The silhouette score gives you a per-point score too, so you can find borderline points and outliers.
Use DBI if you're working with big datasets and speed matters. Use the silhouette score when you want to look at individual points.
Silhouette score vs. Calinski-Harabasz index
The Calinski-Harabasz index (CH), also called the variance ratio criterion, is the ratio of between-cluster dispersion to within-cluster dispersion. Higher scores mean better clustering, and the score is unbounded (no upper limit).
CH is fast and works well on large datasets because it only involves cluster-level statistics. Like silhouette and DBI, it works best on convex, well-separated clusters.
CH also doesn't have a natural scale, so you can only compare CH scores across models on the same dataset, not across different datasets.
Use CH when your dataset is large and you need to get the results fast. Use the silhouette score when you want interpretability and insights for individual data points.
Internal vs. external clustering metrics
The metrics above (silhouette, DBI, CH, elbow) are all internal metrics. They evaluate clustering using only the data itself, without ground-truth labels. That makes them the standard choice for real-world clustering problems, where labels don't exist.
External metrics compare cluster assignments against known labels. The Adjusted Rand Index (ARI), Normalized Mutual Information (NMI), and homogeneity are common examples. They're used when you have labels and want to test how well a clustering algorithm gets them.
Use internal metrics when you don't have labels, which is the typical case. Use external metrics when you're benchmarking clustering algorithms on labeled data.
Here's a recap of the metrics side by side:
| Method | Range | Best value | Speed | Use it for |
|---|---|---|---|---|
| Silhouette score | -1 to 1 | Close to 1 | Slow on large datasets | Interpretability and per-point insights |
| Elbow method | 0 to infinity | Look for the elbow | Fast | Quick checks |
| Davies-Bouldin index | 0 to infinity | Close to 0 | Fast | Large datasets |
| Calinski-Harabasz index | 0 to infinity | Higher is better | Fast | Large, unlabeled datasets |
Silhouette score compared to alternatives
Limitations of the Silhouette Score
The silhouette score has a few limitations worth knowing about:
- Assumes distance-based clustering: The silhouette score is based on Euclidean distance by default. It works well for KMeans and other centroid-based algorithms, but doesn't fit density-based methods like DBSCAN, where clusters have arbitrary shapes and no clear centroid
- Works best with smaller, well-separated clusters: The metric rewards tight, spherical clusters that are far apart. If your data has clusters that are close together or overlapping, the score will be low even if the clustering is correct
- Not the best with irregular cluster shapes: Real-world clusters aren't always convex. If that's not the case for your data, clusters get low silhouette scores even when the assignments are correct
- Computational cost on large datasets: Calculating the silhouette score requires pairwise distances between points, which scales as
O(n^2). On datasets with millions of points, this becomes expensive - Sensitivity to the chosen distance metric: The score changes depending on whether you use Euclidean, Manhattan, cosine, or another distance. If your data doesn't follow Euclidean assumptions, the silhouette score can mislead you
Best Practices for Using the Silhouette Score
The silhouette score works best when you follow a few basic practices:
- Compare multiple clustering solutions: Don't calculate just a single silhouette score. You should fit clustering models with different values of
k(or different algorithms) and compare their scores side by side - Visualize clusters alongside the score: A number alone doesn't tell the full story. Plot your clusters and look at if the shapes make sense
- Don't optimize only for the highest score: The highest silhouette score isn't always the right answer. A clustering with k=2 often has a higher score than
k=5even when 5 clusters are meaningful in your problem - Combine with domain knowledge: The score tells you where the data has the cleanest structure. Domain knowledge tells you which structure is actually useful. Use both
- Evaluate multiple clustering metrics: Silhouette, DBI, CH, and other metrics measure clustering quality differently. When they agree, you're on a good track, but when they don't, look at the data
Conclusion
The silhouette score is one of the most intuitive ways to evaluate clustering because it shows both how tightly points are grouped and how well clusters are separated.
You calculate it point by point, average the results, and get a single number between -1 and 1. Scores closer to 1 mean better-defined clusters, and scores near or below 0 mean the structure isn't really a structure
But the silhouette score is just a beginning. You should pair it with cluster visualizations, and most importantly, your own domain knowledge of the problem. Only when all of these point in the same direction can you trust the result.
Silhouette score is part of the bigger picture of Unsupervised Learning in Python. Enroll today and learn how to cluster, transform, visualize, and extract insights from unlabeled data.
