机器学习 线性回归

线性回归

这部分是我学习线性回归的记录,同时完成了吴恩达机器学习ex1,用python实现了简单的线性回归,参考了和鲸社区中大佬的代码

线性回归

线性回归其实就是把所有特征和标签的关系拟合成一条直线,即$h_{ \theta }\left( x \right)={ \theta_{ 0 } }+{ \theta_{ 1 } } { x_{ 1 } }+{ \theta_{ 2 } } { x_{ 2 } }+…+{ \theta_{ n } } { x_{ n } }$ 线性回归就是求参数$\theta_0$ 到 $\theta_n$ ,实际上就是参数估计的问题。

python实现

1
2
3
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

1 简单练习

输出一个5*5的单位矩阵

1
2
A = np.eye(5)
A
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

2 单变量的线性回归

整个2的部分需要根据城市人口数量,预测开小吃店的利润
数据在ex1data1.txt里,可以在网站中获得,第一列是城市人口数量,第二列是该城市小吃店利润。

2.1 Plotting the Data

读入数据,然后展示数据

1
2
3
path =  './ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head()

</style>

Population Profit
0 6.1101 17.5920
1 5.5277 9.1302
2 8.5186 13.6620
3 7.0032 11.8540
4 5.8598 6.8233

</div>

1
data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))plt.show()

png

2.2 梯度下降

这个部分你需要在现有数据集上,训练线性回归的参数θ

2.2.1 公式

1
2
3
def computeCost(X, y, theta):    
inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner) / (2 * len(X))#这个部分计算J(Ѳ),X是矩阵
1
2
3
4
5
6
def computeCost2(X, y, theta):      
m = len(y)
J = 0
J = (np.transpose(X * theta.T - y)) * (X * theta.T - y) / (2 * m)
return J
#不看上面cell,尝试自己实现一下
1
##computeCost(X, y, theta)
1
##computeCost2(X, y, theta)#实现好之后,用相同的方法调用一遍看答案是否一致

2.2.2实现

数据前面已经读取完毕,我们要为加入一列x,用于更新$\theta_0$,然后我们将$\theta$初始化为0,学习率初始化为0.01,迭代次数为1500次

1
data.insert(0, 'Ones', 1)

现在我们来做一些变量初始化。

1
2
3
4
# 初始化X和y
cols = data.shape[1]
X = data.iloc[:,:-1]#X是data里的除最后列
y = data.iloc[:,cols-1:cols]#y是data最后一列

观察下 X (训练集) and y (目标变量)是否正确.

1
X.head()#head()是观察前5行

</style>

Ones Population
0 1 6.1101
1 1 5.5277
2 1 8.5186
3 1 7.0032
4 1 5.8598

</div>

1
y.head()

</style>

Profit
0 17.5920
1 9.1302
2 13.6620
3 11.8540
4 6.8233

</div>

代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta。

1
2
3
X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0,0]))

看下维度

1
X.shape, theta.shape, y.shape
((97, 2), (1, 2), (97, 1))
1
computeCost(X, y, theta)
32.072733877455676
1
computeCost2(X, y, theta)
matrix([[32.07273388]])

2.2.3计算J(θ)

计算代价函数 (theta初始值为0),答案应该是32.07

2.2.4 梯度下降

记住J($\theta$)的变量是$\theta$,而不是X和y,意思是说,我们变化$\theta$的值来使J($\theta$)变化,而不是变化X和y的值。
一个检查梯度下降是不是在正常运作的方式,是打印出每一步J($\theta$)的值,看他是不是一直都在减小,并且最后收敛至一个稳定的值。
$\theta$最后的结果会用来预测小吃店在35000及70000人城市规模的利润。

1
2
3
4
5
6
7
8
9
10
11
def gradientDescent(X, y, theta, alpha, iters):    
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)
for i in range(iters):
error = (X * theta.T) - y
for j in range(parameters):
term = np.multiply(error, X[:,j])
temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term)) theta = temp
cost[i] = computeCost(X, y, theta)
return theta, cost#这个部分实现了Ѳ的更新

