文章目录
在谈回归之前,先要了解两个概念:监督学习与非监督学习。
监督学习
监督学习的训练数据由样本和标签组成,通过对训练数据学习得到一个模型,对给定的输入产生输出,这个输出可以是一个连续的值(回归),也可以是一个标签(分类)
回归: 通过房地产市场的数据,预测一个给定面积的房屋的价格。
分类: 通过给定数据,根据肿瘤大小预测肿瘤是良性肿瘤还是恶性肿瘤。
非监督学习
非监督学习就是训练数据只给定样本,让机器自己去学习提取样本中的特征值,进行聚类分析。
举例:
新闻分类:
在新闻网站中,根据新闻的主题将新闻划分成多个族。将在同一个族的新闻放在一起。
半监督学习
半监督学习的训练数据一部分有标签,一部分没有标签。
半监督学习的基本思想是利用数据分布上的模型假设, 建立学习器对未标签样本进行标签。
线性回归
线性回归是机器学习的基础,主要用于预测。
一元线性回归:只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。
一元线性回归模型:
x轴表示房屋面积,y轴表示价格。
一元线性回归要做的,就是找到一条直线最大程度的拟合这些点。即使这些点不在线上,也想让这些点距离直线尽量的近。
要判断这些点与直线的距离是不是最小,就要引入cost function(代价函数)
在回归问题中,衡量最优解的常用代价函数为平方误差
x(i)表示向量x中第i个元素
y(i)表示向量y中第i个元素
hθ(x)为多元线性回归模型
θi是参数(权值)。
接下来要做的,就是求参数θ,使损失函数最小。
梯度下降
梯度下降是一种非常通用的优化算法,能够为大范围的问题找到最优解。梯度下降的中心思想就是迭代的调整参数从而使损失函数最小化
假设你迷失在山上的浓雾之中,你能感觉到的只有你脚下路面的坡度。快速到达山脚的一个策略就是沿着最陡的方向下坡。这就是梯度下降的做法:通过测量参数向量θ相关的误差函数的局部梯度,并不断沿着降低梯度的方向调整,直到梯度降为0,到达最小值
具体来说,首先使用一个随机的θ值(这被称为随机初始化),然后逐步改良,每次踏出一步,每一步都尝试降低一点损失函数(如MSE),直到算法收敛出一个最小值
我们用梯度下降算法求解θ,参数θ可以表示为:
a称为**学习率(learning rate)**这个值越大每次修正的就越多,不过这个不是越高越好,如果太高了可能会一直在最低点“摆动”而无法收敛。也有的使用可变的学习速率,一开始设置较高,接近最低点的过程中逐渐降低。
对此函数求偏导数得:
通过梯度下降得到的是损失函数的极小值而不一定是最小值。
初始点不同,得到损失函数的最小值也不同,所以梯度下降得到的可能只是局部最小值。
在有多个样本时,我们将梯度下降进行一些改进:
批梯度下降(Batch Gradient Descent)
每下降一步,使用所有的训练集来计算梯度值。
注意,梯度下降可能得到局部最优,但在优化问题里我们已经证明线性回归只有一个最优点,因为损失函数J(θ)是一个二次的凸函数,不会产生局部最优的情况。
批梯度下降的执行过程:
批梯度下降每次都要对所有样本计算,在训练数据特别大时,计算量就会很大。所以演变出一个计算量较小,效果也不错的方法:随机梯度下降。
随机梯度下降 Stochastic Gradient Descent
随机梯度下降在计算下降最快的方向时时随机选一个数据进行计算,而不是扫描全部训练数据集,这样就加快了迭代速度。
随机梯度下降并不是沿着J(θ)下降最快的方向收敛,而是震荡的方式趋向极小点。
随机梯度下降的执行过程:
import numpy as np
import random
import matplotlib.pyplot as plt
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]
plt.xlabel('x')
plt.ylabel('y')
plt.plot(X,y,'r.')
n_epochs = 500
a0 = 0.1
decay_rate = 1
m = 100
num = [i for i in range(100)]
def learning_schedule(epoch_num):
return (1 / (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)
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+1)
theta = theta - learning_rate * gradients
x1=range(0,3)
y1=theta[0]*x1+theta[1]
plt.plot(x1,y1)
plt.show()
Mini-Batch 梯度下降
Mini-Batch 梯度下降在计算时随机选多个数据进行计算,得出梯度值。
相对于随机梯度下降,Mini-batch梯度下降降低了收敛波动性,使得更新更加稳定。相对于全量梯度下降,其提高了每次学习的速度。
import numpy as np
import random
import matplotlib.pyplot as plt
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)
plt.plot(X,y,'r*')
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
x1=range(0,3)
y1=theta[0]*x1+theta[1]
plt.plot(x1,y1)
plt.show()