美文网首页AI学习笔记
机器学习笔记-线性回归与梯度下降

机器学习笔记-线性回归与梯度下降

作者: sf705 | 来源:发表于2017-06-15 11:28 被阅读1377次

    其实很早就了解线性回归,其解法:梯度下降也是有些了解,一直没有实现,今天实现起来还是不太顺利,就是矩阵维度问题。主要参考ANDREW NG机器学习公开课
    线性回归,就是根据训练数据,得到一个函数(一个直线),然后再给定自变量,就能用该函数求得值。类似求:y= ax +b 求得:a,b 再给x,就可以求得y。但是也可能不止一个自变量x,如:



    其中 theta 为系数,theta0 为偏移量,为了便于写成矩阵,将 x0 设为1 这样就可以写成 x0乘theta0,其中m为训练集的个数


    现在给定x与y,如何求系数theta,使得大多数x,y在一条直线上。

    损失函数

    如何求得函数的系数,先将系数随便设置一个数,将x带入,根据实际y值,调整系数。损失函数就是给定系数theta,得到预测值,将所有预测值减去真实值,就是损失函数。如果预测的很准,损失函数最小(为0)


    上式中,给定的系数与样本点,得出估计值h(x),减去该样本的真实值y,如果得到的结果越小,则系数越接近真实值。 前面加上1/2是便于求导。
    看到这篇写的很详细(https://www.52ml.net/9921.html

    梯度下降

    梯度下降就是为了得到合适的系数theta,通过求导不断更新theta,来逐渐得到最接近的theta。
    上面给出了损失函数,可知损失函数最小时的theta就是最终要求得的theta,但是不能一步步试theta,求最值,先求导,假设就有一个样本点


    然后更新theta


    其中,alpha为学习因子,也就是梯度下降的速率,不能太大(下降速度太快),也不能太小(下降太慢)
    以上是一个样本点,对于多个样本点,就变成下面的了


    上式称为:batch gradient descent 批处理梯度下降。thetaj 是指第j个theta系数,如果每个样本中,有n个特征(x1,x2,x3,....xn),则theta就有n+1(多一个偏移),可以发现求第j 个theta就需要所有样本点,那么所有theta求起来,计算量很大。
    为了便于计算,引入随机梯度下降法


    每次只考虑一个样本点,而不是所有样本点 ,计算量比较少。上图直接从斯坦福公开课copy的图,把括号里面的符号提到外面,所以成了加号。
    上式在运算过程中,直接用整体向量就行了,就一次性求出所有theta

    Normal Equations

    其实对于线性回归,可以不用梯度下降,用normal equations可以直接求出theta,就是矩阵的推导了,具体步骤见,521ml 中给出的推导

    代码实现

    数据是来自 斯坦福的数据 ,50个样本点,x为50个2到8岁小朋友年龄(有小数),y为50个小朋友对应的身高(有小数),然后根据这50个样本,估计3.5岁到7岁孩子的身高。官网中给出的是MATLAB代码
    环境为:Python3 windows

    import numpy as np
    from numpy import *
    import matplotlib.pyplot as plt
    
    def toFloat(array):
        array = mat(array)
        m,n = shape(array)
        newArray = zeros((m,n))
        for i in range(m):
            for j in range(n):
                newArray[i,j] =  float(array[i,j])
        return newArray
    
    def getThetaUseNormal_Equations(xInput,yInput):
        x = toFloat(loadtxt(xInput))
        y = toFloat(loadtxt(yInput))
        m,n = shape(y)
        a = np.ones(n,dtype = np.float)#一行 n 列 float类型
        x = np.row_stack((a,x)) #将x 增加一行
        if not isinstance(x,matrix): #不是向量 转化为向量
            x = mat(x.T)#读取数据的时为行向量,一般书中没有说明,默认为列向量,在此处转化为列向量
        if not isinstance(y,matrix):
            y=mat(y.T)
        thta = (x.T*x)**-1 * x.T * y
        print(thta)
    
    def getThetaUseGradient_descent(xInput,yInput):
        x = toFloat(loadtxt(xInput))
        y = toFloat(loadtxt(yInput))
        x = x.T #转化为列向量
        y = y.T
        m,n = shape(x)
        a = np.ones((m,1),dtype=np.float)# 将x0 置为1 便于写成向量的乘积 theta*X
        x = np.column_stack((a,x))# 维度50*2
        theta = np.zeros((1,size(x[0,:])),dtype=float) # theta 1*2
        MAX_ITR = 1500#迭代次数
        alpha = 0.07#学习率
    '''
    迭代1500次达到最优,其实次数不定,可以设一个变量,监控theta,例如theta变化小于某一个很小的数的时候停止迭代。
    学习率0.07也可以改变,刚开始设为大一点,然后学习率依次减小
    '''
        for i in range(0,MAX_ITR):
            t1 = np.dot(x,theta.T) - y #x(50*2),theta.T(2*1) y(50*1),,t1(50*1)
            t2 = np.dot(t1.T,x)/m #t1.T(1,50),x(50,2)  t2(1*2)
            theta = theta - alpha * t2#theta(1*2) ,t2(1*2)
        print(theta)
    
    getThetaUseNormal_Equations("E:/Train_Data/Logistic_Regression/ex2x.dat","E:/Train_Data/Logistic_Regression/ex2y.dat")
    getThetaUseGradient_descent("E:/Train_Data/Logistic_Regression/ex2x.dat","E:/Train_Data/Logistic_Regression/ex2y.dat")
    
    

    参考文献

    http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=DeepLearning&doc=exercises/ex2/ex2.html
    https://www.52ml.net/9921.html
    http://www.cnblogs.com/tornadomeet/archive/2013/03/15/2961660.html

    相关文章

      网友评论

        本文标题:机器学习笔记-线性回归与梯度下降

        本文链接:https://www.haomeiwen.com/subject/axvhqxtx.html