要建立几何直觉,首先考虑一个最简单的场景。假设我们有一个实验,其样本空间 只包含 个离散的、等概率的结果,即 。在这个样本空间上定义一个随机变量 。根据定义,随机变量是一个从样本空间到实数的映射函数。这意味着,对于每一个实验结果 ,随机变量 都会赋予它一个具体的数值 。
我们可以将这 个数值排列成一个列向量:
这个 维的向量 ,在几何上完整地代表了随机变量 。向量的每一个分量,都对应于一种可能的状态。比如,这个向量 就是我们从数据库中取出的一列数据。例如过去天某只股票的收盘价,那么向量 的每个分量就是某一天的具体价格。即可以定义另一个随机变量 ,它也对应于一个 维的向量 ,其中对于连续随机变量,这个 维空间会推广为无限维的希尔伯特空间(Hilbert Space),但其核心的几何性质与有限维空间是完全一致的。
在上一节中,我们反复强调协方差是关于去中心化的。现在来看看这个代数操作的几何意义。
随机变量 的期望(均值),在我们的 维向量空间中,就是向量 所有分量的算术平均值:
一个去中心化随机变量 ,对应于一个新的向量 ,其每一个分量都是原始分量减去均值:
其中 是一个所有分量都为1的向量。这个操作的几何和意义相当于将原始数据向量 的起点,平移到数据的重心或质心处。
性质1:去中心化后的向量 的所有分量之和恒等于0。
证明:
性质1的结果表明:,去中心化向量 与向量 是正交(Orthogonal)的,因为它们的内积 。
在本文后续讨论协方差的几何意义时,我们用小写字母 和 表示的向量,如非特别指出,均为去中心化数据向量。
两个去中心化向量 和 的内积(或称点积,Dot Product),在 维空间中定义为它们对应分量的乘积之和:
回顾一下样本协方差的计算公式:
可以得出:
上式结果表明:协方差,在几何上,就是两个去中心化数据向量的内积,再除以一个与样本量相关的标量 。
我们知道,内积的几何定义是:
其中 和 分别是向量 和 的欧几里得范数(即向量的长度), 是这两个向量之间的夹角。
结合这两个等式,进一步可以得到:
这个公式从几何层面揭示了协方差的符号来源,即 表明 ,即向量夹角 是一个锐角,两个数据向量在 维空间中指向大致相同的方向; 表明 ,即向量夹角 是一个钝角,两个数据向量在 维空间中指向大致相反的方向; 表明 ,即向量夹角 ,两个数据向量在 维空间中相互正交。
通过Python代码。我们将生成两个只有3个观测值()的数据向量,将它们在三维空间中可视化,并展示它们的去中心化、内积和协方差之间的精确关系。
import numpy as npimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d import Axes3Dplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = False# 设定随机种子np.random.seed(1)# 生成两个原始数据向量,每个向量有 3 个分量 (N=3)X = np.random.rand(3) * 10Y = 0.5 * X + np.random.rand(3) * 3# 1. 计算均值mean_X = np.mean(X)mean_Y = np.mean(Y)# 2. 计算去中心化向量 x 和 yx_centered = X - mean_Xy_centered = Y - mean_Y# 3. 计算几何量# 内积 (dot product)dot_product = np.dot(x_centered, y_centered)# 向量长度 (Euclidean norm)norm_x = np.linalg.norm(x_centered)norm_y = np.linalg.norm(y_centered)# 向量夹角的余弦值cos_theta = dot_product / (norm_x * norm_y)# 夹角(弧度转角度)theta_deg = np.rad2deg(np.arccos(cos_theta))# 4. 计算统计量# 样本协方差# 注意:np.cov 默认使用 N-1 作为分母cov_xy = np.cov(X, Y)[0, 1]# 验证关系:Cov = dot / (N-1)N = len(X)calculated_cov_from_dot = dot_product / (N - 1)# 5. 可视化fig = plt.figure(figsize=(10, 8))ax = fig.add_subplot(111, projection='3d')# 绘制去中心化向量 x 和 y# 向量起点为原点(0,0,0)ax.quiver(0, 0, 0, x_centered[0], x_centered[1], x_centered[2], color='#d73027', arrow_length_ratio=0.1, linewidth=3, label='去中心化向量 $\\mathbf{x}$')ax.quiver(0, 0, 0, y_centered[0], y_centered[1], y_centered[2], color='#4575b4', arrow_length_ratio=0.1, linewidth=3, label='去中心化向量 $\\mathbf{y}$')# 设置坐标轴范围max_val = np.max(np.abs(np.concatenate([x_centered, y_centered]))) * 1.2ax.set_xlim([-max_val, max_val])ax.set_ylim([-max_val, max_val])ax.set_zlim([-max_val, max_val])ax.set_xlabel('观测 1 的偏差', fontsize=12)ax.set_ylabel('观测 2 的偏差', fontsize=12)ax.set_zlabel('观测 3 的偏差', fontsize=12)ax.set_title('协方差的几何本质:去中心化向量的内积', fontsize=16)# 添加文本信息info_text = (f"原始数据 X = {np.round(X, 2)}\n"f"原始数据 Y = {np.round(Y, 2)}\n"f"-----------------------------------------\n"f"去中心化向量 $\\mathbf{{x}}$ = {np.round(x_centered, 2)}\n"f"去中心化向量 $\\mathbf{{y}}$ = {np.round(y_centered, 2)}\n"f"-----------------------------------------\n"f"内积 $\\mathbf{{x}} \\cdot \\mathbf{{y}}$ = {dot_product:.2f}\n"f"向量夹角 $\\theta$ = {theta_deg:.1f}° (锐角)\n"f"-----------------------------------------\n"f"样本协方差 Cov(X,Y) = {cov_xy:.2f}\n"f"验证:内积 / (N-1) = {dot_product:.2f} / 2 = {calculated_cov_from_dot:.2f}")# 使用 figtext 在画布的固定位置添加文本框plt.figtext(0.05, 0.2, info_text, fontsize=11, bbox=dict(boxstyle='round', facecolor='white', alpha=0.8))ax.legend()plt.show()执行结果如下:

