《机器学习实战》学习笔记——第4章 训练模型
本文纯属菜鸟自学中的学习记录,以供将来遗忘后方便补习,如有错误还行大佬指出。
4.1 线性回归
书中代码缺失较多,学习此书一定要参考源代码进行学习,代码链接https://github.com/ageron/handson-ml2
# Python ≥3.5 is required
import sys
assert sys.version_info >= (3, 5) # assert 如果条件返回错误,则终止程序运行
# Scikit-Learn ≥0.20 is required
import sklearn
assert sklearn.__version__ >= "0.20"
# Common imports
import numpy as np
import os
# to make this notebook's output stable across runs
# 生成随机种子
np.random.seed(42)
import numpy as np
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
rand()生成0-1的均匀随机分布
randn()生成均值为0,方差为1的正态分布
使用标准方程计算。
X_b = np.c_[np.ones((100, 1)), X]
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
np.c_ 按行连接两个矩阵,把两个矩阵上下相加,下图分别为为X矩阵和相加后的X_b矩阵。
np.linalg.inv()矩阵求逆。
.dot()求内积,dot()求内积即将括号内的两个变量或矩阵相乘,或将.前的变量或矩阵与括号内的相乘。例:
np.dot(4, 5) ===> 4 * 5 = 20
X.np.dot(y) ===> X * y
书中的标准方程(正规方程)在吴恩达的机器学习课程中有讲到(链接https://www.bilibili.com/video/BV164411b7dx?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click),视频中并没有提到如何进行公示的推导,博主也暂时没有理解推导过程,这段将来学习过后会进行补充。
Θ
=
(
X
T
X
)
−
1
X
T
y
\Theta = (X^TX)^{-1}X^Ty
Θ=(XTX)−1XTy
下面使用θ做预测:
X_new = np.array([[0], [2]])
X_new_b = np.c_[np.ones((2, 1)), X_new]
y_predict = X_new_b.dot(theta_best)
X_new, y_predict
绘制图形:
plt.plot(X_new, y_predict, "r-")
plt.plot(X, y, "b.")
plt.axis([0, 2, 0, 15])
plt.show()
plot()函数中最后的引号(“”)中代表了图形的颜色及样式。
- 颜色
- b: blue
- g: green
- r: red
- c: cyan
- m: magenta
- y: yellow
- k: black
- w: white
- 样式
- -实线
- –虚线
- -.点划线
- :点线
- .点
这段代码可以自己尝试试一下,不同的颜色样式效果差很多。
使用Scikit_learn执行线性回归, Scikit_learn将很多常用的二机器学习算法都集中在库里,调用函数就可以实现简单的算法,当然,如果要将性能提的更高可能还是要自己写算法。
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X, y)
theta_best_svd, residuals, rank, s = np.linalg.lstsq(X_b, y, rcond=1e-6)
np.linalg.pinv(X_b).dot(y)
pinv为求伪逆,简单来说就是
p
i
n
v
(
X
)
=
(
X
T
X
)
−
1
X
T
pinv(X) = (X^TX)^{-1}X^T
pinv(X)=(XTX)−1XT
可以省去之前标准方程的那一长串代码。
4.2 梯度下降
梯度下降在书中共使用了三种方法:批量梯度下降、随机梯度下降、小批量梯度下降。
梯度下降法中,最关键的为代价函数的偏导数:
δ
δ
θ
j
M
S
E
(
θ
)
=
2
m
∑
i
=
1
m
(
θ
T
x
(
i
)
−
y
(
i
)
)
x
j
(
i
)
\frac{\delta}{\delta\theta_j}MSE(\theta) = \frac{2}{m}\sum_{i=1}^{m}{(\theta^Tx^{(i)} - y^{(i)})x^{(i)}_j}
δθjδMSE(θ)=m2i=1∑m(θTx(i)−y(i))xj(i)
在批量梯度下降和随机梯度下降中使用的是代价函数的梯度向量:
Δ
θ
M
S
E
(
θ
)
=
2
m
X
T
(
X
θ
−
y
)
\Delta_{\theta}MSE(\theta) = \frac{2}{m}X^T(X\theta - y)
ΔθMSE(θ)=m2XT(Xθ−y)
梯度下降的步骤为:
θ
(
下
一
步
)
=
θ
−
η
Δ
θ
M
S
E
(
θ
)
\theta^{(下一步)} = \theta - \eta\Delta_{\theta}MSE(\theta)
θ(下一步)=θ−ηΔθMSE(θ)
接下来是批量梯度下降的算法实现:
eta = 0.1 # 学习率
n_iterations = 1000
m = 100
theta = np.random.randn(2,1) # 生成随机的2行1列矩阵
for iteration in range(n_iterations):
gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
theta = theta - eta * gradients # 这两行代码即上面的代价函数的梯度向量和梯度下降公式
下面是随机梯度下降:
n_epochs = 50
t0, t1 = 5, 50 # learning schedule hyperparameters
def learning_schedule(t): # 学习率调度函数,使用此函数实现步长越来越小
return t0 / (t + t1)
theta = np.random.randn(2,1) # random initialization
for epoch in range(n_epochs):
for i in range(m):
random_index = np.random.randint(m)
xi = X_b[random_index:random_index+1]
yi = y[random_index:random_index+1]
gradients = 2 * xi.T.dot(xi.dot(theta) - yi)
eta = learning_schedule(epoch * m + i)
theta = theta - eta * gradients
最后是使用Scikit-Learn中的随机梯度下降执行线性回归,使用SGDRegressor类。
from sklearn.linear_model import SGDRegressor
sgd_reg = SGDRegressor(max_iter=1000, tol=1e-3, penalty=None, eta0=0.1, random_state=42)
sgd_reg.fit(X, y.ravel())
简单记录,仅此而已