【问题标题】:Obtaining wrong error-curve for logistic regression (Bug in Code)获取逻辑回归的错误误差​​曲线(代码中的错误)
【发布时间】:2019-10-31 16:47:24
【问题描述】:

我开始机器学习并编写了这段代码。但由于某种原因,我得到的是锯齿形误差曲线,而不是递减的对数曲线。 “form_binary_classes”现在什么都不做,只是获取两个具有不同标签的相似数据集的开始和结束索引。 error 函数在每次迭代中返回错误(很可能这是错误所在),acc 返回准确性。 gradient_descent 基本上用于返回训练的权重和偏差项。只寻找错误而不是寻找有效的方法。

def hypothesis(x, theta, b):
    h = np.dot(x, theta) + b
    return sigmoid(h)

def sigmoid(z):
    return 1.0/(1.0+np.exp(-1.0*z))

def error(y_true, x, w, b):
    m = x.shape[0]
    err = 0.0
    for i in range(m):
        hx = hypothesis(x[i], w, b)
        if(hx==0):
            err += (1-y_true[i])*np.log2(1-hx)
        elif(hx==1):
            err += y_true[i]*np.log2(hx)
        else:
            err += y_true[i]*np.log2(hx) + (1-y_true[i])*np.log2(1-hx)
    return -err/m

def get_gradient(y_true, x, w, b):
    grad_w = np.zeros(w.shape)
    grad_b = 0.0
    m = x.shape[0]
    for i in range(m):
        hx = hypothesis(x[i], w, b)
        grad_w += (y_true[i] - hx)*x[i]
        grad_b += (y_true[i] - hx)

    grad_w /= m
    grad_b /= m
    return [grad_w, grad_b]

def gradient_descent(y_true, x, w, b, learning_rate=0.1):
    err = error(y_true, x, w, b)
    grad_w, grad_b = get_gradient(y_true, x, w, b)
    w = w + learning_rate*grad_w
    b = b + learning_rate*grad_b
    return err, w, b

def predict(x,w,b):   
    confidence = hypothesis(x,w,b)
    if confidence<0.5:
        return 0
    else:
        return 1

def get_acc(x_tst,y_tst,w,b):

    y_pred = []

    for i in range(y_tst.shape[0]):
        p = predict(x_tst[i],w,b)
        y_pred.append(p)

    y_pred = np.array(y_pred)

    return  float((y_pred==y_tst).sum())/y_tst.shape[0]

def form_binary_classes(a_start, a_end, b_start, b_end):
    x = np.vstack((X[a_start:a_end], X[b_start:b_end]))
    y = np.hstack((Y[a_start:a_end], Y[b_start:b_end]))
    print("{} {}".format(x.shape,y.shape[0]))
    loss = []
    acc = []
    w = 2*np.random.random((x.shape[1],))
    b = 5*np.random.random()
    for i in range(100):
        l, w, b = gradient_descent(y, x, w, b, learning_rate=0.5)       
        acc.append(get_acc(X_test,Y_test,w))
        loss.append(l)
    plt.plot(loss)
    plt.ylabel("Negative of Log Likelihood")
    plt.xlabel("Time")
    plt.show()

错误图是什么样子的:

应该是什么样子:

【问题讨论】:

  • 你尝试过更小的学习率吗?比如 0.1 或 0.05 ?
  • 是的。甚至尝试 0.01 和相同的东西

标签: python python-3.x performance machine-learning logistic-regression


【解决方案1】:

您在计算错误时遇到问题,这很可能导致您的模型出现无法收敛的问题。

在您的代码中,当您考虑极端情况时,如果 hx==0 或 hx==1 以任何方式计算的错误为零,即使我们有预测错误,例如 hx==0 而 ytrue= 1

在这种情况下,我们进入第一个 if,错误将是 (1-1)*log2(1) =0,不正确。

您可以通过以下方式修改前两个 if 来解决此问题:

def error(y_true, x, w, b):
    m = x.shape[0]
    err = 0.0
    for i in range(m):
        hx = hypothesis(x[i], w, b)
        if(hx==y_true[i]): #Corner cases where we have zero error
            err += 0
        elif((hx==1 and y_true[i]==0) or (hx==0 and y_true[i]==1) ): #Corner cases where we will have log2 of zero
            err += np.iinfo(np.int32).min # which is an approximation for log2(0), and we penalzie the model at most with the greatest error possible
        else:
            err += y_true[i]*np.log2(hx) + (1-y_true[i])*np.log2(1-hx)
    return -err/m

在这部分代码中,我假设你有二进制标签

【讨论】:

  • 这是有道理的。但是如果 hx 和 y_true 都为 0 或都为 1 怎么办?此时 else 语句将被执行,我得到一个运行时警告和一个空白图表。我该怎么办?
  • 你是对的,那些是错误为零的情况。我以覆盖这些极端情况的方式编辑了代码,没有任何警告
猜你喜欢
  • 1970-01-01
  • 2013-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 2016-02-21
  • 2019-03-05
相关资源
最近更新 更多