更新scipy.stats.multivariate_normal协方差时触发AttributeError求助
问题
尝试逐次更新scipy中多元高斯分布的协方差矩阵时触发了AttributeError,复现代码如下:
import numpy as np from scipy.stats import multivariate_normal # Initial mean init_pose = np.array([0, 0, 0]).T # Multi-variate Gaussian belief = multivariate_normal(mean=init_pose, cov=np.diag([1e-10, 1e-10, 1e-10])) print(belief.mean, belief.cov) # Update mean and covariance belief.mean = np.array([10, 20, 30]).T belief.cov = np.diag([1, 2, 3])
错误信息:
AttributeError Traceback (most recent call last) Cell In[42], line 7 5 print(belief.mean, belief.cov) 6 belief.mean = np.array([10, 20, 30]).T ----> 7 belief.cov = np.diag([1, 2, 3]) 8 print(belief.mean, belief.cov) AttributeError: can't set attribute
通过belief.__dict__查看属性,发现对象没有cov属性,只有cov_object:
{'_dist': <scipy.stats._multivariate.multivariate_normal_gen object at 0x2b84d81cfc10>, 'dim': 3, 'mean': array([0., 0., 0.]), 'cov_object': <scipy.stats._covariance.CovViaPSD object at 0x2b84d81cfbe0>, 'allow_singular': False, 'maxpts': 3000000, 'abseps': 1e-05, 'releps': 1e-05}
疑问:是否可以用numpy数组直接更新协方差?
解决方案
为什么不能直接赋值cov
multivariate_normal实例的cov是只读属性,它是从cov_object中计算导出的,并非可直接修改的实例变量,所以直接赋值会触发AttributeError。
两种可行的更新方式
方式1:直接修改cov_object内部参数(不推荐)
可以通过cov_object的data属性直接替换协方差矩阵,但这属于访问内部私有接口,scipy版本更新后可能失效:
# 直接替换cov_object的data为新的numpy数组 belief.cov_object.data = np.diag([1,2,3]) # 验证更新结果 print(belief.cov) # 输出:[[1. 0. 0.] # [0. 2. 0.] # [0. 0. 3.]]
方式2:重新实例化multivariate_normal(推荐)
scipy设计上更推荐通过重新创建实例来更新分布参数,这种方式更稳定,符合API设计规范:
# 基于当前mean和新cov创建新实例 belief = multivariate_normal(mean=belief.mean, cov=np.diag([1,2,3])) print(belief.mean, belief.cov)
关于mean可直接赋值的原因
mean是实例的可写属性,scipy内部实现了对应的setter方法,所以可以直接赋值修改;而cov仅实现了getter方法,没有开放setter。
内容的提问来源于stack exchange,提问作者Ogiad
相关产品推荐
相关产品推荐

