【问题标题】:Linear Regression with gradient desent not giving correct results梯度下降的线性回归没有给出正确的结果
【发布时间】:2019-04-09 06:52:42
【问题描述】:

与 sklearn 相比,使用梯度下降的线性回归在同一数据集上给出不同的结果。

想知道为什么会这样。是局部最小值的问题吗

数据集如下

ht  wt
63  127
64  121
66  142
69  157
69  162
71  156
71  169
72  165
73  181
75  208

Sklearn 计算截距为 -266.53439537,系数为 6.13758146

而梯度下降给出的截距为 -1.49087014,系数为 2.3239637

import numpy as np
import pandas as pd

from sklearn.linear_model import LinearRegression 

import matplotlib.pyplot as plt

def cost (m,b , data_size):
    x = IN
    y = OUT
    totalError = 0
    for i in range (data_size):
    x = IN[i]
    y = OUT[i]
    totalError += ((m*x + b) - y) ** 2
    return totalError/ float(data_size)


def compute_gradient(X , Y, theta_1 ,theta_0 , N, learning_rate):

    gradient_theta_0 = 0
    gradient_theta_1 = 0

    #print (X.shape, Y.shape, N)

    Y_pred = theta_1*X + theta_0

    gradient_theta_1 = ((-2/N) * sum(X * (Y - Y_pred)))
    gradient_theta_0 = ((-2/N) * sum(Y - Y_pred))


    #print (gradient_theta_0 , gradient_theta_1, gradient_theta_0 * 
    learning_rate, gradient_theta_1 * learning_rate)    
    new_theta_0 = theta_0 - (gradient_theta_0 * learning_rate)
    new_theta_1 = theta_1 - (gradient_theta_1 * learning_rate)

    return (new_theta_1,new_theta_0)

IN = np.array([63 , 64, 66, 69, 69, 71, 71, 72, 73, 75])
OUT = np.array([127,121,142,157,162,156,169,165,181,208])

X = IN[:,np.newaxis]
Y = OUT[:,np.newaxis]

iterations       = 10000
initial_theta_0  = 0 
initial_theta_1  = 0
learning_rate    = 0.00001  
theta_0          = initial_theta_0
theta_1          = initial_theta_1

fig,ax = plt.subplots(figsize=(12,8))
cost_history = []

for i in range (iterations):
    #print ("iteration {} m {} b {}".format(i, theta_1, theta_0))
    [theta_1, theta_0] = compute_gradient(X , Y , theta_1 ,theta_0, 
data_size, learning_rate) 
    totalError = cost (theta_1,theta_0, data_size)
    #print (totalError)
    cost_history.append (totalError)

ax.plot(range(iterations),cost_history,'b.')    

print ("iteration {} m {} b {}".format(i, theta_1, theta_0))

reg_line = [(theta_1 * x) + theta_0 for x in IN]

lm = LinearRegression()
lm.fit(X, Y)

print ("SKLEARN coeff {}".format(lm.coef_))
print ("SKLEARN intercept {}".format(lm.intercept_))

#reg_line = [(lm.coef_[0] * x) + lm.intercept_ for x in IN]

ax3.plot (IN, reg_line , color='red')  
plt.show()

print ("SKLEARN coeff {}".format(lm.coef_))
print ("SKLEARN intercept {}".format(lm.intercept_)) 

RESULTS
iteration 99999 m [2.3239637] b [-1.49087014]
SKLEARN coeff [[6.13758146]]
SKLEARN intercept [-266.53439537]

【问题讨论】:

  • 请通过准确显示您如何使用代码(您的和 sklearn 的)来得出报告的系数,使示例完全可重现。
  • 添加了完整代码

标签: python-3.x machine-learning linear-regression


【解决方案1】:

您采用了糟糕的初始条件 (0,0) 并陷入了接近该点的局部最小值。更直观的初始条件是基于 ht 和 wt 的最大值和最小值,即

initial_theta_0 = np.min(Y)+np.min(X)*(np.min(Y)-np.max(Y))/(np.max(X)-np.min(X)) #-335.75
initial_theta_1 = (np.max(Y)-np.min(Y))/(np.max(X)-np.min(X)) # 7.25    

#initial_theta_0 = 121+63*(121-208)/(75-63) # -335.75
#initial_theta_1 = (208-121)/(75-63) # 7.25

【讨论】:

  • 谢谢格热戈兹。但是最小二乘是凸函数。那么它不是独立于初始值的吗?无论我们选择什么初始值,它都应该收敛?
  • 是的,但是对于您的数据,有许多局部最小值,而只有一个全局最小值。从“我的”初始条件开始,可以留下许多局部最小值。使用 learning_rate=0.0002 和迭代次数=999999,您可以获得 m [6.45397547] b [-288.52353716] 仍然接近 sklearn 找到的值。
  • 我假设你的值被你检查为最小值,但这是一个错误的假设——你可以慢慢增加迭代次数,但仍会朝着 sklearn 找到的值前进。
  • @AjoyDas 看来您已经发现了无监督梯度下降的缺点,恭喜! :-) 想象一下自己在阿尔卑斯山滑雪;如果您在没有任何转向输入的情况下下陡坡,您会自动到达山脚,还是会卡在小径上的某个地方,处于局部最小值(一条沟)或最大值(一棵树)?如果您等待的时间足够长,您最终会到达海平面 (X=0,Y=0) 吗? :-)
  • 有几个方面。 Primo,一位数学家对给定模型和数据的观察能够获得良好的初始条件。在接近损失函数的全局最小值的意义上很好,并且比其他任何迭代都需要更少的迭代。 Secundo,检查损失函数的值是否达到最小值(一种提前停止)。 Tertio,从几个不同的初始条件和/或不同的学习率开始,您可以消除意外达​​到局部最小值而不是更好或全局最小值的情况。
猜你喜欢
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 2017-06-20
  • 2019-10-09
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
  • 2016-10-22
相关资源
最近更新 更多