Mistake: energy is the sum of singular values
“The singular values are [5, 3, 1]. Keeping the top two keeps 8/9 of the energy, about 89% — less than 95%.”
spectrum_example = np.array([5., 3., 1.])
wrong_retention = spectrum_example[:2].sum() / spectrum_example.sum()
correct_retention = (spectrum_example[:2]**2).sum() / (spectrum_example**2).sum()
assert wrong_retention < 0.95 <= correct_retention
Energy is squared amplitude. The squares are 25, 9 and 1, so the correct ratio is 34/35 — about 97%, over the 95% line — not 8/9.
Summing raw singular values understates how much the top components keep, and picks a rank that is larger than needed.