机器学习01:单变量线性回归及python实现

Regression 回归分析

线性回归

单变量线性回归

单变量的意思是只有一个自变量。

比如,我们想要根据明天的最高温度预测明天某城市的峰值用电量。我们不可能平白无故地预测明天的数据,而是需要根据以往的数据来预测以后的数据。因此,我们需要收集以往的数据,如下表:

最高温度(℉)峰值用电量
76.71.87
72.71.92
71.51.96
86.02.43
90.04.69
87.72.50

散点图:
在这里插入图片描述

对于单变量线性回归,可表示为如下模型:
当 天 峰 值 用 电 量 = θ 0 + θ 1 ⋅ ( 当 天 最 高 温 度 ) 当天峰值用电量=\theta_0+\theta_1·(当天最高温度) =θ0+θ1()
如果我们把这个模型函数放在上面的散点图中(三条直线的参数值不同):
在这里插入图片描述

很显然,根据明天的最高温度预测明天的峰值用电量的问题,就转化成了在上面的图中找一条最吻合训练数据的直线,“最吻合”也就等价于选择合适的 θ 0 \theta_0 θ0 θ 1 \theta_1 θ1.

那么,我们应该怎么衡量“最吻合”呢?这就需要用到Loss Function(损失函数)了。

损失函数

L ( f ( x ) − y ) = ∑ i = 1 n ( f ( x i ) − y i ) 2 = ∑ i = 1 n ( ( θ 1 x + θ 0 ) − y i ) 2 L(f(x)-y)=\sum_{i=1}^n(f(x_i)-y_i)^2=\sum_{i=1}^n((\theta_1x+\theta_0)-y_i)^2 L(f(x)y)=i=1n(f(xi)yi)2=i=1n((θ1x+θ0)yi)2

对于损失函数,我们需要注意以下两点:

  • 损失函数值越小,越吻合(预测值与实际值差别越小)
  • 损失函数值是非负

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8EIUgaaI-1600340952863)(C:\Users\Administrator\OneDrive\机器学习\3.png)]

因此这个问题就转换成了一个优化问题:
m i n J ( θ 0 , θ 1 ) = m i n ( 1 2 m ∑ i = 1 n ( ( θ 1 x + θ 0 ) − y i ) 2 ) ( m 为 样 本 个 数 ) minJ(\theta_0, \theta_1)=min(\frac{1}{2m}\sum_{i=1}^n((\theta_1x+\theta_0)-y_i)^2)\quad (m为样本个数) minJ(θ0,θ1)=min(2m1i=1n((θ1x+θ0)yi)2)(m)
解决上面的优化问题主要用梯度下降法。

梯度下降法

上面说到:“最吻合”也就等价于选择合适的 θ 0 \theta_0 θ0 θ 1 \theta_1 θ1.在梯度下降法中,我们需要对 θ 0 \theta_0 θ0 θ 1 \theta_1 θ1 进行多次迭代计算,逐步逼近 J ( θ 0 , θ 1 ) J(\theta_0, \theta_1) J(θ0,θ1)的最小值。

那么,在每一次迭代中,我们应如何计算 θ 0 \theta_0 θ0 θ 1 \theta_1 θ1呢?需要用到如下算法:

注意: θ 0 \theta_0 θ0 θ 1 \theta_1 θ1同步更新的。(也就是 批处理:梯度下降的每一步都使用所 有的训练样本)

附:相关计算步骤:
∂ J ∂ θ 1 = ∂ 1 2 n ∑ i = 0 n ( y i − y i ^ ) 2 ∂ θ 1 = 1 n ∑ i = 0 n ( y i − θ 1 x i − θ 0 ) ∂ ( y i − θ 1 x i − θ 0 ) ( − x i ) ∂ θ 1 = 1 n ∑ i = 0 n ( y i − θ 1 x i − θ 0 ) ( − x i ) = 1 n ∑ i = 0 n x ( y i ^ − y i ) \frac{\partial J}{\partial \theta_1}=\frac{\partial\frac{1}{2n}\displaystyle \sum_{i=0}^n(y_i- \hat{y_i})^2}{\partial \theta_1}=\frac{1}{n}\displaystyle \sum_{i=0}^n(y_i-\theta_1x_i-\theta_0)\frac{\partial(y_i-\theta_1x_i-\theta_0)(-x_i)}{\partial \theta_1}\\=\frac{1}{n}\displaystyle \sum_{i=0}^n(y_i-\theta_1x_i-\theta_0)(-x_i)=\frac{1}{n} \displaystyle \sum_{i=0}^nx(\hat{y_i}-y_i) θ1J=θ12n1i=0n(yiyi^)2=n1i=0n(yiθ1xiθ0)θ1(yiθ1xiθ0)(xi)=n1i=0n(yiθ1xiθ0)(xi)=n1i=0nx(yi^yi)