由途中可以看到一个三维空间中的两个向量。这两个向量代表了我们仅有的3个样本数据去中心化后的状态。
图表左侧的文本框详细地列出了每一步的计算结果,可以得出:
①内积的符号决定了协方差的符号;
②内积的大小与协方差成正比。
在上一节中,我们证明了协方差的一个特例:。现在我们来看看这个代数恒等式的几何意义。
当我们将 替换为 时,我们的几何对象就变成了去中心化向量 与其自身的内积:
这个内积等于向量 长度的平方。这个平方和 在统计学中被称为离差平方和(Sum of Squared Deviations)。
再来看方差的定义:
因此,我们得到了方差的几何解释:
方差,在几何上,就是去中心化数据向量长度的平方,再除以一个与样本量相关的标量 。
这个结论表明:一个随机变量的波动性(方差)越大,意味着它的数据点偏离均值的程度越剧烈,这在几何上就表现为它的去中心化数据向量 在 维空间中伸展得越长。
将已经推导出了协方差的几何表达式:
以及方差的几何表达式:
代入皮尔逊相关系数 的定义公式中:
即
可以得出:
结果表明:皮尔逊相关系数在几何上,就是两个去中心化数据向量之间夹角的余弦值。
这个等式将一个复杂的、带有单位的、受尺度影响的统计量(协方差),通过几何的视角,转化成了一个无量纲的、只描述方向关系的几何量(夹角余弦)。
通过上述等式也可以证明皮尔逊相关系数的边界范围,而无需使用柯西-施瓦茨不等式。其中:
我们用一段Python代码来直观地展示不同相关系数下的向量夹角。我们将固定向量的长度,只旋转其中一个向量,并观察相关系数如何随着夹角的变化而平滑地变化。
import numpy as npimport matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = False# 为了便于在 2D 平面可视化,我们假设 N=2# 定义一个固定的去中心化向量 xx_centered = np.array([2.0, 0.0])# 创建一个 1x3 的子图布局fig, axes = plt.subplots(1, 3, figsize=(18, 6))fig.suptitle('皮尔逊相关系数的几何本质:向量夹角的余弦值', fontsize=18)# 场景1:锐角(正相关)theta1 = np.deg2rad(30) # 30度角rotation_matrix1 = np.array([[np.cos(theta1), -np.sin(theta1)], [np.sin(theta1), np.cos(theta1)]])y_centered1 = np.dot(rotation_matrix1, x_centered)corr1 = np.dot(x_centered, y_centered1) / (np.linalg.norm(x_centered) * np.linalg.norm(y_centered1))# 场景2:直角(不相关)theta2 = np.deg2rad(90) # 90度角rotation_matrix2 = np.array([[np.cos(theta2), -np.sin(theta2)], [np.sin(theta2), np.cos(theta2)]])y_centered2 = np.dot(rotation_matrix2, x_centered)corr2 = np.dot(x_centered, y_centered2) / (np.linalg.norm(x_centered) * np.linalg.norm(y_centered2))# 场景3:钝角(负相关)theta3 = np.deg2rad(150) # 150度角rotation_matrix3 = np.array([[np.cos(theta3), -np.sin(theta3)], [np.sin(theta3), np.cos(theta3)]])y_centered3 = np.dot(rotation_matrix3, x_centered)corr3 = np.dot(x_centered, y_centered3) / (np.linalg.norm(x_centered) * np.linalg.norm(y_centered3))scenarios = [ (axes[0], y_centered1, theta1, corr1, '锐角 (正相关)'), (axes[1], y_centered2, theta2, corr2, '直角 (不相关)'), (axes[2], y_centered3, theta3, corr3, '钝角 (负相关)')]for ax, y_vec, angle_rad, corr, title in scenarios:# 绘制向量 x ax.quiver(0, 0, x_centered[0], x_centered[1], angles='xy', scale_units='xy', scale=1, color='#d73027', width=0.015, label='向量 $\\mathbf{x}$')# 绘制向量 y ax.quiver(0, 0, y_vec[0], y_vec[1], angles='xy', scale_units='xy', scale=1, color='#4575b4', width=0.015, label='向量 $\\mathbf{y}$')# 绘制夹角弧线 angle_deg = np.rad2deg(angle_rad) arc = plt.matplotlib.patches.Arc((0, 0), 1.0, 1.0, angle=0, theta1=0, theta2=angle_deg, color='black', linestyle='--') ax.add_patch(arc) ax.text(0.6 * np.cos(angle_rad / 2), 0.6 * np.sin(angle_rad / 2), f'$\\theta={angle_deg:.0f}^\\circ$', fontsize=14)# 设置坐标轴 ax.set_xlim(-2.5, 2.5) ax.set_ylim(-2.5, 2.5) ax.set_aspect('equal') ax.axhline(0, color='grey', lw=0.5) ax.axvline(0, color='grey', lw=0.5) ax.set_title(f'{title}\n$\\rho = \\cos({angle_deg:.0f}^\\circ) = {corr:.2f}$', fontsize=15) ax.legend(loc='upper right')plt.tight_layout(rect=[0, 0.03, 1, 0.93])plt.show()执行结果如下:

