机器学习06:多项式回归及python实现
多项式回归
多项式回归的假设函数:
hθ(x)=θ0+θ1x1+θ2x2+ ⋅⋅⋅ +θdxd=θ0+θ1x+θ2x2+ ⋅⋅⋅ +θdxd
\begin{aligned}
h_\theta(\pmb{x})&=\theta_0+\theta_1x_1+\theta_2x_2+\,···\,+\theta_dx_d\\&=\theta_0+\theta_1x+\theta_2x^2+\,···\,+\theta_dx^d
\end{aligned}
hθ(xxx)=θ0+θ1x1+θ2x2+⋅⋅⋅+θdxd=θ0+θ1x+θ2x2+⋅⋅⋅+θdxd
之前我一直有一个疑惑,多项式回归是不是线性回归?
在这里,如果我们把hθ(x)h_\theta(\pmb{x})hθ(xxx)看作x\pmb{x}xxx的函数,这个方程就是非线性的,当然不是线性回归,可是在多项式回归中,我们要确定的是θ\pmb{\theta}θθθ的取值,xxx的多次幂可以当作一个新的特征值,hθ(x)h_\theta(\pmb{x})hθ(xxx)是θ\pmb{\theta}θθθ的函数,可以理解为上面方程中的第一行。所以,多项式回归也是线性回归。因此,线性回归的相关算法也适用于多项式回归。
Python 实现
下面我们直接用python来实现一个例子:
- 引入需要用到的模块
## 导入模块
import numpy as np
import matplotlib.pyplot as plt
- 创造实验数据
这里使用函数 f(x)=(x+5)2+随机噪声f(x)=(x+5)^2+随机噪声f(x)=(x+5)2+随机噪声 来创造实验数据,选取15个样本点。
## 创造实验数据
x0 = np.arange(1,16).reshape(-1,1) # 这里我们选取15个点,将数组转换为列向量
## 使用 y = (x-5)^2 = x^2+10*x+25, 作为模型函数并添加噪声
y0 = ((x0-52.)**2 + np.random.uniform(0,10,size=(len(x0),1))).reshape(-1,1)
- 构造特点矩阵
对于这个示例,该特点矩阵一共有三列,第一列为全为 111,第二列为向量x\pmb{x}xxx,第三列为向量x**2
.
## 构造特性矩阵
'''
该特性矩阵一共有三列,第一列为全为1,第二列为向量x,第三列为向量x^2
'''
first = np.ones((len(x0))).reshape(-1,1)
second = x0
third = x0**2
X = np.concatenate((first, second, third), axis=1)
- 求解
这里我们运用正规方程求解。
利用公式:
θ=(XTX)XTy \pmb{\theta}=(\pmb{X^TX})\pmb{X^Ty} θθθ=(XTXXTXXTX)XTyXTyXTy
求解系数
X_T = X.transpose()
beta = np.linalg.inv(X_T.dot(X)).dot(X_T).dot(y0)
- 画图
fig = plt.figure()
sub = plt.subplot(111)
sub.scatter(x0, y0)
sub.plot(x0, yi)
plt.show()
附:源代码
'''
Description:
Author: Weijian Ma
Date: 2020-09-21 20:20:34
LastEditTime: 2020-09-21 21:01:42
LastEditors: Weijian Ma
'''
'''
多项式回归实现
'''
## 导入模块
import numpy as np
import matplotlib.pyplot as plt
## 创造实验数据
x0 = np.arange(1,16).reshape(-1,1) # 这里我们选取15个点,将数组转换为列向量
## 使用 y = (x-5)^2 = x^2+10*x+25, 作为模型函数并添加噪声
y0 = ((x0-5)**2 + np.random.uniform(0,10,size=(len(x0),1))).reshape(-1,1)
## 构造特性矩阵
'''
该特性矩阵一共有三列,第一列为全为1,第二列为向量x,第三列为向量x^2
'''
first = np.ones((len(x0))).reshape(-1,1)
second = x0
third = x0**2
X = np.concatenate((first, second, third), axis=1)
X_T = X.transpose()
beta = np.linalg.inv(X_T.dot(X)).dot(X_T).dot(y0)
print("系数矩阵:\n{0}".format(beta))
yi = beta[0]+beta[1]*x0+beta[2]*(x0**2)
fig = plt.figure()
sub = plt.subplot(111)
sub.scatter(x0, y0)
sub.plot(x0, yi)
plt.show()
结果如下(每次运行的结果可能不一样,因为噪声是随机的):
系数矩阵:
[[25.88223989]
[-8.81802872]
[ 0.93633153]]