【问题标题】:Logistic regression cost function returning nan返回 nan 的逻辑回归成本函数
【发布时间】:2021-02-16 21:19:26
【问题描述】:

我最近学习了逻辑回归,我想实践一下。我目前正在使用this dataset from kaggle。我尝试以这种方式定义成本函数(我做了所有必要的导入):

# Defining the hypothesis
sigmoid = lambda x: 1 / (1 + np.exp(-x))
predict = lambda trainset, parameters: sigmoid(trainset @ parameters)

# Defining the cost
def cost(theta):
    #print(X.shape, y.shape, theta.shape)
    preds = predict(X, theta.T)
    errors = (-y * np.log(preds)) - ((1-y)*np.log(1-preds))
    return np.mean(errors)

theta = []
for i in range(13):
    theta.append(1)
theta = np.array([theta])
cost(theta)

当我运行这个单元格时,我得到:

/opt/venv/lib/python3.7/site-packages/ipykernel_launcher.py:9: RuntimeWarning: divide by zero encountered in log
  if __name__ == '__main__':
/opt/venv/lib/python3.7/site-packages/ipykernel_launcher.py:9: RuntimeWarning: invalid value encountered in multiply
  if __name__ == '__main__':
nan

当我在网上搜索时,我得到了将数据标准化的建议,然后尝试一下。所以我就是这样做的:

df = pd.read_csv("/home/jovyan/work/heart.csv")
df.head()

# The dataset is 303x14 in size (using df.shape)
length = df.shape[0]

# Output vector
y = df['target'].values
y = np.array([y]).T

# We name trainingset as X for convenience
trainingset = df.drop(['target'], axis = 1)
#trainingset = df.insert(0, 'bias', 1)

minmax_normal_trainset = (trainingset - trainingset.min())/(trainingset.max() - trainingset.min())
X = trainingset.values

我真的不知道除以零错误发生在哪里以及如何解决它。如果我在这个实现中犯了任何错误,请纠正我。如果之前有人问过这个问题,我很抱歉,但我能找到的只是标准化数据的提示。提前致谢!

【问题讨论】:

    标签: python-3.x pandas numpy nan logistic-regression


    【解决方案1】:

    np.log(0) 引发 divide by zero 错误。所以这是导致问题的部分:

    errors = (-y * np.log(preds)) - ((1 - y) * np.log(1 - preds))
                   ##############              #################
    

    preds 的绝对值大于 709 时,preds 可以是 0 或 1(因为浮点数学,至少在我的机器上是这样),这就是为什么将 x 规范化为介于 0 和 1 之间的原因解决问题。

    编辑:

    您可能希望标准化到比(0, 1) 更大的范围 - 当前设置的 sigmoid 函数在该范围内几乎是线性的。也许使用:

     minmax_normal_trainset = c * (trainingset - trainingset.mean())/(trainingset.stdev())
    

    并调整c 以获得更好的收敛性。

    【讨论】:

    • 我对 x 进行了标准化,但问题仍然存在。我应该怎么做才能解决它?
    • 如果您在问题中使用了代码,minmax_normal_trainset 已标准化,但您设置了X = trainingset.values,未标准化
    • 只是一个评论-您可能希望标准化到比 (0, 1) 更大的范围-您当前设置的 sigmoid 函数在该范围内几乎是线性的。如果您的模型不能很好地收敛,也许改用minmax_normal_trainset = c * (trainingset - trainingset.mean())/(trainingset.stdev()) 并调整c
    • 我实际上缩放正常,模型出来的效果很好,尽管我也会尝试你的建议。
    猜你喜欢
    • 2020-05-08
    • 1970-01-01
    • 2016-05-26
    • 2019-04-24
    • 2018-03-01
    • 2015-09-28
    • 1970-01-01
    • 2020-08-08
    相关资源
    最近更新 更多