机器学习——多变量线性回归

在上一篇文章我们提到过的线性回归中,我们只有一个单一特征量(变量)——房屋面积x。我们希望使用这个特征量来预测房子的价格。
不妨思考一下,如果我们不仅仅知道房屋面积(作为预测房屋价格的特征量(变量)),我们还知道卧室的数量、楼层的数量以及房屋的使用年限,那么这就给了我们更多可以用来预测房屋价格的信息。

在这里插入图片描述
因此,模型发生了变化:在这里插入图片描述
损失函数改变如下:在这里插入图片描述
我们依然用梯度下降法来获取损失函数的最小值
在这里插入图片描述
画出损失函数关于θ0与θ1的图形
在这里插入图片描述
Jθ (x) – 损失函数
在这里插入图片描述
在这里插入图片描述
特征缩放(归一化)在这里插入图片描述
左图的梯度下降算法直接走向最小值,可以快速到达。而在右图中,先是沿着与全局最小值方向近乎垂直的方向前进,接下来是一段几乎平坦的长长的山谷。最终还是会抵达最小值,但是这需要花费大量的时间。
特征缩放是为了确保特征在一个数量级上,一般情况下,我们使用特征缩放,把特征值会缩放到接近 -1 ≤ xi ≤ 1的区域。
特征缩放的方法有:最大值法:原来的值x1/x1中的最大值
平方均值法:在原来的基础上把特征x1-u(平均值)然后在除以最大值。

下面介绍几种梯度下降的方法:
“Batch” Gradient Descent 批梯度下降
批梯度下降:指的是每下降一步,使用所有的训练集来计算梯度值
下面写一段代码利用线性回归实现梯度下降的批处理,代码如下:

"""
线性回归实现梯度下降的批处理(batch_gradient_descent )
"""
import numpy as np

X1 = 2 * np.random.rand(100, 1)
X2 = 4 * np.random.rand(100, 1)
X3 = 6 * np.random.rand(100, 1)

y = 4 + 3 * X1 + 4 * X2 + 5 * X3 + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X1, X2, X3]
# print(X_b)

learning_rate = 0.1
# 通常在做机器学习的时候,一般不会等到他收敛,因为太浪费时间,所以会设置一个收敛次数
n_iterations = 1000
m = 100

# 1.初始化theta, w0...wn
theta = np.random.randn(4, 1)
count = 0

# 4. 不会设置阈值,之间设置超参数,迭代次数,迭代次数到了,我们就认为收敛了
for iteration in range(n_iterations):
    count += 1
    # 2. 接着求梯度gradient
    gradients = 1.0/m * X_b.T.dot(X_b.dot(theta)-y)
    # 3. 应用公式调整theta值, theta_t + 1 = theta_t - grad * learning_rate
    theta = theta - learning_rate * gradients

print(count)
print(theta)

“Stochastic” Gradient Descent 随机梯度下降
随机梯度下降:指的是每下降一步,使用一条训练集来计算梯度值
随机梯度下降思想:把m个样本分成m份,每次用1份做梯度下降;也就是说,当有m个样本时,批梯度下降只能做一次梯度下降,但是随机梯度下降可以做m次。

下面还是通过代码实现随机梯度下降:

"""
随机梯度下降
"""
import numpy as np
import random

X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# print(X_b)

n_epochs = 500
a0 = 0.1
decay_rate = 1

m = 100
num = [i for i in range(100)]
# print(num)

def learning_schedule(epoch_num):
    return (1.0 / (decay_rate * epoch_num + 1)) * a0

theta = np.random.randn(2, 1)

# epoch 是轮次的意思,意思是用m个样本做一轮迭代
for epoch in range(n_epochs):
    # 生成100个不重复的随机数
    rand = random.sample(num, 100)
    # print(rand)
    for i in range(m):
        random_index = rand[i]
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = xi.T.dot(xi.dot(theta)-yi)
        learning_rate = learning_schedule(epoch + i)
        theta = theta - learning_rate * gradients

print(theta)

“Mini-Batch” Gradient Descent “Mini-Batch”梯度下降
“Mini-Batch”梯度下降:指的是每下降一步,使用一部分的训练集来计算梯度值。

如果 mini-batch 大小 = m : 那他就是批梯度下降
如果 mini-batch 大小 = 1 : 那他就是随机梯度下降
如果 mini-batch 1 < 大小 < m :那他就是‘Mini-batch’随机梯度下降

下面还是通过代码实现“Mini-Batch”梯度下降:

import numpy as np
import random

X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# print(X_b)

n_epochs = 500
t0, t1 = 5, 50

m = 100
num = [i for i in range(100)]

def learning_schedule(t):
    return t0 / (t + t1)

theta = np.random.randn(2, 1)

batch_num = 5
batch_size = m // 5


# epoch 是轮次的意思,意思是用m个样本做一轮迭代
for epoch in range(n_epochs):
    # 生成100个不重复的随机数
    for i in range(batch_num):
        start = i*batch_size
        end = (i+1)*batch_size
        xi = X_b[start:end]
        yi = y[start:end]
        gradients = 1/batch_size * xi.T.dot(xi.dot(theta)-yi)
        learning_rate = learning_schedule(epoch*m + i)
        theta = theta - learning_rate * gradients

print(theta)

三种梯度下降的比较:
在这里插入图片描述
随机梯度下降会丧失向量带来的加速,所以我们不会太用随机梯度下降。
如何选择:
训练集比较小: 使用批梯度下降(小于2000个)
训练集比较大:使用Mini-bitch梯度下降 一般的Mini-batch size 是64,128,256, 512,1024
Mini-batch size要适用CPU/GPU的内存。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值