初始化一些附加变量 - 学习速率α和要执行的迭代次数,2.2.2中已经提到。

1
2
alpha = 0.01
iters = 1500

现在让我们运行梯度下降算法来将我们的参数θ适合于训练集。

1
g, cost = gradientDescent(X, y, theta, alpha, iters)g
matrix([[-3.63029144,  1.16636235]])
1
cost
array([6.73719046, 5.93159357, 5.90115471, ..., 4.48343473, 4.48341145,       4.48338826])
1
predict1 = [1,3.5]*g.Tprint("predict1:",predict1)predict2 = [1,7]*g.Tprint("predict2:",predict2)#预测35000和70000城市规模的小吃摊利润
predict1: [[0.45197679]]predict2: [[4.53424501]]
1
2
3
4
5
6
7
8
9
10
x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = g[0, 0] + (g[0, 1] * x)
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()#原始数据以及拟合的直线

png

2.4 可视化J(θ)

此步可以便于你理解J($\theta$)以及梯度下降。
三维图显示了${ { \theta } _ { 0 } }$和$ { { \theta } _ { 1 } } $与J($\theta$)的对应关系,J($\theta$)是一个碗状的图形,并且有全局最小值。这个最小值就是$ { { \theta } _ { 0 } } $和$ { { \theta } _ { 1 } } $的最优解。梯度下降的每一步都会更接近这个最小值

并不会用python复现,截个图意思一下

Image Name

3 多变量线性回归

ex1data2.txt里的数据,第一列是房屋大小,第二列是卧室数量,第三列是房屋售价
根据已有数据,建立模型,预测房屋的售价

1
path =  './ex1data2.txt'data2 = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])data2.head()

</style>

Size Bedrooms Price
0 2104 3 399900
1 1600 3 329900
2 2400 3 369000
3 1416 2 232000
4 3000 4 539900

</div>

3.1 特征归一化

观察数据发现,size变量是bedrooms变量的1000倍大小,统一量级会让梯度下降收敛的更快。做法就是,将每类特征减去他的平均值后除以标准差

1
2
data2 = (data2 - data2.mean()) / data2.std()
data2.head()

</style>

Size Bedrooms Price
0 0.130010 -0.223675 0.475747
1 -0.504190 -0.223675 -0.084074
2 0.502476 -0.223675 0.228626
3 -0.735723 -1.537767 -0.867025
4 1.257476 1.090417 1.595389

</div>

3.2 梯度下降

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 加一列常数项
data2.insert(0, 'Ones', 1)

# 初始化X和y
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]

# 转换成matrix格式,初始化theta
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta2 = np.matrix(np.array([0,0,0]))

# 运行梯度下降算法
g2, cost2 = gradientDescent(X2, y2, theta2, alpha, iters)
g2
matrix([[-1.10856950e-16,  8.84042349e-01, -5.24551809e-02]])

3.3 正规方程

正规方程是通过求解下面的方程来找出使得代价函数最小的参数的:$\frac { \partial } { \partial { { \theta } _ { j } } } J\left( { { \theta } _ { j } } \right)=0$ 。
假设我们的训练集特征矩阵为 X(包含了$ { { x } _ { 0 } } =1$)并且我们的训练集结果为向量 y,则利用正规方程解出向量 $\theta = { { \left( { { X } ^ { T } } X \right) } ^ { -1 } } { { X } ^ { T } } y$ 。
上标T代表矩阵转置,上标-1 代表矩阵的逆。设矩阵$A= { { X } ^ { T } } X$,则:$ { { \left( { { X } ^ { T } } X \right) } ^ { -1 } } = { { A } ^ { -1 } } $

梯度下降与正规方程的比较:

梯度下降:需要选择学习率α,需要多次迭代,当特征数量n大时也能较好适用,适用于各种类型的模型