这三幅图清晰地展示了相关系数与向量夹角之间的对应关系。
这个几何视角还为我们解释了第一节中反复强调的一个误区:为什么相关系数只能度量线性关系?
这是因为夹角余弦这个几何工具,本身就是为线性空间中的向量关系而设计的。它衡量的是一个向量在另一个向量方向上的线性投影长度。
如果两个数据向量之间存在完美的非线性关系(例如,一个向量是另一个向量各分量的平方),那么在 维空间中,这两个向量会呈现出某种弯曲的正交关系。尽管它们在拓扑上紧密相连,但在欧几里得线性投影的意义下,它们的夹角可能依然是90度。
在线性回归中,我们的目标是找到一个最优的系数 ,使得预测值 能够最好地拟合真实值 。所谓的“最好”,通常是通过最小二乘法(Ordinary Least Squares, OLS)来定义的,即最小化残差的平方和:
注意:此处因为向量 系去中心化向量,所有没有截距项,若 为一般向量,则最小二乘法需要确定的是
其中系截距项
现在,我们有两个去中心化数据向量 和 。我们希望找到一个标量 ,使得向量 能够最接近向量 。向量 必然位于向量 所在的直线上。
那么,从向量 的终点到向量 所在直线的最短距离是什么?在线性代数中,这个最短距离是通过正交投影(Orthogonal Projection)得到的。最优的 ,就是向量 在向量 上的正交投影向量,我们记为 。
根据线性代数,投影向量的计算公式为:
将这个公式与我们的回归模型 进行对比,我们可以立刻得到最优回归系数 的几何表达式:
我们知道 且
代入上式可以得出简单线性回归系数的经典统计学公式:
表明最小二乘线性回归,在几何上,就是将被预测向量 正交投影到预测向量 所在的子空间上。*回归系数 只是这个投影操作的一个缩放因子。
我们可以进一步将相关系数 引入这个公式:
这个公式清晰地表明,回归线的斜率,本质上是由相关系数(方向)和两个变量的标准差之比(尺度)共同决定的。
我们通过一段代码来可视化这个投影过程。
import numpy as npimport matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = False# 再次假设 N=2 以便在 2D 平面可视化# 定义两个去中心化向量x_centered = np.array([3.0, 1.0])y_centered = np.array([2.0, 2.5])# 计算几何量dot_product = np.dot(y_centered, x_centered)norm_x_sq = np.dot(x_centered, x_centered)beta_hat = dot_product / norm_x_sq# 计算投影向量y_hat = beta_hat * x_centered# 计算残差向量residual = y_centered - y_hat# 创建图表fig, ax = plt.subplots(figsize=(8, 8))# 绘制向量ax.quiver(0, 0, x_centered[0], x_centered[1], angles='xy', scale_units='xy', scale=1, color='#d73027', width=0.01, label='预测变量向量 $\\mathbf{x}$')ax.quiver(0, 0, y_centered[0], y_centered[1], angles='xy', scale_units='xy', scale=1, color='#4575b4', width=0.01, label='真实观测向量 $\\mathbf{y}$')ax.quiver(0, 0, y_hat[0], y_hat[1], angles='xy', scale_units='xy', scale=1, color='black', width=0.015, label='投影(预测)向量 $\\hat{\\mathbf{y}} = \\beta \\mathbf{x}$')ax.quiver(y_hat[0], y_hat[1], residual[0], residual[1], angles='xy', scale_units='xy', scale=1, color='#1a9850', width=0.01, label='残差向量 $\\mathbf{e}$')# 绘制辅助线ax.plot([y_centered[0], y_hat[0]], [y_centered[1], y_hat[1]], 'k--')ax.plot([0, x_centered[0]*1.5], [0, x_centered[1]*1.5], 'gray', linestyle=':')# 添加文本和标签ax.text(x_centered[0]*0.5, x_centered[1]*0.5-0.2, '$\\mathbf{x}$', fontsize=14, color='#d73027')ax.text(y_centered[0]*0.5+0.1, y_centered[1]*0.5, '$\\mathbf{y}$', fontsize=14, color='#4575b4')ax.text(y_hat[0]*0.4, y_hat[1]*0.4+0.1, '$\\hat{\\mathbf{y}}$', fontsize=14, color='black')ax.text(y_hat[0] + residual[0]*0.5, y_hat[1] + residual[1]*0.5, '$\\mathbf{e}$', fontsize=14, color='#1a9850')# 验证正交性residual_dot_x = np.dot(residual, x_centered)ax.set_title(f'线性回归的几何本质:正交投影\n回归系数 $\\beta$ = {beta_hat:.2f}\n残差与x的内积 = {residual_dot_x:.2e} (接近0)', fontsize=15)ax.set_xlim(-0.5, 4)ax.set_ylim(-0.5, 4)ax.set_aspect('equal')ax.grid(True)ax.legend()plt.show()执行结果如下:

黑色的预测向量 确实是蓝色真实向量 在红色预测向量 方向上的正交投影。而绿色的残差向量 则与预测向量 严格垂直。标题中计算出的内积接近于0(由于浮点数精度问题),证明了它们的正交性。
从几何维度出发:最小二乘法找到的拟合线,其本质是使得残差向量与所有预测变量向量都正交。这是多元线性回归中一个极其深刻的性质。
我们首先将抽象的随机变量映射为高维数据空间中的具体向量。接着,我们将统计学中的去中心化等价于几何上的向量平移,使其重心与坐标原点重合。
基于这个框架,我们得出了本节最核心的三个几何等价关系:一是 协方差等价于去中心化数据向量之间的内积;二是方差等价于去中心化数据向量长度的平方;三是皮尔逊相关系数等价于去中心化数据向量之间夹角的余弦值。
这个发现解释了相关系数的边界和其对线性关系的偏好。
最后,我们将这个几何框架应用于线性回归,证明了最小二乘法在几何上就是寻找一个正交投影。我们从纯粹的几何原理出发,反向推导出了回归系数的经典统计学公式 。