求与Matlab lscov等效的Python函数及代码修正方案
等效Matlab lscov的Python实现问题
我有三个数组:A(143,12)、b(143,1)、w(143,1),在Matlab中通过[x,stdx]=lscov(A,b,w)计算,期望得到(12,1)的NaN矩阵(因原问题秩亏或权重特性导致)。尝试了三种Python方法,但要么结果不符,要么权重未生效,求修正方案。
尝试过的方法
方法1
import numpy as np w=np.sqrt(np.diag(w)) Aw=A*np.sqrt(w) bw=b*np.sqrt(w) x, residuals, rank, s = np.linalg.lstsq(Aw, bw, rcond=0)
方法2
import numpy as np w=np.sqrt(np.diag(w)) w=np.squeeze(w) Aw=np.dot(w,A) bw=np.dot(b,w) x,res,rank,s=np.linalg.lstsq(Aw, bw, rcond=-1)
方法3
import statsmodels.api as sm x=sm.WLS(b,A,weights=w).fit() x.params
问题分析与修正方案
错误原因
- 方法1:
np.diag(w)将(143,1)的w转为143x143对角矩阵,与A做元素乘法时广播维度不匹配,加权逻辑完全错误。 - 方法2:
np.dot(w,A)将权重作为行向量与A相乘,得到(1,12)的Aw,偏离了加权最小二乘对Aw形状(143x12)的要求。 - 方法3:未处理秩亏场景(statsmodels默认返回最小范数解而非NaN),且未确保权重数组形状符合要求。
修正后的Numpy实现
import numpy as np # 确保w为一维数组 w = w.squeeze() # 过滤权重为0的观测(匹配Matlab lscov行为:权重为0的观测会被忽略) mask = w != 0 A_filtered = A[mask] b_filtered = b[mask] w_filtered = w[mask] # 正确计算加权后的A和b:每一行乘以对应权重的平方根 Aw = A_filtered * np.sqrt(w_filtered)[:, np.newaxis] bw = b_filtered * np.sqrt(w_filtered)[:, np.newaxis] # 求解最小二乘,rcond=None匹配Matlab的秩判断逻辑 x, residuals, rank, s = np.linalg.lstsq(Aw, bw, rcond=None) # 若秩小于A的列数,返回NaN矩阵(匹配Matlab预期结果) if rank < A.shape[1]: x = np.full((A.shape[1], 1), np.nan)
修正后的Statsmodels实现
import statsmodels.api as sm # 确保w为一维数组 w = w.squeeze() # 构建加权最小二乘模型 model = sm.WLS(b, A, weights=w) results = model.fit() # 若模型秩不足,返回NaN矩阵;否则返回参数 if results.model.rank < A.shape[1]: x_params = np.full((A.shape[1], 1), np.nan) else: x_params = results.params.values.reshape(-1, 1)
内容的提问来源于stack exchange,提问作者Fand
相关产品推荐
相关产品推荐