正规方程:不需要选择学习率α,一次计算得出,需要计算$ { { \left( { { X } ^ { T } } X \right) } ^ { -1 } } $,如果特征数量n较大则运算代价大,因为矩阵逆的计算时间复杂度为$O(n^3)$,通常来说当$n$小于10000 时还是可以接受的,只适用于线性模型,不适合逻辑回归模型等其他模型

1
2
3
4
# 正规方程
def normalEqn(X, y):
theta = np.linalg.inv(X.T@X)@X.T@y#X.T@X等价于X.T.dot(X)
return theta
1
2
final_theta2=normalEqn(X, y)#这里用的是data1的数据
final_theta2
matrix([[-3.89578088],
        [ 1.19303364]])
1
#梯度下降得到的结果是matrix([[-3.24140214,  1.1272942 ]])

黄海广博士的笔记

=====

四、多变量线性回归(Linear Regression with Multiple Variables)

4.1 多维特征

目前为止,我们探讨了单变量/特征的回归模型,现在我们对房价模型增加更多的特征,例如房间数楼层等,构成一个含有多个变量的模型,模型中的特征为$\left( { x_{ 1 } },{ x_{ 2 } },…,{ x_{ n } } \right)$。

增添更多特征后,我们引入一系列新的注释:

$n$ 代表特征的数量

${ x^{ \left( i \right) } }$代表第 $i$ 个训练实例,是特征矩阵中的第$i$行,是一个向量vector)。

比方说,上图的

${ x }^{ (2) }\text{ = }\begin{bmatrix} 1416\\\ 3\\\ 2\\\ 40 \end{bmatrix}$,

${ x }_{ j }^{ \left( i \right) }$代表特征矩阵中第 $i$ 行的第 $j$ 个特征,也就是第 $i$ 个训练实例的第 $j$ 个特征。

如上图的$x_{ 2 }^{ \left( 2 \right) }=3,x_{ 3 }^{ \left( 2 \right) }=2$,

支持多变量的假设 $h$ 表示为:$h_{ \theta }\left( x \right)={ \theta_{ 0 } }+{ \theta_{ 1 } } { x_{ 1 } }+{ \theta_{ 2 } } { x_{ 2 } }+…+{ \theta_{ n } } { x_{ n } }$,

这个公式中有$n+1$个参数和$n$个变量,为了使得公式能够简化一些,引入$x_{ 0 }=1$,则公式转化为:$h_{ \theta } \left( x \right)={ \theta_{ 0 } } { x_{ 0 } }+{ \theta_{ 1 } } { x_{ 1 } }+{ \theta_{ 2 } } { x_{ 2 } }+…+{ \theta_{ n } } { x_{ n } }$

此时模型中的参数是一个$n+1$维的向量,任何一个训练实例也都是$n+1$维的向量,特征矩阵$X$的维度是 $m*(n+1)$。 因此公式可以简化为:$h_{ \theta } \left( x \right)={ \theta^{ T } }X$,其中上标$T$代表矩阵转置。

4.2 多变量梯度下降

参考视频: 4 - 2 - Gradient Descent for Multiple Variables (5 min).mkv

与单变量线性回归类似,在多变量线性回归中,我们也构建一个代价函数,则这个代价函数是所有建模误差的平方和,即:$J\left( { \theta_{ 0 } },{ \theta_{ 1 } }…{ \theta_{ n } } \right)=\frac{ 1 } { 2m }\sum\limits_{ i=1 }^{ m } { { { \left( h_{ \theta } \left({ x }^{ \left( i \right) } \right)-{ y }^{ \left( i \right) } \right) }^{ 2 } } }$ ,

其中:$h_{ \theta }\left( x \right)=\theta^{ T }X={ \theta_{ 0 } }+{ \theta_{ 1 } } { x_{ 1 } }+{ \theta_{ 2 } } { x_{ 2 } }+…+{ \theta_{ n } } { x_{ n } }$ ,

