【问题标题】:Linear regression implementation from scratch从零开始的线性回归实现
【发布时间】:2020-01-01 06:22:10
【问题描述】:

我正在尝试理解梯度下降算法。

谁能解释一下为什么我使用以下代码获得了高 MSE 值,或者如果我遗漏了一些概念,请澄清一下?

import numpy as np
import pandas as pd

my_data = pd.DataFrame({'x': np.arange(0,100),
                       'y': np.arange(0,100)})
X = my_data.iloc[:,0:1].values
y = my_data.iloc[:,1].values

def gradientDescent(X, y, lr = 0.001, n = 1000):

    n_samples, n_features = X.shape
    cost = []
    weight = np.zeros([n_features])
    b = 0

    for _ in range(n):
        # predict
        y_hat = np.dot(X, weight) + b # y = ax + b

        residual =  y - y_hat
        db = -(2/n_samples) * np.sum(residual)
        dw = -(2/n_samples) * np.sum(X.T * residual, axis = 1)

        # update weights

        weight -= (lr * dw)
        b -= (lr * db)

        cost.append(((y-y_hat) **2).mean())

    return weight, b, cost

gradientDescent(X,y)

【问题讨论】:

  • 你试过不同的lr吗?
  • 简单的梯度下降就像在雾中爬山:因为雾你只能在脚边看到,所以你看脚边看哪个方向往下走。然后你朝那个方向移动,再看一遍。如果山坡相当平坦,这可以很好地工作,但如果山坡崎岖不平,您可能会卡在低处。成功还取决于你从哪里开始。在这个类比中,初始参数是你的起点,你脚的方向是局部梯度,学习率是你在再次靠近你的脚之前走了多远。

标签: python linear-regression


【解决方案1】:

不是专家,但我认为您目前遇到了exploding gradient 问题。如果您单步执行您的代码,您会注意到您的权重值在递增的步骤中从正值变为负值。我相信你找不到最小值,因为对这个数据集使用 mse 会导致你来回跳跃,永远不会收敛。您的 x 和 y 范围为 100,因此当您查看成本时,它只是在爆炸。

如果您想将 mse 与当前的 x 和 y 值一起使用,您应该标准化您的数据。您可以通过减去平均值并除以标准差来做到这一点,或者只是将 x 和 y 都归一化为 1。

例如:

my_data.x = my_data.x.transform(lambda x: x / x.max())
my_data.y = my_data.y.transform(lambda x: x / x.max())

如果你这样做,你应该会看到你的成本收敛到 ~0 并有足够的迭代次数。

【讨论】: