监督学习
机器学习中有一类学习方法叫做监督学习,它是说为了训练一个模型,我们要提供这样一堆训练样本:每个训练样本既包括输入特征x,也包括对应的输出y(也叫做标记,label)。
比如下面这个例子
数据集
面积 户型 房价
2104 3 400
1600 3 330
2400 2 369
1416 2 232
3000 11 540
线性回归模型
上述数据集中输入特征x是二维的矢量,比如x1(i)表示数据集中第i个房子的面积,x2(i)表示数据集中第i个房子的房间数量。于是可以假设输入特征x与房价y满足线性函数
输入特征x是二维的矢量,比如x1(i)表示数据集中第i个房子的面积,x2(i)表示数据集中第i个房子的房间数量。于是可以假设输入特征x与房价y满足线性函数,比如:
为了简化表示,我们在输入特征中加入x0 = 1,于是得到:
其中n是输入的特征x的个数
根据一个训练集即数据集,我们应该怎么学习参数θ,从而达到比较好的拟合效果呢?一个直观的想法是使得预测值h(x)尽可能接近y,为了达到这个目的,我们对于每一个参数θ,定义一个函数用来描述h(x(i))'与对应的y(i)'的接近程度:
前面乘上的1/2是为了求导的时候,使常数系数消失。于是我们的目标就变为了调整θ使得函数J(θ)取得最小值,需要用到的方法为梯度下降法
梯度下降法
数学学习中我们学过怎样求函数的极值。函数的极值点,就是它的导数的那个点。因此我们可以通过解方程,求得函数的极值点。对于计算机来说,他可以一步一步的去把函数的极值点试出来
首先,我们随便选择一个点开始。接下来,每次迭代修改x的为x1,x2。。。经过数次迭代后最终达到函数最小值点。
为了能更快的达到函数最小值点,必须使得每次修改的值,都能往函数最小值那个方向前进,即我们每次都是向函数的梯度的相反方向来修改。什么是梯度呢?翻开大学高数课的课本,我们会发现梯度是一个向量,它指向函数值上升最快的方向。显然,梯度的反方向当然就是函数值下降最快的方向了。我们每次沿着梯度相反方向去修改的值,当然就能走到函数的最小值附近。之所以是最小值附近而不是最小值那个点,是因为我们每次移动的步长不会那么恰到好处,有可能最后一次迭代走远了越过了最小值那个点。步长的选择是门手艺,如果选择小了,那么就会迭代很多轮才能走到最小值附近;如果选择大了,那可能就会越过最小值很远,收敛不到一个好的点上。
由此我们得到梯度下降算法的公式,即L(θ)对θ的偏导
α称为学习率
梯度下降法就采用这样的思想:对θ设定一个随机初值θ0,然后迭代进行以下更新
import numpy as np
import matplotlib.pyplot as plt
import math
#输入样本数据
x = np.array([[2104,3],[1600,3],[2400,3],[1416,2],[3000,11]])
x1 = np.array([2104,1600.2400,1416,3000])
x2 = np.array([3,3,3,2,11])
t = np.array([400,330,369,232,540])
alpha = 0.1 #学习率
k0 = np.random.random()
k1 = np.random.random()
k2 = np.random.random()
k = np.array([k1,k2])
q = math.exp(-4)
e0 = 11 #赋初值
e1 = 11
e2 = 11
i = 0
while e0 >=q or e1 >=q or e2>=q:
e0 = (np.sum((x1[i]*k[i]+x2[i]*k[i]))+k0*1 -t[i])
e1 = e0*x1[i]
e2 = e0*x2[i]
k0 = k0 - alpha*e0 #迭代
k1 = k1 -alpha*e1
k2 = k2 -alpha*e2
if i < 4:
i+=1
else:
i=0
print(k0, k1, k2)
8.751815606431679 16610.95141539081 24.50579225924013