我们的目标和单变量线性回归问题中一样,是要找出使得代价函数最小的一系列参数。
多变量线性回归的批量梯度下降算法为:

即:

求导数后得到:

当$n>=1$时,
${ { \theta }_{ 0 } }:={ { \theta }_{ 0 } }-a\frac{ 1 } { m }\sum\limits_{ i=1 }^{ m } { ({ { h }_{ \theta } }({ { x }^{ (i) } })-{ { y }^{ (i) } }) }x_{ 0 }^{ (i) }$

${ { \theta }_{ 1 } }:={ { \theta }_{ 1 } }-a\frac{ 1 } { m }\sum\limits_{ i=1 }^{ m } { ({ { h }_{ \theta } }({ { x }^{ (i) } })-{ { y }^{ (i) } }) }x_{ 1 }^{ (i) }$

${ { \theta }_{ 2 } }:={ { \theta }_{ 2 } }-a\frac{ 1 } { m }\sum\limits_{ i=1 }^{ m } { ({ { h }_{ \theta } }({ { x }^{ (i) } })-{ { y }^{ (i) } }) }x_{ 2 }^{ (i) }$

我们开始随机选择一系列的参数值,计算所有的预测结果后,再给所有的参数一个新的值,如此循环直到收敛。

代码示例:

计算代价函数
$J\left( \theta \right)=\frac{ 1 } { 2m }\sum\limits_{ i=1 }^{ m } { { { \left( { h_{ \theta } }\left( { x^{ (i) } } \right)-{ y^{ (i) } } \right) }^{ 2 } } }$
其中:${ h_{ \theta } }\left( x \right)={ \theta^{ T } }X={ \theta_{ 0 } } { x_{ 0 } }+{ \theta_{ 1 } } { x_{ 1 } }+{ \theta_{ 2 } } { x_{ 2 } }+…+{ \theta_{ n } } { x_{ n } }$

Python 代码:

1
2
3
def computeCost(X, y, theta):
inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner) / (2 * len(X))

4.3 梯度下降法实践1-特征缩放

参考视频: 4 - 3 - Gradient Descent in Practice I - Feature Scaling (9 min).mkv

在我们面对多维特征问题的时候,我们要保证这些特征都具有相近的尺度,这将帮助梯度下降算法更快地收敛。

以房价问题为例,假设我们使用两个特征,房屋的尺寸和房间的数量,尺寸的值为 0-2000平方英尺,而房间数量的值则是0-5,以两个参数分别为横纵坐标,绘制代价函数的等高线图能,看出图像会显得很扁,梯度下降算法需要非常多次的迭代才能收敛。

解决的方法是尝试将所有特征的尺度都尽量缩放到-1到1之间。如图:

最简单的方法是令:${ { x }_{ n } }=\frac{ { { x }_{ n } }-{ { \mu }_{ n } } } { { { s }_{ n } } }$,其中 ${ \mu_{ n } }$是平均值,${ s_{ n } }$是标准差。

4.4 梯度下降法实践2-学习率

参考视频: 4 - 4 - Gradient Descent in Practice II - Learning Rate (9 min).mkv

梯度下降算法收敛所需要的迭代次数根据模型的不同而不同,我们不能提前预知,我们可以绘制迭代次数和代价函数的图表来观测算法在何时趋于收敛。

也有一些自动测试是否收敛的方法,例如将代价函数的变化值与某个阀值(例如0.001)进行比较,但通常看上面这样的图表更好。

梯度下降算法的每次迭代受到学习率的影响,如果学习率$a$过小,则达到收敛所需的迭代次数会非常高;如果学习率$a$过大,每次迭代可能不会减小代价函数,可能会越过局部最小值导致无法收敛。

通常可以考虑尝试些学习率:

$\alpha=0.01,0.03,0.1,0.3,1,3,10$

4.5 特征和多项式回归

参考视频: 4 - 5 - Features and Polynomial Regression (8 min).mkv

如房价预测问题,

