逻辑回归代价函数返回 nan
Logistic regression cost function returning nan
最近学了逻辑回归,想实践一下。我目前正在使用 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
我真的不知道除零错误发生在哪里以及如何解决它。如果我在这个实现中犯了任何错误,请纠正我。如果之前有人问过这个问题,我很抱歉,但我能找到的只是规范化数据的提示。提前致谢!
np.log(0)
引发 divide by zero
错误。所以这是导致问题的部分:
errors = (-y * np.log(preds)) - ((1 - y) * np.log(1 - preds))
############## #################
当 preds
的绝对值大于 709 时,
preds
可以是 0 或 1(因为浮点数学,至少在我的机器上),这就是规范化 [=15 的原因=] 介于 0 和 1 之间即可解决问题。
编辑:
您可能希望标准化到比 (0, 1)
更大的范围 - 您当前设置的 sigmoid 函数在该范围内几乎是线性的。也许使用:
minmax_normal_trainset = c * (trainingset - trainingset.mean())/(trainingset.stdev())
并调整 c
以获得更好的收敛性。
最近学了逻辑回归,想实践一下。我目前正在使用 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
我真的不知道除零错误发生在哪里以及如何解决它。如果我在这个实现中犯了任何错误,请纠正我。如果之前有人问过这个问题,我很抱歉,但我能找到的只是规范化数据的提示。提前致谢!
np.log(0)
引发 divide by zero
错误。所以这是导致问题的部分:
errors = (-y * np.log(preds)) - ((1 - y) * np.log(1 - preds))
############## #################
当 preds
的绝对值大于 709 时,
preds
可以是 0 或 1(因为浮点数学,至少在我的机器上),这就是规范化 [=15 的原因=] 介于 0 和 1 之间即可解决问题。
编辑:
您可能希望标准化到比 (0, 1)
更大的范围 - 您当前设置的 sigmoid 函数在该范围内几乎是线性的。也许使用:
minmax_normal_trainset = c * (trainingset - trainingset.mean())/(trainingset.stdev())
并调整 c
以获得更好的收敛性。