回归问题--单变量numpy实现


首先,我们先做个检验参数误差的函数


我们在上面定义了那个平方差的和来检验我们模型的拟合程度
该函数是这么定义的c=Σ(wxi+b-yi)^2
就是把我们样本的每个点的x经我我们求出的函数算出的y,与真实的y相减然后平方求和,所以代码如下

def GetError(b,w,points):
	#此变量用于保存结果,初始化为0
    totalerror=0;
    #遍历每个样本点
    for i in range(0,len(points)):
        x=points[i,0]
        y=points[i,1];
        #根据数学公式求出平方和误差,应该是+=,求和嘛!
        totalerror+=(y-(w*x+b))**2
    #然后将结果返回,因为我们的参数在同一标准下测试的,所以加减乘除都可
    #为什么除样本个数,其实就是数值规范化,就是比较起来方便,仿照结果过大/小
    return totalerror/float(len(points));

第二步,就是一个求导并更新的步骤,代码如下

def GetGradient(b_current,w_current,points,learningrate):
    #初始化的梯度
    b_gradient=0;
    w_gradient=0;
    N=float(len(points))
    #因为loss函数是对于全部样本点来说的,所以循环一遍
    for i in range(0,len(points)):
        x=points[i,0];
        y=points[i,1];
        #grad_b=2(wx+b-y)
        #误差函数对w求偏导
        #误差函数为
        #fx=(wx1+b-y)**2
        b_gradient+=(2/N)*((w_current*x+b_current)-y)
        w_gradient+=(2/N)*x*((w_current*x+b_current)-y)
    #现在我们得到的是∂Σ(wxi+b-yi)/∂w和∂Σ(wxi+b-yi)/∂b
    #现在我们的两个便是分别是w和b,所以让w和b沿着梯度的反方向前进
    #前进的步长是多少呢,就是参数learningrate学习率
    #所以这一次计算就梯度下降了怎么多
    new_b=b_current-(learningrate*b_gradient)
    new_w=w_current-(learningrate*w_gradient)
    #将w和b返回
    return [new_b,new_w]

这是一次求解梯度的运算,也就是个模板,那么多次计算应该在写一个函数


def gradient_descent_runner(points,starting_b,starting_w,learning_ract,num_iterations):
    b=starting_b;
    w=starting_w;
    #梯度下降的次数
    for i in range(num_iterations):
        b,w=GetGradient(b,w,points,learning_ract)
    return [b,w]

然后是,总的运行

def run():
    #将数据读入
    points=np.genfromtxt("data.csv",delimiter=",")
    #设置学习率
    learning_rect=0.0001;
    #初始化的w和b,一般采用标准正态分布
    init_b=0;
    init_w=0;
    num_iterations = 1000
    print("Starting gradient descent at b = {0}, w = {1}, error = {2}"
          .format(init_b, init_w,
                  #计算为学习的时候的loss
                  #loss=Σ(wx+b-y)**2
                  GetError(init_b, init_w, points))
          )
    print("Running...")
    #开始计算线性回归方程的w和b
    [b, w] = gradient_descent_runner(points, init_b, init_w, learning_rect, num_iterations)
    print("After {0} iterations b = {1}, w = {2}, error = {3}".
          format(num_iterations, b, w,
                 #计算新的wb所造成的loss
                 GetError(b, w, points))
          )

然后分析结果

在这里插入图片描述
我们可以看到,wb设为0的时候误差函数是5565怎么多,当我们经过1000次梯度下降之后,误差就会变成112,比起0的时候这个结果无疑是好的很多。
在这里插入图片描述
当我把次数增加到10000次的时候此时的误差比原来就小了0.3左右,
0–》1000 error从5565降到112
1000–》10000 error降低了0.3
这就可能是我们的步长选取不合适引起的效果,或许也可能是这些数据的极限就是这些,如果error=0的话,这意味着是每个点都在我们的直线上,但是根据散点图来说,他们不可能都在一条直线上,所以,也可能是这方面的原因。
下一章是多变量的实践
数据资源如下

发布了19 篇原创文章 · 获赞 7 · 访问量 4047

猜你喜欢

转载自blog.csdn.net/weixin_43906877/article/details/104451256
今日推荐