$h_{ \theta }\left( x \right)={ \theta_{ 0 } }+{ \theta_{ 1 } }\times{ frontage }+{ \theta_{ 2 } }\times{ depth }$

${ x_{ 1 } }=frontage$(临街宽度),${ x_{ 2 } }=depth$(纵向深度),$x=frontage*depth=area$(面积),则:${ h_{ \theta } }\left( x \right)={ \theta_{ 0 } }+{ \theta_{ 1 } }x$。
线性回归并不适用于所有数据,有时我们需要曲线来适应我们的数据,比如一个二次方模型:$h_{ \theta }\left( x \right)={ \theta_{ 0 } }+{ \theta_{ 1 } } { x_{ 1 } }+{ \theta_{ 2 } } { x_{ 2 }^2 }$
或者三次方模型: $h_{ \theta }\left( x \right)={ \theta_{ 0 } }+{ \theta_{ 1 } } { x_{ 1 } }+{ \theta_{ 2 } } { x_{ 2 }^2 }+{ \theta_{ 3 } } { x_{ 3 }^3 }$

通常我们需要先观察数据然后再决定准备尝试怎样的模型。 另外,我们可以令:

${ { x }_{ 2 } }=x_{ 2 }^{ 2 },{ { x }_{ 3 } }=x_{ 3 }^{ 3 }$,从而将模型转化为线性回归模型。

根据函数图形特性,我们还可以使:

${ { { h } }_{ \theta } }(x)={ { \theta }_{ 0 } }\text{ + } { { \theta }_{ 1 } }(size)+{ { \theta }_{ 2 } } { { (size) }^{ 2 } }$

或者:

${ { { h } }_{ \theta } }(x)={ { \theta }_{ 0 } }\text{ + } { { \theta }_{ 1 } }(size)+{ { \theta }_{ 2 } }\sqrt{ size }$

注:如果我们采用多项式回归模型,在运行梯度下降算法前,特征缩放非常有必要。

4.6 正规方程

参考视频: 4 - 6 - Normal Equation (16 min).mkv

到目前为止,我们都在使用梯度下降算法,但是对于某些线性回归问题,正规方程方法是更好的解决方案。如:

正规方程是通过求解下面的方程来找出使得代价函数最小的参数的:$\frac{ \partial } { \partial{ \theta_{ j } } }J\left( { \theta_{ j } } \right)=0$ 。
假设我们的训练集特征矩阵为 $X$(包含了 ${ { x }_{ 0 } }=1$)并且我们的训练集结果为向量 $y$,则利用正规方程解出向量 $\theta ={ { \left( { X^T }X \right) }^{ -1 } } { X^{ T } }y$ 。
上标T代表矩阵转置,上标-1 代表矩阵的逆。设矩阵$A={ X^{ T } }X$,则:${ { \left( { X^T }X \right) }^{ -1 } }={ A^{ -1 } }$
以下表示数据为例:

即:

运用正规方程方法求解参数:

Octave 中,正规方程写作:

