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

修复牛顿-拉夫逊算法实现中的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)时,实际是在试图调用这个数组,而数组是不可调用的对象,因此触发错误。

修复步骤

  1. 重命名冲突变量:把全局变量H_inv改成其他名字,比如h_inv_result,避免和函数名重名。
  2. 修正循环初始条件:原代码中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ò

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:48:24