修复牛顿-拉夫逊算法实现中的TypeError: 'numpy.ndarray'对象不可调用
解决牛顿-拉夫逊算法中的TypeError问题
我在实现牛顿-拉夫逊算法解决统计问题时,矩阵乘法环节触发了如下错误:
TypeError: 'numpy.ndarray' object is not callable
使用的代码
import numpy as np import scipy.special as sp def U_score(x, theta): a = theta[0] b = theta[1] n = len(x) d_a = -sp.digamma(a) + sp.digamma(a + b) + sum(np.log(x)) / n d_b = -sp.digamma(b) + sp.digamma(a + b) + sum(np.log(1 - x)) / n return np.array([d_a, d_b]) def Hessiana(x, theta): a = theta[0] b = theta[1] h11 = sp.polygamma(1, a + b) - sp.polygamma(1, a) h12 = sp.polygamma(1, a + b) h21 = sp.polygamma(1, a + b) - sp.polygamma(1, b) h22 = sp.polygamma(1, a + b) return np.array([[h11, h12], [h21, h22]]) def H_inv(x, theta): H = Hessiana(x, theta) ridge = 1e-6 # Small constant H_ridge = H + ridge * np.eye(H.shape[0]) return np.linalg.inv(H_ridge) def max_likelihood(x, theta, tol): theta_new = np.array([0, 0]) while np.linalg.norm(theta_new - theta) > tol: theta_new = theta - H_inv(x, theta) @ U_score(x, theta) return theta_new x = np.random.beta(2, 5, 100) theta = np.array([1,1]) U = U_score(x, theta) H = Hessiana(x, theta) H_inv = H_inv(x, theta) # 变量名与函数名冲突 emv = max_likelihood(x, theta, 1e-5) print(emv)
错误信息
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[80], line 1 ----> 1 emv = max_likelihood(x, theta, 1e-5) 2 print(emv) Cell In[78], line 4 2 theta_new = np.array([0, 0]) 3 while np.linalg.norm(theta_new - theta) > tol: ----> 4 theta_new = theta - H_inv(x, theta) @ U_score(x, theta) 5 return theta_new TypeError: 'numpy.ndarray' object is not callable
错误原因与修复
核心问题
全局变量H_inv覆盖了同名的H_inv()函数:你在代码中执行H_inv = H_inv(x, theta)后,全局作用域的H_inv变成了一个numpy数组。当max_likelihood函数尝试调用H_inv(x, theta)时,实际是在试图调用这个数组,而数组是不可调用的对象,因此触发错误。
修复步骤
- 重命名冲突变量:把全局变量
H_inv改成其他名字,比如h_inv_result,避免和函数名重名。 - 修正循环初始条件:原代码中
theta_new初始化为[0,0],第一次循环的范数计算逻辑不合理。将theta_new初始化为theta的副本,再通过新旧值的差值判断迭代终止,更符合牛顿-拉夫逊算法的迭代逻辑。
修改后的完整代码
import numpy as np import scipy.special as sp def U_score(x, theta): a = theta[0] b = theta[1] n = len(x) d_a = -sp.digamma(a) + sp.digamma(a + b) + sum(np.log(x)) / n d_b = -sp.digamma(b) + sp.digamma(a + b) + sum(np.log(1 - x)) / n return np.array([d_a, d_b]) def Hessiana(x, theta): a = theta[0] b = theta[1] h11 = sp.polygamma(1, a + b) - sp.polygamma(1, a) h12 = sp.polygamma(1, a + b) h21 = sp.polygamma(1, a + b) - sp.polygamma(1, b) h22 = sp.polygamma(1, a + b) return np.array([[h11, h12], [h21, h22]]) def H_inv(x, theta): H = Hessiana(x, theta) ridge = 1e-6 # Small constant H_ridge = H + ridge * np.eye(H.shape[0]) return np.linalg.inv(H_ridge) def max_likelihood(x, theta, tol): theta_new = theta.copy() # 初始化为theta的副本 while True: theta_old = theta_new.copy() theta_new = theta_old - H_inv(x, theta_old) @ U_score(x, theta_old) if np.linalg.norm(theta_new - theta_old) < tol: break return theta_new x = np.random.beta(2, 5, 100) theta = np.array([1,1]) U = U_score(x, theta) H = Hessiana(x, theta) h_inv_result = H_inv(x, theta) # 重命名变量,避免冲突 emv = max_likelihood(x, theta, 1e-5) print(emv)
内容的提问来源于stack exchange,提问作者Gabriel Ligabò
相关产品推荐
相关产品推荐

