11.5 多维标度法¶
小率拿来一张城市距离表:每两个城市之间有多远都知道,但没有经纬度。他想只靠这张距离表,把城市的相对位置画出来。
| 城市 | A | B | C | D |
|---|---|---|---|---|
| A | 0 | 5 | 9 | 10 |
| B | 5 | 0 | 7 | 8 |
| C | 9 | 7 | 0 | 4 |
| D | 10 | 8 | 4 | 0 |
只有距离,没有坐标,也能画地图吗?
能。MDS 就是把距离矩阵还原成低维坐标。
11.5.1 从距离表反推坐标¶
多维尺度分析(Multidimensional Scaling, MDS)的输入不是原始变量表,而是样本两两之间的距离矩阵。它输出一组低维坐标,让新坐标里的点间距离尽量接近原来的距离。
如果原始距离是 \(d_{ij}\),低维坐标是 \(z_i\)、\(z_j\),MDS 希望:
\[
\|z_i-z_j\|\approx d_{ij}
\]
它不是在看变量,而是在看“谁离谁近”。
对,所以 MDS 特别适合品牌相似度、城市距离、样本距离这类数据。
11.5.2 经典 MDS:欧氏距离的代数解¶
经典 MDS 适合欧氏距离。它先把距离矩阵转成内积矩阵,再做特征分解:
\[
B=-\frac12 JD^{(2)}J
\]
其中:
\[
J=I-\frac1n\mathbf{1}\mathbf{1}^\top
\]
对 \(B\) 做特征分解后,取前 \(k\) 个正特征值和对应特征向量,就能得到低维坐标。
你知道吗
如果距离来自原始数据的欧氏距离,经典 MDS 与 PCA 有很深的联系:一个从数据矩阵出发,一个从距离矩阵出发,最后都在寻找低维表示。
11.5.3 度量 MDS:用 Stress 衡量还原误差¶
度量 MDS 直接最小化距离误差。常用指标叫 Stress:
\[
\text{Stress}=\sqrt{\frac{\sum_{i<j}(\hat d_{ij}-d_{ij})^2}{\sum_{i<j}d_{ij}^2}}
\]
Stress 越小,说明低维图越好地保留了原距离。
| Stress | 读法 |
|---|---|
| < 0.05 | 很好 |
| 0.05-0.10 | 良好 |
| 0.10-0.20 | 勉强可用 |
| > 0.20 | 低维图可能误导 |
11.5.4 方向和镜像不重要¶
MDS 只保留距离,所以输出图整体平移、旋转、翻转都不算错。城市图如果上下颠倒,只要城市之间的相对距离对,旋转一下就好。
也就是说,MDS 图的坐标轴本身没什么物理含义?
对。别执着坐标轴,先看距离结构。
11.5.5 用 Python 跑 MDS¶
完整脚本放在:
import numpy as np
from sklearn.manifold import MDS
D = np.array([
[0, 5, 9, 10],
[5, 0, 7, 8],
[9, 7, 0, 4],
[10, 8, 4, 0],
], dtype=float)
mds = MDS(
n_components=2,
dissimilarity="precomputed",
random_state=42,
normalized_stress="auto",
)
Z = mds.fit_transform(D)
print("二维坐标:")
print(np.round(Z, 2))
print("Stress:", round(mds.stress_, 3))
11.5.6 MDS 和 t-SNE、UMAP 的关系¶
| 方法 | 主要保留 | 适合 |
|---|---|---|
| PCA | 方差 | 线性降维、解释主轴 |
| MDS | 两两距离 | 距离矩阵、相似度数据 |
| t-SNE | 局部邻域 | 只为看簇 |
| UMAP | 局部结构兼顾全局 | 大数据可视化 |
需要注意
t-SNE 图上簇之间的远近不一定可信;MDS 更直接地把“距离保留”作为目标,但高维复杂结构压到二维时也会有损失。
小率的笔记本
MDS 的输入是距离矩阵,输出是低维坐标。它尽量让低维图上的点间距离接近原距离;Stress 用来衡量还原误差。MDS 图可以整体旋转或镜像,坐标轴方向不需要过度解释。

