机器学习之路-最小二乘法、梯度下降法

最小二乘法 

   基本思想:          

   最小二乘法则是一种统计学习优化技术,它的目标是最小化误差平方之和来作为目标,从而找到最优模型,这个模型可以拟合观察数据。 回归学习最常用的损失函数是平方损失函数,在此情况下,回归问题可以用著名的最小二乘法来解决。最小二乘法就是曲线拟合的一种解决方法。最小二乘的思想是使观测点好估计点的距离平方和最小,在古汉语中平方叫做二乘,最小指的是参数的估计值要保证各个观测点与估计点的距离平方和最小。    

  方程组求解方法:            

   对于拟合曲线所选择的特征函数,比如y=ax^{^{2}}+bx+c,可以用矩阵表示为X\beta =y

引入平方差函数: S(\beta )=\left \| X\beta -y \right \|^{^{2}},通过微分求最小值,可得:X^{^{T}}X\beta =X^{^{T}}y,如果矩阵X^{^{T}}X可逆,可得\beta = (X^{^{T}}X)^{^{-1}}X^{T}y,可求得特征函数的参数\beta

import numpy as np
from matplotlib import pyplot as plt
'''
最小二乘法拟合曲线
x:点的x坐标
y:点的y坐标
k:特征方程的次数
返回特征函数的参数以及预测值
'''
def calculate_wy(x, y, k):
    A = []
    for index in range(k + 1):
        A.append(x ** (k - index))
    A = np.array(A).T
    B = y_.reshape(y_.shape[0], 1)
    ws = np.linalg.inv(A.T.dot(A)).dot(A.T).dot(B)  #B=(X^TX)^-1X^TY
    pred = A.dot(ws)
    return ws,pred
 
# 随机生成数据
x = np.linspace(-1, 1, 100)
y = 2.3*x*x + 3.5*x + 0.04
y_ = y + np.random.rand(len(x)) - 0.5
 
#绘制理想曲线以及实际曲线
# calculate A
w, pred_y = calculate_wy(x, y_, 3)
plt.scatter(x, y_)
plt.plot(x, y, 'k-')
plt.plot(x, pred_y, 'r-')
plt.show()

梯度下降法:

       网上大佬们关于梯度下降法的介绍都很详细,在这里就说明一下刚开始看的时候比较纠结的问题,就是在最速下降法中,为什么相邻两次搜索方向必正交:

      证明:设第k步的步长为\lambda ^{_{k}},梯度为P^{_{k}},则有第K+1步的梯度为

                P^{^{k+1}} = b - AX^{^{k+1}} = b - A(X^{^{k}} +\lambda ^{_{k}}P^{^{k}}) = b - AX^{^{k}} -\lambda^{_{k}}AP^{^{k}} = P^{k} - \lambda^{_{k}}AP^{^{k}}

                \lambda ^{_{k}} = \frac{\left \| P^{k} \right \|}{(P^{k})^{T}AP^{k}} =\frac{ (P^{k},P^{k})}{ (AP^{k},P^{k})}

               (P^{k+1},P^{k}) = (P^{k},P^{k}) - \lambda _{k}(AP^{k},P^{k}) = 0

           即 \bigtriangledown f(X^{k+1})^{T}\bigtriangledown f(X^{k}) = 0,两次搜索方向正交

      拟合直线的代码实现,学习于stanford的机器学习视频

 假设我们拟合y=ax+b的直线,矩阵化后可得:

\begin{bmatrix} x1 &1 \\ x2 &1 \\ x3& 1\\ x4& 1 \end{bmatrix} \cdot \begin{bmatrix} a\\ b \end{bmatrix} = \begin{bmatrix} y1\\ y2 \\ y3 \\y4 \end{bmatrix} ,通过梯度下降法不断更新参数a,b

raw_X = [3333, 2222, 1111, 555]
raw_Y = [400, 200, 300, 150]
'''
数据的归一化处理,通过X=(X-average(X))/X.max

'''
X = np.array(raw_X)
Y = np.array(raw_Y)
X = X - (1/len(raw_X))*X.sum()
Y = Y - (1/len(raw_X))*Y.sum()
X = 1/X.max() * X
Y = 1/Y.max() * Y
plt.scatter(X, Y)
raw_X = X
raw_Y = Y
# 矩阵化拟合函数  y=ax+b
X = np.vstack((np.array([X.data]), np.ones([1, len(raw_X)]))).T
print(X)
Y = np.array([Y.data]).T
learning_rate = 0.1  # 学习率,用来控制步伐的大小
parameters = np.array([[0], [0]])  # 初始化的参数,设置为0可能会出现除数为0的情况

# 预测函数 y=ax+b
def Prediction(X, paras):
    return X.dot(paras)

# 梯度下降函数
Costs = []
maxStep = 70
for step in range(maxStep):
    P = Prediction(X, parameters)
    # 对学习率的优化,在坡度大的时候取大值,小的时候取小值,防止出现震荡情况
    a_ = 1/size * np.sum((P-Y)*X)
    b_ = 1/size * np.sum(P-Y)
    a = a - learning_rate*a_
    b = b - learning_rate*b_
    # print(P)
    parameters = np.array([[a], [b]])
    last_P = Prediction(X, parameters)
    cost = abs(np.sum(last_P - Y))
    Costs.append(cost)
    

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮的开心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值