📜  多项式回归(使用Python从头开始)(1)

📅  最后修改于: 2023-12-03 15:23:43.635000             🧑  作者: Mango

多项式回归(使用Python从头开始)

多项式回归是线性回归的一种扩展形式,它的基本思想是在线性回归的基础上,增加特征的次数,从而得到更适合复杂非线性数据的回归拟合模型。

实现过程
步骤一:导入相关库

我们需要使用numpy库来处理数据、matplotlib库来可视化数据。

import numpy as np
import matplotlib.pyplot as plt
步骤二:准备数据

我们以一个简单的例子来说明多项式回归。我们生成一组正弦曲线上的点并加入一些噪声。

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x) + 0.2*np.random.randn(len(x))

随机生成一些噪声使得数据更加真实。

步骤三:特征变换

我们先来回顾线性回归的形式:

$y = w_1x_1 + w_2x_2 + ... + w_nx_n + b$

线性回归的特征就是$x_1, x_2, ..., x_n$,而多项式回归的特征是$x_1, x_2^2, ..., x_n^m$,其中$m$为特征次数。

我们定义一个函数来进行特征变换,将特征从线性变成多项式形式。

def poly_features(x, degree):
    X_poly = np.zeros((len(x), degree))
    for i in range(degree):
        X_poly[:, i] = np.power(x, i+1)
    return X_poly

该函数接受两个参数,一个是特征向量$x$,另一个是特征次数$degree$。该函数返回特征向量转换后的结果$X_{poly}$。

步骤四:模型训练

多项式回归的模型形式为:

$y = w_0 + w_1x + w_2x^2 + ... + w_mx^m$

我们使用最小二乘法来训练模型。最小二乘法是一种经典的回归分析方法,它通过最小化实际值与预测值之间的差异来拟合出一个最优的模型。具体而言,我们需要求解以下方程组:

$X^TXw = X^Ty$

其中$X$为特征向量,$y$为目标向量,$w$为模型参数。

我们定义一个函数来求解模型参数。

def train_poly_model(X, y, degree):
    X_poly = poly_features(X, degree)
    w = np.linalg.inv(X_poly.T.dot(X_poly)).dot(X_poly.T).dot(y)
    return w

该函数接受三个参数,分别是特征向量$X$、目标向量$y$和特征次数$degree$。该函数返回一个向量$w$,表示模型的参数。

步骤五:模型预测

我们定义一个函数来进行模型预测。

def poly_predict(X, w, degree):
    X_poly = poly_features(X, degree)
    y_pred = X_poly.dot(w)
    return y_pred

该函数接受三个参数,分别是特征向量$X$、模型参数向量$w$和特征次数$degree$。该函数返回预测结果$y_{pred}$。

步骤六:模型评估

为了评估多项式回归模型的性能,我们可以使用均方误差(MSE)来衡量预测值与实际值之间的偏差程度。

def mse(y_true, y_pred):
    return np.mean((y_true - y_pred)**2)

该函数接受两个参数,分别是实际值$y_{true}$和预测值$y_{pred}$。该函数返回均方误差。

完整代码
import numpy as np
import matplotlib.pyplot as plt

def poly_features(x, degree):
    X_poly = np.zeros((len(x), degree))
    for i in range(degree):
        X_poly[:, i] = np.power(x, i+1)
    return X_poly

def train_poly_model(X, y, degree):
    X_poly = poly_features(X, degree)
    w = np.linalg.inv(X_poly.T.dot(X_poly)).dot(X_poly.T).dot(y)
    return w

def poly_predict(X, w, degree):
    X_poly = poly_features(X, degree)
    y_pred = X_poly.dot(w)
    return y_pred

def mse(y_true, y_pred):
    return np.mean((y_true - y_pred)**2)

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x) + 0.2*np.random.randn(len(x))

degree = 3
w = train_poly_model(x, y, degree)
y_pred = poly_predict(x, w, degree)

plt.scatter(x, y, label='data')
plt.plot(x, y_pred, color='r', label='poly fit')
plt.legend()
plt.show()

print('Degree:', degree)
print('MSE:', mse(y, y_pred))
结果分析

我们可以通过调整特征次数$degree$来观察拟合效果。下面展示了当特征次数分别为1、3和10时的拟合结果和均方误差。

特征次数为1时:

degree_1

Degree: 1 MSE: 0.14648466838166794

特征次数为3时:

degree_3

Degree: 3 MSE: 0.040013819708189186

特征次数为10时:

degree_10

Degree: 10 MSE: 0.011615392538950653

我们发现,当特征次数为1时,模型的拟合效果不太好,误差较大。当特征次数增加到3时,拟合效果明显提升,误差也减小了。当特征次数增加到10时,拟合效果已经非常好,误差也更小了。但是,特征次数过大会导致过拟合的问题,需要注意。