∂ J ∂ θ 0 = ∂ 1 2 n ∑ i = 0 n ( y i − y i ^ ) 2 ∂ θ 0 = 1 n ∑ i = 0 n ( y i − θ 1 x i − θ 0 ) ∂ ( y i − θ 1 x i − θ 0 ) ( − x i ) ∂ θ 0 = 1 n ∑ i = 0 n ( y i − θ 1 x i − θ 0 ) ( − 1 ) = 1 n ∑ i = 0 n ( y i ^ − y i ) \frac{\partial J}{\partial \theta_0}=\frac{\partial\frac{1}{2n}\displaystyle \sum_{i=0}^n(y_i- \hat{y_i})^2}{\partial \theta_0}=\frac{1}{n}\displaystyle \sum_{i=0}^n(y_i-\theta_1x_i-\theta_0)\frac{\partial(y_i-\theta_1x_i-\theta_0)(-x_i)}{\partial \theta_0}\\=\frac{1}{n}\displaystyle \sum_{i=0}^n(y_i-\theta_1x_i-\theta_0)(-1)=\frac{1}{n} \displaystyle \sum_{i=0}^n(\hat{y_i}-y_i) θ0J=θ02n1i=0n(yiyi^)2=n1i=0n(yiθ1xiθ0)θ0(yiθ1xiθ0)(xi)=n1i=0n(yiθ1xiθ0)(1)=n1i=0n(yi^yi)

θ 0 = θ 0 − α ∂ J ∂ θ 0 \theta_0=\theta_0-\alpha\frac{\partial J}{\partial \theta_0} θ0=θ0αθ0J

θ 1 = θ 1 − α ∂ J ∂ θ 1 \theta_1=\theta_1-\alpha\frac{\partial J}{\partial \theta_1} θ1=θ1αθ1J

你可能会对式中的 α \alpha α 很疑惑,不用担心,下面我们会讲到。

学习率 α \alpha α

对于学习率,它代表了 J ( θ 0 , θ 1 ) J(\theta_0,\theta_1) J(θ0,θ1)在每一次迭代中的减小程度。

  • 对于合适的 α \alpha α J ( θ 0 , θ 1 ) J(\theta_0,\theta_1) J(θ0,θ1)应该在每一次迭代中都减小

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Jd5XMJl-1600340952864)(C:\Users\Administrator\OneDrive\机器学习\4.png)]

  • 如果 α \alpha α太小,梯度下降算法则会收敛很慢

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c5vI8yDk-1600340952865)(C:\Users\Administrator\OneDrive\机器学习\5.png)]

  • 如果 α \alpha α太大,梯度下降算法则不会收敛:发散或震荡

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S7R5NBjM-1600340952866)(C:\Users\Administrator\OneDrive\机器学习\6.png)]

为了找到合适的 α \alpha α,我们可以不断尝试。

练习

拟合 x x x y y y

x x x y y y
12
38
514

代码如下(python):

'''
Description: 
Author: Weijian Ma
Date: 2020-09-16 18:47:40
LastEditTime: 2020-09-17 16:59:55
LastEditors: Weijian Ma
'''
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

## 数据及参数的初始化
x = [1, 3, 5] 
x = np.reshape(x,newshape=(len(x),1))
y =  [3, 6, 16] 
y = np.reshape(y,newshape=(len(y),1))
a = 1
b = 1
alpha = 0.1
n = len(x)

## 损失函数
def costFunction(a, b):
    return 0.5/n*(np.square(a*x+b-y)).sum()

## 优化
def opt(a, b):
    da = (1/n) * ((a*x+b-y)*x).sum()
    db = (1/n) * ((a*x+b-y).sum())
    a = a-alpha*da
    b = b-alpha*db
    return a, b

## 训练模型
fig = plt.figure(figsize=(12,8))
sub01 = plt.subplot(221)
sub02 = plt.subplot(222)
sub03 = plt.subplot(223)
sub04 = plt.subplot(224)

costList = []
aList = []
bList = []

for i in range(100):
    print('训练次数:{} a={:.4f} b={:.4f}'.format(i+1, a, b))
    cost = costFunction(a, b)
    costList.append(cost)
    a, b = opt(a, b)
    aList.append(a)
    bList.append(b)
    sub01.cla()
    sub02.cla()
    sub03.cla()
    sub04.cla()
    sub01.plot(x, a*x+b)
    sub01.scatter(x, y)
    sub01.set_xlabel('x')
    sub01.set_ylabel('y')
    sub01.set_title('a={:.6f}, b={:.6f}'.format(a, b))
    sub02.set_xlabel('训练次数')
    sub02.set_ylabel('损失函数值')
    sub02.set_title('当前损失函数值:{:.6f}'.format(cost))
    sub02.plot(costList)
    sub03.plot(aList)
    sub04.plot(bList)
    sub03.set_xlabel('训练次数')
    sub03.set_ylabel('a')
    sub04.set_xlabel('训练次数')
    sub04.set_ylabel('b')
    plt.pause(0.001)
plt.show()

结果(学习率为0.1,迭代次数100次):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值