对于某些 theta 值,逻辑回归的成本函数输出 NaN

Posted

技术标签:

【中文标题】对于某些 theta 值,逻辑回归的成本函数输出 NaN【英文标题】:Cost function of logistic regression outputs NaN for some values of theta 【发布时间】:2020-08-08 19:44:39 【问题描述】:

在仅使用 numpy 库实现逻辑回归时,我为成本函数编写了以下代码:

#sigmoid function
def sigmoid(z):
  sigma = 1/(1+np.exp(-z))
  return sigma
#cost function
def cost(X,y,theta):
  m = y.shape[0]
  z = X@theta
  h = sigmoid(z)
  J = np.sum((y*np.log(h))+((1-y)*np.log(1-h)))
  J = -J/m
  return J

Theta 是一个 (3,1) 数组,X 是形状 (m,3) 的训练数据。 X 的第一列是个数。 对于 theta = [0,0,0],成本函数输出 0.693,这是正确的成本,但对于 theta = [1,-1,1],它输出:

/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:5: RuntimeWarning: divide by zero encountered in log
  """
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:5: RuntimeWarning: invalid value encountered in multiply
  """
nan

我的梯度下降代码是:

#gradientdesc function
#alpha is the learning rate, iter is the number of iterations
def gradientDesc(X,y,theta,alpha,iter):
  m = y.shape[0]
  #d represents the derivative term
  d = np.zeros((3,1))
  for iter in range(iter):

    h = sigmoid(X@theta) - y
    temp = h.T.dot(X)

    d = temp.T
    d/=m
    theta = theta - alpha*d

  return theta

但这并没有给出正确的 theta 值。我该怎么办?

【问题讨论】:

【参考方案1】:

X 中的值是否很大?这可能会导致 sigmoid 返回值接近零,从而导致您看到警告。看看这个线程: Divide-by-zero-in-log

除非您解决这个值爆炸的问题,否则您的梯度下降将无法正常工作。我还会考虑在您的成本函数中添加正则化。

J += C * np.sum(theta**2) 

【讨论】:

数据在20到110之间,不算太大吧? 它已经欠拟合,所以正则化可能无济于事。我说的对吗? 如果拟合不足,则可以跳过正则化。您拥有的值可能会导致较大的指数(插入 z = 110 并亲自查看您与零的接近程度)。已知sigmoid 存在此类饱和问题。为什么不尝试将输入标准化为介于 0 和 1 之间?

以上是关于对于某些 theta 值,逻辑回归的成本函数输出 NaN的主要内容,如果未能解决你的问题,请参考以下文章

为啥逻辑回归的代价函数有对数表达式?

可以为逻辑回归定义自己的成本函数吗?

逻辑回归 - 计算成本函数会返回错误的结果

matlab中的正则化逻辑回归代码

吴恩达《机器学习》课程总结_logistic回归

对数回归的成本函数