目录
1. 初识机器学习
1.1 简介
机器学习是一种不需要明确编程就能让计算机学习的研究领域。机器学习可以分为:监督学习和无监督学习。
1.2 监督学习
监督学习是学习输入到输出映射的算法。对于监督学习而言,每一个给定的输入x,都对应一个正确的标签y。
通过学习正确的输入x和期望的输出y,算法最终能够只能接受输入,而不需要接受输出标签,就能给出合理准确的输出预测或猜测。
监督学习可分为以下两类:回归和分类。监督学习的一些应用如下表所示。
输入 | 输出 | 应用 |
---|---|---|
电子邮件 | 是否垃圾邮件?(否/是) | 垃圾邮件过滤 |
音频 | 转化后的文本 | 语音识别 |
英语 | 西班牙语 | 机器翻译 |
广告,用户信息 | 是否点击?(否/是) | 网上广告 |
图像,雷达信息 | 其他车辆的位置 | 自动驾驶汽车 |
手机图片 | 是否有瑕疵?(否/是) | 视觉检测 |
1.2.1 回归
回归是从无限多个可能的数中预测出一个数。
经典的例子有房价预测,比如说给定一些房子的面积以及对应的售价,让你预测没被给出的房子面积对应的售价。
1.2.2 分类
分类问题预测的类别可以是数值的,也可以是非数值的。相对于回归,分类预测的结果是小的,有限的输出类别集合中的一个类。
经典的例子有乳腺癌检测。比如说给定一些肿瘤的大小以及对应的状态(是否恶性),让你根据别的肿瘤大小预测该肿瘤是否恶性。
1.3 无监督学习
无监督学习的目的是找出一些结构,模式或者在数据中挖掘出的有意思的东西。与监督学习相比,无监督学习不需要给每个输入指定正确的标签。
无监督学习可分为以下三类:聚类,异常检测和降维。
2. 单变量线型回归
2.1 模型
对于一组给定的数据点 ( x i , y i ) (x_i, y_i) (xi,yi),i的取值为1到m的整数。要用这些数据拟合一条最优的直线,模型为 f w , b ( x ) = w x + b f_{w,b}(x)=wx+b fw,b(x)=wx+b,参数为 w , b w,b w,b。
2.2 代价函数
代价函数是评价模型的指标。在单变量线性回归中,代价函数为
J
(
w
,
b
)
=
1
2
m
∑
i
=
1
m
[
f
w
,
b
(
x
(
i
)
)
−
y
(
i
)
]
2
,
其中
m
是样本个数
\begin{align*} \Large J(w,b)&=\Large \frac{1}{2m}\sum\limits_{i=1}^{m}[f_{w,b}(x^{(i)})-y^{(i)}]^2, 其中m是样本个数 \end{align*}
J(w,b)=2m1i=1∑m[fw,b(x(i))−y(i)]2,其中m是样本个数
代价函数值越小,模型拟合效果越好,因此最优参数的值要使代价函数最小。
2.3 梯度下降法
梯度下降法可以最小化任意函数,因此可以使用梯度下降法来最小化上面的代价函数。
单变量线性回归的梯度下降算法:参数
w
w
w和
b
b
b的初值一般为0,用下面的公式同时更新
w
w
w和
b
b
b,直至
w
w
w和
b
b
b收敛。
w
=
w
−
α
∂
J
(
w
,
b
)
∂
w
=
w
−
α
m
∑
i
=
1
m
x
(
i
)
[
f
w
,
b
(
x
(
i
)
)
−
y
(
i
)
]
b
=
b
−
α
∂
J
(
w
,
b
)
∂
b
=
b
−
α
m
∑
i
=
1
m
[
f
w
,
b
(
x
(
i
)
)
−
y
(
i
)
]
其中
α
是学习率
\begin{align*} \Large w&=\Large w-\alpha\frac{\partial J(w, b)}{\partial w}\\ &=\Large w-\frac{\alpha}{m}\displaystyle\sum_{i=1}^mx^{(i)}[f_{w,b}(x^{(i)})-y^{(i)}]\\ \Large b&=\Large b-\alpha\frac{\partial J(w,b)}{\partial b}\\ &=\Large b-\frac{\alpha}{m}\displaystyle\sum_{i=1}^m[f_{w,b}(x^{(i)})-y^{(i)}]\\ &其中\alpha是学习率 \end{align*}
wb=w−α∂w∂J(w,b)=w−mαi=1∑mx(i)[fw,b(x(i))−y(i)]=b−α∂b∂J(w,b)=b−mαi=1∑m[fw,b(x(i))−y(i)]其中α是学习率
2.3.1 用例子理解梯度下降算法
训练集有如下几个数据点:(1,1),(2,2),(3,3)。
假设参数
b
b
b等于0,那么模型变为
f
w
(
x
)
=
w
x
f_w(x)=wx
fw(x)=wx,代价函数为
J
(
w
)
=
1
6
∑
i
=
1
3
(
w
x
(
i
)
−
y
(
i
)
)
2
J(w)=\displaystyle\frac{1}{6}\sum_{i=1}^3(wx^{(i)}-y^{(i)})^2
J(w)=61i=1∑3(wx(i)−y(i))2。
w
在
[
0
,
2
]
w在[0,2]
w在[0,2]范围内的代价函数如下图所示。
画出上图的Python代码如下:
import matplotlib.pyplot as plt
import numpy as np
plt.style.use("deeplearning.mplstyle")
plt.rcParams["font.family"] = "sans-serif"
plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei"] # 设置中文字体
plt.rcParams["axes.unicode_minus"] = False # 正确显示负号
s = 10 ** 6
m = 3
x = np.array([1, 2, 3]) # 特征
y = np.array([1, 2, 3]) # 目标
w = np.linspace(0, 2, s) # 参数w
jw = np.sum((w.reshape(s, -1) * x - y) ** 2, axis=1) / (2 * m) # 代价函数
plt.plot(w, jw)
plt.title("f=wx时的代价函数")
plt.xlabel("w")
plt.ylabel("J(w)")
w
w
w的更新算法公式为
w
=
w
−
α
3
∑
i
=
1
3
x
(
i
)
(
w
x
(
i
)
−
y
(
i
)
)
w=\displaystyle w-\frac{\alpha}{3}\sum_{i=1}^3{{x^{(i)}(wx^{(i)}-y^{(i)})}}
w=w−3αi=1∑3x(i)(wx(i)−y(i))。接下来令
w
w
w的初值为0,
α
\alpha
α的值为0.05,分析
w
w
w的收敛过程。
从下图中,可以看出
w
w
w从初值0开始沿着该点的切线方向一路下降,直至
w
w
w的值为1时。此时
w
w
w收敛,达到了
J
(
w
)
J(w)
J(w)的局部最小值。
画出上图的Python代码如下:
plt.plot(w, jw, zorder=1)
plt.title("w从初值0到收敛的过程")
plt.xlabel("w")
plt.ylabel("J(w)")
old_w = 0
alpha = 0.05 # 学习率
count = 0
while (1):
new_w = old_w - alpha * np.sum(x * (old_w * x - y)) / m # 更新参数w
old_jw = np.sum((old_w * x - y) ** 2) / (2 * m)
new_jw = np.sum((new_w * x - y) ** 2) / (2 * m)
count += 1
plt.scatter(old_w, old_jw, c="red", zorder=2)
plt.annotate(
"",
xy=(new_w, new_jw),
xytext=(old_w, old_jw),
arrowprops=dict(facecolor="black", shrink=0.05, width=2, headwidth=5),
)
if (np.isclose(old_jw, new_jw, atol=1e-8, rtol=1e-7)):
break
old_w = new_w
print(count)
2.3.2 学习率
学习率也是梯度下降算法中重要的一环。一方面,如果学习率很小,那么梯度下降算法到达局部最小值需要经过很多次的迭代;另一方面,如果学习率很大,那么梯度下降算法会不断越过局部最小值,永远不接近局部最小值。
学习率小的情况就不举例了,上面2.3.1中
w
w
w从初值0开始经过了36次迭代。在学习率大的情况下,令
α
\alpha
α的值为1,w的初值为0.05,分析w变化的过程。
从下图中,可以看出
w
w
w在不断跃过收敛值1,左右摇摆,最终$J(w)永远不会到达局部最小值。
画出上图的Python代码如下:
s2 = 10 ** 6
w_1 = np.linspace(-1000, 1000, s2) # 参数w
jw_1 = np.sum((w_1.reshape(s2, -1) * x - y) ** 2, axis=1) / (2 * m) # 代价函数
plt.plot(w_1, jw_1)
plt.title("学习率大的情况下w发散的过程")
plt.xlabel("w")
plt.ylabel("J(w)")
old_w = 0.05
alpha = 1 # 学习率
count = 0
while 1:
new_w = old_w - alpha * np.sum(x * (old_w * x - y)) / m # 更新参数w
old_jw = np.sum((old_w * x - y) ** 2) / (2 * m)
new_jw = np.sum((new_w * x - y) ** 2) / (2 * m)
count += 1
plt.scatter(old_w, old_jw, c="red", zorder=2)
plt.annotate(
"",
xy=(new_w, new_jw),
xytext=(old_w, old_jw),
arrowprops=dict(facecolor="black", shrink=0.05, width=2, headwidth=5),
)
if count == 5:
plt.scatter(new_w, new_jw, c="red", zorder=2)
break
old_w = new_w
2.4 训练和预测的过程
参考
吴恩达 机器学习视频