1
pinv(X'*X)*X'*y

注:对于那些不可逆的矩阵(通常是因为特征之间不独立,如同时包含英尺为单位的尺寸和米为单位的尺寸两个特征,也有可能是特征数量大于训练集的数量),正规方程方法是不能用的。

梯度下降与正规方程的比较:

梯度下降 正规方程
需要选择学习率$\alpha$ 不需要
需要多次迭代 一次运算得出
当特征数量$n$大时也能较好适用 需要计算${ { \left( { { X }^{ T } }X \right) }^{ -1 } }$ 如果特征数量n较大则运算代价大,因为矩阵逆的计算时间复杂度为$O\left( { { n }^{ 3 } } \right)$,通常来说当$n$小于10000 时还是可以接受的
适用于各种类型的模型 只适用于线性模型,不适合逻辑回归模型等其他模型

总结一下,只要特征变量的数目并不大,标准方程是一个很好的计算参数$\theta $的替代方法。具体地说,只要特征变量数量小于一万,我通常使用标准方程法,而不使用梯度下降法。

随着我们要讲的学习算法越来越复杂,例如,当我们讲到分类算法,像逻辑回归算法,我们会看到,实际上对于那些算法,并不能使用标准方程法。对于那些更复杂的学习算法,我们将不得不仍然使用梯度下降法。因此,梯度下降法是一个非常有用的算法,可以用在有大量特征变量的线性回归问题。或者我们以后在课程中,会讲到的一些其他的算法,因为标准方程法不适合或者不能用在它们上。但对于这个特定的线性回归模型,标准方程法是一个比梯度下降法更快的替代算法。所以,根据具体的问题,以及你的特征变量的数量,这两种算法都是值得学习的。

正规方程的python实现:

1
2
3
4
5
6
7
import numpy as np

def normalEqn(X, y):

theta = np.linalg.inv(X.T@X)@X.T@y #X.T@X等价于X.T.dot(X)

return theta

4.7 正规方程及不可逆性(可选)

参考视频: 4 - 7 - Normal Equation Noninvertibility (Optional) (6 min).mkv

在这段视频中谈谈正规方程 ( normal equation ),以及它们的不可逆性。
由于这是一种较为深入的概念,并且总有人问我有关这方面的问题,因此,我想在这里来讨论它,由于概念较为深入,所以对这段可选材料大家放轻松吧,也许你可能会深入地探索下去,并且会觉得理解以后会非常有用。但即使你没有理解正规方程和线性回归的关系,也没有关系。

我们要讲的问题如下:$\theta ={ { \left( { X^{ T } }X \right) }^{ -1 } } { X^{ T } }y$

备注:本节最后我把推导过程写下。

有些同学曾经问过我,当计算 $\theta$=inv(X'X ) X'y ,那对于矩阵$X’X$的结果是不可逆的情况咋办呢?
如果你懂一点线性代数的知识,你或许会知道,有些矩阵可逆,而有些矩阵不可逆。我们称那些不可逆矩阵为奇异或退化矩阵。
问题的重点在于$X’X$的不可逆的问题很少发生,在Octave里,如果你用它来实现$\theta$的计算,你将会得到一个正常的解。在Octave里,有两个函数可以求解矩阵的逆,一个被称为pinv(),另一个是inv(),这两者之间的差异是些许计算过程上的,一个是所谓的伪逆,另一个被称为逆。使用pinv() 函数可以展现数学上的过程,这将计算出$\theta$的值,即便矩阵$X’X$是不可逆的。

pinv()inv() 之间,又有哪些具体区别呢 ?

其中inv() 引入了先进的数值计算的概念。例如,在预测住房价格时,如果${ x_{ 1 } }$是以英尺为尺寸规格计算的房子,${ x_{ 2 } }$是以平方米为尺寸规格计算的房子,同时,你也知道1米等于3.28英尺 ( 四舍五入到两位小数 ),这样,你的这两个特征值将始终满足约束:${ x_{ 1 } }={ x_{ 2 } }*{ { \left( 3.28 \right) }^{ 2 } }$。
实际上,你可以用这样的一个线性方程,来展示那两个相关联的特征值,矩阵$X’X$将是不可逆的。

第二个原因是,在你想用大量的特征值,尝试实践你的学习算法的时候,可能会导致矩阵$X’X$的结果是不可逆的。
具体地说,在$m$小于或等于n的时候,例如,有$m$等于10个的训练样本也有$n$等于100的特征数量。要找到适合的$(n +1)$ 维参数矢量$\theta$,这将会变成一个101维的矢量,尝试从10个训练样本中找到满足101个参数的值,这工作可能会让你花上一阵子时间,但这并不总是一个好主意。因为,正如我们所看到你只有10个样本,以适应这100或101个参数,数据还是有些少。

稍后我们将看到,如何使用小数据样本以得到这100或101个参数,通常,我们会使用一种叫做正则化的线性代数方法,通过删除某些特征或者是使用某些技术,来解决当$m$比$n$小的时候的问题。即使你有一个相对较小的训练集,也可使用很多的特征来找到很多合适的参数。
总之当你发现的矩阵$X’X$的结果是奇异矩阵,或者找到的其它矩阵是不可逆的,我会建议你这么做。

首先,看特征值里是否有一些多余的特征,像这些${ x_{ 1 } }$和${ x_{ 2 } }$是线性相关的,互为线性函数。同时,当有一些多余的特征时,可以删除这两个重复特征里的其中一个,无须两个特征同时保留,将解决不可逆性的问题。因此,首先应该通过观察所有特征检查是否有多余的特征,如果有多余的就删除掉,直到他们不再是多余的为止,如果特征数量实在太多,我会删除些 用较少的特征来反映尽可能多内容,否则我会考虑使用正规化方法。
如果矩阵$X’X$是不可逆的,(通常来说,不会出现这种情况),如果在Octave里,可以用伪逆函数pinv() 来实现。这种使用不同的线性代数库的方法被称为伪逆。即使$X’X$的结果是不可逆的,但算法执行的流程是正确的。总之,出现不可逆矩阵的情况极少发生,所以在大多数实现线性回归中,出现不可逆的问题不应该过多的关注${ X^{ T } }X$是不可逆的。

增加内容:

$\theta ={ { \left( { X^{ T } }X \right) }^{ -1 } } { X^{ T } }y$ 的推导过程:

$J\left( \theta \right)=\frac{ 1 } { 2m }\sum\limits_{ i=1 }^{ m } { { { \left( { h_{ \theta } }\left( { x^{ (i) } } \right)-{ y^{ (i) } } \right) }^{ 2 } } }$
其中:${ h_{ \theta } }\left( x \right)={ \theta^{ T } }X={ \theta_{ 0 } } { x_{ 0 } }+{ \theta_{ 1 } } { x_{ 1 } }+{ \theta_{ 2 } } { x_{ 2 } }+…+{ \theta_{ n } } { x_{ n } }$

将向量表达形式转为矩阵表达形式,则有$J(\theta )=\frac{ 1 } { 2 } { { \left( X\theta -y\right) }^{ 2 } }$ ,其中$X$为$m$行$n$列的矩阵($m$为样本个数,$n$为特征个数),$\theta$为$n$行1列的矩阵,$y$为$m$行1列的矩阵,对$J(\theta )$进行如下变换

$J(\theta )=\frac{ 1 } { 2 } { { \left( X\theta -y\right) }^{ T } }\left( X\theta -y \right)$

​ $=\frac{ 1 } { 2 }\left( { { \theta }^{ T } } { { X }^{ T } }-{ { y }^{ T } } \right)\left(X\theta -y \right)$

​ $=\frac{ 1 } { 2 }\left( { { \theta }^{ T } } { { X }^{ T } }X\theta -{ { \theta }^{ T } } { { X }^{ T } }y-{ { y }^{ T } }X\theta -{ { y }^{ T } }y \right)$

接下来对$J(\theta )$偏导,需要用到以下几个矩阵的求导法则:

$\frac{ dAB } { dB }={ { A }^{ T } }$

$\frac{ d{ { X }^{ T } }AX } { dX }=2AX$

所以有:

$\frac{ \partial J\left( \theta \right) } { \partial \theta }=\frac{ 1 } { 2 }\left(2{ { X }^{ T } }X\theta -{ { X }^{ T } }y -{ }({ { y }^{ T } }X )^{ T }-0 \right)$

$=\frac{ 1 } { 2 }\left(2{ { X }^{ T } }X\theta -{ { X }^{ T } }y -{ { X }^{ T } }y -0 \right)$

​ $={ { X }^{ T } }X\theta -{ { X }^{ T } }y$

令$\frac{ \partial J\left( \theta \right) } { \partial \theta }=0$,

则有$\theta ={ { \left( { X^{ T } }X \right) }^{ -1 } } { X^{ T } }y$