import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.metrics import confusion_matrixGraduate Quantitative Economics and Datascience
Formally,
\[ \min_{\mathbf{S}} \sum_{k=1}^K \frac{1}{2|S_k|}\sum_{n, n' \in S_k} \|x_n - x_{n'}\|_2^2 \]
Using standard Euclidean norm between two elements in \(S_k\)
\[ \|x_n - x_{n'}\|_2^2 = \sum_{m=1}^M (x_{nm} - x_{n'm})^2 \]
Can prove that the previous objective is equivalent to minimizing the sum of the squared distances from the group \(k\)’s mean
\[ \min_{\mathbf{S}} \sum_{k=1}^K \sum_{n \in S_k} \|x_n - \bar{x}_k\|_2^2 \]
Where the mean of group \(k\) is standard, and across all \(m\) features
\[ \bar{x}_k \equiv \frac{1}{|S_k|}\sum_{n \in S_k} x_n \]
Avoid different scales so the distances aren’t dominated by one feature
KMeans in scikit-learn runs this n_init times from different starts and keeps the lowest objective; fix random_state for reproducibilityTwo groups differ only in feature \(1\); feature \(2\) is noise on the same scale. Multiply feature \(2\) by \(1000\) and rerun k-means with \(K = 2\).
What does the partition look like?
A. Unchanged
B. Split by feature \(1\) alone
C. Split mostly by feature \(2\)
D. k-means fails to converge
np.random.seed(14)
mu_1 = np.array([0.0, 0.0]) # mean of k=1
mu_2 = np.array([1.0, 1.0]) # mean of k=2
sigma = np.array([[0.2, 0], [0, 0.2]]) # use same variance
N = 100 # observations per group
X_1 = np.random.multivariate_normal(mu_1, sigma, N)
X_2 = np.random.multivariate_normal(mu_2, sigma, N)
df_1 = pd.DataFrame({"f1": X_1[:, 0], "f2": X_1[:, 1], "k": 1})
df_2 = pd.DataFrame({"f1": X_2[:, 0], "f2": X_2[:, 1], "k": 2})
df = pd.concat([df_1, df_2], ignore_index=True)Suppose a run with two groups gives a correlation of \(-0.98\) between the true \(k\) and the assigned \(\hat{k}\).
Did k-means fail?
A. Yes: a success is near \(+1\)
B. No: cluster labels are arbitrary
C. Yes: the clusters are inverted
D. Cannot tell without the confusion matrix
Label ordering is arbitrary, so the confusion matrix might require reordering to compare
Use Economics, and don’t rely on technical tools alone
Run k-means with \(K = 2\) on a single Gaussian blob with no latent groups.
What happens?
A. One cluster comes back empty
B. It returns an error
C. Every point goes in one cluster
D. It splits the blob into two groups anyway, cutting across its longest axis
Take the global optimum of the k-means objective for each \(K\).
How does the within-cluster sum of squares move as \(K\) increases?
A. It weakly decreases, reaching \(0\) at \(K = N\)
B. It can rise or fall
C. It strictly increases
D. It is constant once \(K\) passes the true number of groups
k-means with two different random_state values returns different partitions on the same data.
Why?
A. The data have no clusters
B. The seed changes the distance norm
C. k-means is randomized by design, so both partitions are correct
D. The objective has many local minima, and the assign-then-average iteration stops at one that depends on the starting centers
n_init above \(1\) runs several starts and keeps the lowest objective; the default is a single start.n_init.