上一节的梯度下降是一种最小化成本函数 J 的方法。这一节我们将介绍另一种算法也可以实现该功能且不需要使用迭代。正规方程组通过计算成本函数对每个 θj 的偏导数,求出偏导为零的点来成本函数的最小值。为了不必写大量的代数式和矩阵导数,让我们约定一些矩阵计算的符号。
对于一个函数 f:Rm×n→R ,它将m*n的矩阵映射为一个实数,我们定义 f 对A的偏导为:
举个例子,如果 A=[A11A21A12A22] 是一个2*2的矩阵,函数 f 定义如下:
根据矩阵偏导公式可求得:
我们引入矩阵的迹,写作“ tr ”。对于一个n阶方阵A,它的迹是其对角线元素之和:
如果a是一个实数(也可看成1-by-1矩阵),有 tra=a 。迹操作符有这样的性质:如果矩阵 A 和 B 满足 AB 是方阵,则有 trAB=trBA ,由此可推得:
迹操作符的下列性质也容易证明。其中 A 和 B 是方阵, a 是实数:
结合矩阵的迹和矩阵导数,可以给出下列公式:
其中(4)只在矩阵A为满秩矩阵时成立。
了解了矩阵导数这一工具后,为了实现最小化 J(θ) 的目标,我们先设法将成本函数 J 用向量表示。
给定一个训练集,我们将其以m-by-n矩阵 X 的形式表示,其中每一行代表一个训练样本:
同时将包含所有目标值的 y⃗ 表示为一个m维的列向量:
因为 hθ(x(i))=(x(i))Tθ ,我们可以很容易地证明:
对于一个向量 z ,有 zTz=∑iz2i ,则:
最后要最小化 J ,我们要求解它关于 θ 的导数:
为了最小化 J(θ) ,我们要设法使其偏导数为零,这样就可推出正规方程:
那么权重矩阵 θ ,应该调整为:
举个例子,硝酸钠的溶解度试验中,测得不同温度x(单位:C)下,硝酸钠溶解于水中的溶解度y%的数据如下:
温度 | 0 | 4 | 10 | 15 | 21 | 29 | 36 | 51 | 68 |
---|---|---|---|---|---|---|---|---|---|
溶解度(%) | 66.7 | 71.0 | 76.3 | 80.6 | 85.7 | 92.9 | 99.4 | 113.6 | 125.1 |
求 y 和 x 的经验回归函数。
从上面的数据中可以,写出输入特征矩阵 X 和目标变量矩阵 y⃗ 。
代入公式 θ=(XTX)−1XTy⃗ 中求解权重 θ 的值,得:
于是所求的线性回归假设为:
实现的python代码如下:
# coding=utf-8
import matplotlib.pyplot as plt
import numpy as np
# 输入特征温度和标签溶解度
X = np.array([0 , 4, 10, 15, 21, 29, 36, 51, 68])
y = np.array([[66.7, 71.0, 76.3, 80.6, 85.7, 92.9, 99.4, 113.6, 125.1]])
# X转化为n*1的矩阵
X_0 = np.ones(len(X)).astype(dtype=np.int)
X_new = np.array([X_0, X])
# 根据求参数公式theta = (X.T * X)^-1 * X.T * y求解
temp = np.matrix(np.dot(X_new, X_new.T))
ans_matrix = temp ** -1 * X_new * y.T
# 训练后的模型,提取截距和系数
intercept = np.array(ans_matrix)[0][0]
coef = np.array(ans_matrix)[1][0]
# x从0到70,y=ax+b
lx = np.arange(0, 70)
ly = coef * lx + intercept
# 绘制拟合直线
plt.plot(lx, ly, color='blue')
# 绘制数据点和x轴y轴标题
plt.scatter(X, y, c='red', s=40, marker='o')
plt.xlabel('Temperature(C)')
plt.ylabel('Solubility(%)')
plt.show()
在特征维度少的情况下,正规方程组的计算会比梯度下降法快很多,推荐计算线性回归时多使用该方法。