一元线性回归
构造一个简单的一元线性回归数据集
x_train = [4, 8, 5, 10, 12]
y_train = [20, 50, 30, 70, 60]
我们需要利用下面这个公式拟合
y
t
r
a
i
n
=
w
×
x
t
r
a
i
n
+
b
y_{train}=w \times x_{train}+b
ytrain=w×xtrain+b
其中
w
=
∑
(
x
i
−
x
‾
)
(
y
i
−
y
‾
)
∑
(
x
i
−
x
‾
)
2
,
b
=
y
‾
−
w
×
x
‾
w =\frac{\sum{(x_i-\overline{x}) (y_i-\overline{y}) }}{\sum({x_i-\overline{x}})^2}, \ b= \overline{y}-w\times\overline{x}
w=∑(xi−x)2∑(xi−x)(yi−y), b=y−w×x
多元线性回归
多元线性回归即为多变量问题,对应的多元数据集举例如下
x_train = [[3, 2, 9],
[4, 10, 2],
[3, 4, 9],
[12, 3, 4]]
y_train = [20, 72, 21, 20]
则我们需要利用最小二乘解求其最佳解:
首先在x_train
前加入常数项1使得
x_train = np.mat(np.c_[np.ones(x_train.shape[0]), x_train])
Results=> x_train = [[1, 3, 2, 9],
[1, 4, 10, 2],
[1, 3, 4, 9],
[1, 12, 3, 4]]
利用下面公式进行最小二乘解拟合:
arg
min
B
∣
∣
y
t
r
a
i
n
−
B
×
x
t
r
a
i
n
∣
∣
\arg \min_B||y_{train} - B\times x_{train}||
argBmin∣∣ytrain−B×xtrain∣∣
其中, 当x_train
为列满秩矩阵时,B可以用加号广义逆得到:
B
=
(
x
t
r
a
i
n
H
x
t
r
a
i
n
)
−
1
∗
x
t
r
a
i
n
H
B = (x_{train}^H x_{train})^{-1}*x_{train}^H
B=(xtrainHxtrain)−1∗xtrainH
这里华为AI Gallery中机器学习给出的例子为
# 根据最小二乘法的目标函数求导为0得到最优参数向量B的解析解公式如下,可以直接求取最优参数向量
B = np.linalg.inv(X.T * X) * (X.T) * (Y.T)
源代码入口:华为AI Gallery进入后
在此粘贴其源代码方便观看
# 多元线性回归的实现
# 导入模块
import numpy as np
import pandas as pd
# 构造数据,前三列表示自变量X,最后一列表示因变量Y
data = np.array([[3, 2, 9, 20],
[4, 10, 2, 72],
[3, 4, 9, 21],
[12, 3, 4, 20]])
print("data:", data, "\n")
X = data[:, :-1]
Y = data[:, -1]
X = np.mat(np.c_[np.ones(X.shape[0]), X]) # 为系数矩阵增加常数项系数
Y = np.mat(Y) # 数组转化为矩阵
print("X:", X, "\n")
print("Y:", Y, "\n")
# 根据最小二乘法的目标函数求导为0得到最优参数向量B的解析解公式如下,可以直接求取最优参数向量
B = np.linalg.inv(X.T * X) * (X.T) * (Y.T)
print("B:", B, "\n") # 输出系数,第一项为常数项,其他为回归系数
print("1,60,60,60预测结果:", np.mat([1, 60, 60, 60]) * B, "\n") # 预测结果
# 相关系数
Q_e = 0
Q_E = 0
Y_mean = np.mean(Y)
for i in range(Y.size):
Q_e += pow(np.array((Y.T)[i] - X[i] * B), 2)
Q_E += pow(np.array(X[i] * B) - Y_mean, 2)
R2 = Q_E / (Q_e + Q_E)
print("R2", R2)
但是上述公式成立的条件为 x_train
为列满秩矩阵,因此上述代码具有一定的局限性。
最好使用公式:
B
=
x
t
r
a
i
n
+
B = x_{train}^+
B=xtrain+
进行求最小二乘解,其中加号广义逆可以通过 奇异值分解 或者 满秩分解 得到。
- 利用加号广义逆(Moore-Penrose)代码更新如下:
# 利用加号广义逆(Moore-Penrose)
B = np.linalg.pinv(x_train)