Topic
- 实现二次多项式拟合
- 实现多次多项式拟合
- 使用 scikit-learn 进行多项式拟合
本篇是多项式回归代码实践篇,理论篇:多项式回归理论
matplotlib
图像显示数据集点分布情况scipy
提供的最小二乘法类,得到最佳拟合参数# 1. 定义数据集
x = [4, 8, 12, 25, 32, 43, 58, 63, 69, 79]
y = [20, 33, 50, 56, 42, 31, 33, 46, 65, 75]
# 2. 使用Matplotlib 绘制数据
from matplotlib import pyplot as plt
plt.scatter(x, y)
plt.show()
# 3. 实现 2 次多项式函数及误差函数
def func(p, x1):
w0, w1, w2 = p
f = w0 + w1*x1 + w2*x1*x1
return f
def err_func(p, x1, y1):
ret = func(p, x1) - y1
return ret
# 4. 生成随机数
import numpy as np
# 生成 3 个随机数
p_init = np.random.randn(3)
p_init
# 5. 使用 Scipy 提供的最小二乘法哈数得到最佳拟合参数
from scipy.optimize import leastsq
parameters = leastsq(err_func, p_init, args=(np.array(x), np.array(y)))
print('Fitting Parameters: ', parameters[0])
## 6. 绘制拟合后的图像
# 绘制拟合图像时需要的临时点
x_temp = np.linspace(0, 80, 10000)
# 绘制拟合函数曲线
plt.plot(x_temp, func(parameters[0], x_temp), 'r')
# 绘制原数据点
plt.scatter(x, y)
# 1. 定义数据集
x = [4, 8, 12, 25, 32, 43, 58, 63, 69, 79]
y = [20, 33, 50, 56, 42, 31, 33, 46, 65, 75]
# 2. 实现 n 次多项式拟合
import numpy as np
from scipy.optimize import leastsq
from matplotlib import pyplot as plt
# 根据公式,定义 n 次多项式函数
def fit_func(p, x):
f = np.poly1d(p)
return f(x)
# 残差函数(观测值与拟合值之间的差距)
def err_func(p, x, y):
ret = fit_func(p, x) - y
return ret
# n 次多项式拟合
def n_poly(n):
p_init = np.random.randn(n) # 生成 n 个随机数
parameters = leastsq(err_func, p_init, args=(np.array(x), np.array(y)))
return parameters[0]
n_poly(3)
# 3. 绘制出 4,5,6,7, 8, 9 次多项式的拟合图像
# 绘制拟合图像时需要的临时点
x_temp = np.linspace(0, 80, 10000)
# 绘制子图
fig, axes = plt.subplots(2, 3, figsize=(15,10))
axes[0,0].plot(x_temp, fit_func(n_poly(4), x_temp), 'r')
axes[0,0].scatter(x, y)
axes[0,0].set_title("m = 4")
axes[0,1].plot(x_temp, fit_func(n_poly(5), x_temp), 'r')
axes[0,1].scatter(x, y)
axes[0,1].set_title("m = 5")
axes[0,2].plot(x_temp, fit_func(n_poly(6), x_temp), 'r')
axes[0,2].scatter(x, y)
axes[0,2].set_title("m = 6")
axes[1,0].plot(x_temp, fit_func(n_poly(7), x_temp), 'r')
axes[1,0].scatter(x, y)
axes[1,0].set_title("m = 7")
axes[1,1].plot(x_temp, fit_func(n_poly(8), x_temp), 'r')
axes[1,1].scatter(x, y)
axes[1,1].set_title("m = 8")
axes[1,2].plot(x_temp, fit_func(n_poly(9), x_temp), 'r')
axes[1,2].scatter(x, y)
axes[1,2].set_title("m = 9")
scikit-learn 采用 最小二乘法矩阵求解
通过PolynomialFeatures()
类自动产生多项式特征矩阵
sklearn.preprocessing.PolynomialFeatures(degree=2, interaction_only=False, include_bias=True)
degree
: 多项式次数,默认为 2 次多项式interaction_only
: 默认为 False,如果为 True 则产生相互影响的特征集。include_bias
: 默认为 True,包含多项式中的截距项。# 1. 使用 PolynomialFeatures 自动生成特征矩阵
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
X = [2, -1, 3]
X_reshape = np.array(X).reshape(len(X), 1) # 转换为列向量
PolynomialFeatures(degree=2, include_bias=False).fit_transform(X_reshape)
# 2. 使用 sklearn 得到 2 次多项式回归特征矩阵
x = [4, 8, 12, 25, 32, 43, 58, 63, 69, 79]
y = [20, 33, 50, 56, 42, 31, 33, 46, 65, 75]
x = np.array(x).reshape(len(x), 1) # 转换为列向量
y = np.array(y).reshape(len(y), 1)
poly_features = PolynomialFeatures(degree=2, include_bias=False)
poly_x = poly_features.fit_transform(x)
poly_x
# 3. 转换为线性回归预测
from sklearn.linear_model import LinearRegression
# 定义线性回归模型
model = LinearRegression()
model.fit(poly_x, y) # 训练
# 得到模型拟合参数
model.intercept_, model.coef_
# 4. 绘制拟合图像
from matplotlib import pyplot as plt
# 绘制拟合图像时需要的临时点
x_temp = np.linspace(0, 80, 10000)
x_temp = np.array(x_temp).reshape(len(x_temp),1)
poly_x_temp = poly_features.fit_transform(x_temp)
plt.plot(x_temp, model.predict(poly_x_temp), 'r')
plt.scatter(x, y)