You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让scipy.linalg.eig采用加权内积对特征向量进行归一化?

好问题!scipy.linalg.eig确实没有内置支持自定义加权内积归一化的选项,但我们有两种实用的方法来实现你想要的效果——让特征向量满足$\sum_i v_i^2 w_i = 1$(其中$w$是你的权重向量)。下面分别介绍:

方法1:手动重新归一化特征向量

这是最直接的思路:先用scipy.linalg.eig得到标准内积归一的特征向量,再根据你的权重向量重新调整每个向量的尺度。

原理

假设scipy.linalg.eig返回的特征向量矩阵为vecs(每一列对应一个特征向量),对于任意一列特征向量v,它当前满足$\sum_i v_i^2 = 1$。我们需要计算它的加权范数平方:
$$\text{weighted_norm_sq} = \sum_i v_i^2 w_i$$
然后用归一化因子$\frac{1}{\sqrt{\text{weighted_norm_sq}}}$乘以原向量,就能得到满足加权内积归一化的新向量。

代码示例

import numpy as np
from scipy.linalg import eig

# 示例矩阵和权重向量
A = np.array([[1, 2], [3, 4]])
w = np.array([0.5, 2.0])  # 自定义权重

# 求解标准特征值问题
vals, vecs = eig(A)

# 对每个特征向量进行加权归一化
weighted_vecs = np.zeros_like(vecs)
for i in range(vecs.shape[1]):
    v = vecs[:, i]
    weighted_norm = np.sqrt(np.sum(v**2 * w))
    weighted_vecs[:, i] = v / weighted_norm

# 验证:检查每个特征向量的加权范数是否为1
for i in range(weighted_vecs.shape[1]):
    print(f"特征向量{i}的加权范数平方:{np.sum(weighted_vecs[:,i]**2 * w):.6f}")

方法2:通过矩阵相似变换求解

如果不想事后调整特征向量,我们可以先对原矩阵做相似变换,将加权内积归一化的需求转化为标准特征值问题,直接求解得到符合要求的特征向量。

原理

我们的目标是求解$A\mathbf{v} = \lambda\mathbf{v}$,同时满足$\mathbf{v}^T W \mathbf{v} = 1$(其中$W$是对角矩阵,对角元素为权重$w_i$)。

令$\mathbf{v} = W{-1/2}\mathbf{u}$($W{-1/2}$是$W$的逆平方根矩阵,即对角元素为$1/\sqrt{w_i}$的对角矩阵),代入原方程可得:
$$A W^{-1/2}\mathbf{u} = \lambda W^{-1/2}\mathbf{u}$$
两边左乘$W^{1/2}$,得到:
$$W^{1/2} A W^{-1/2}\mathbf{u} = \lambda\mathbf{u}$$

此时求解这个变换后矩阵的特征值问题,得到的$\mathbf{u}$是标准内积归一的($\mathbf{u}T\mathbf{u}=1$),对应的$\mathbf{v}=W{-1/2}\mathbf{u}$自然满足$\mathbf{v}^T W \mathbf{v} = 1$,完全符合你的需求。而且相似变换不会改变特征值,所以得到的特征值和原问题一致。

代码示例

import numpy as np
from scipy.linalg import eig

# 示例矩阵和权重向量
A = np.array([[1, 2], [3, 4]])
w = np.array([0.5, 2.0])

# 构造权重的平方根和逆平方根对角矩阵
sqrt_W = np.diag(np.sqrt(w))
inv_sqrt_W = np.diag(1 / np.sqrt(w))

# 构造变换后的矩阵
A_transformed = sqrt_W @ A @ inv_sqrt_W

# 求解变换后的特征值问题
vals, us = eig(A_transformed)

# 转换为加权归一的特征向量
weighted_vecs = inv_sqrt_W @ us

# 验证
for i in range(weighted_vecs.shape[1]):
    print(f"特征向量{i}的加权范数平方:{np.sum(weighted_vecs[:,i]**2 * w):.6f}")

两种方法的对比

  • 方法1更简单直观,适合小矩阵或者只需要快速调整的场景;
  • 方法2适合需要直接从求解过程得到目标向量的场景,避免事后循环处理,但需要额外的矩阵运算。

内容的提问来源于stack exchange,提问作者Rachel Garrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:33:48