Python 多项式拟合
文章目录
- Python 多项式拟合
- 一、Numpy 实现
- 二、Torch 实现
- 三、拟合程度
- 3.1 展示
- 3.2 过拟合
- 3.3 欠拟合
Python 多项式拟合
一、Numpy 实现
多项式拟合原理:Python最小二乘法
这里使用第三方库来实现多项式拟合,而不是使用原始的方法:
numpy 库实现:
import numpy as np
import matplotlib.pyplot as plt
# 生成原始数据
# 生成 20 个在 [0, 1) 之间的随机数作为输入特征
x = np.sort(np.random.rand(100))
# 根据正弦函数生成对应的目标值,并添加噪声
y = np.sin(2 * np.pi * x) + 0.3 * np.random.randn(100)
p_is1 = np.poly1d(np.polyfit(x, y, 3)) # 拟合曲线
x_plot = np.linspace(0, 1, 100)
plt.scatter(x, y, label='Training data', color='blue')
plt.plot(x_plot, p_is1(x_plot), label="predict data")
plt.title('fitting curve')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
二、Torch 实现
import torch
import torch.nn as nn
from torch.utils.data import TensorDataset, DataLoader
# 1. 准备数据
# 生成一些示例数据
n_samples = 100
x1 = torch.randn(n_samples, 1)
x2 = torch.randn(n_samples, 1)
# 真实的权重和偏置
true_w1 = 2.0
true_w2 = 3.0
true_b = 1.0
# 生成标签
y = true_w1 * x1 + true_w2 * x2 + true_b + 0.1 * torch.randn(n_samples, 1)
# 合并特征
X = torch.cat((x1, x2), dim=1)
# 创建数据集和数据加载器
dataset = TensorDataset(X, y)
batch_size = 10
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
# 2. 定义模型
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(2, 1) # 输入维度为 2,输出维度为 1
def forward(self, x):
return self.linear(x)
model = LinearRegression()
# 3. 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 4. 训练模型
num_epochs = 100
for epoch in range(num_epochs):
for inputs, labels in dataloader:
# 前向传播
outputs = model(inputs)
loss = criterion(outputs, labels)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
# 输出最终的权重和偏置
print("Final weights:", model.linear.weight.tolist())
print("Final bias:", model.linear.bias.item())
三、拟合程度
3.1 展示
代码:
import numpy as np
import matplotlib.pyplot as plt
# 生成原始数据
# 生成 20 个在 [0, 1) 之间的随机数作为输入特征
x = np.sort(np.random.rand(100))
# 根据正弦函数生成对应的目标值,并添加噪声
y = np.sin(2 * np.pi * x) + 0.3 * np.random.randn(100)
p_over = np.poly1d(np.polyfit(x, y, 15)) # 过饱和曲线
p_under = np.poly1d(np.polyfit(x, y, 1)) # 过饱和曲线
p_is1 = np.poly1d(np.polyfit(x, y, 3)) # 拟合曲线
p_is2 = np.poly1d(np.polyfit(x, y, 4)) # 拟合曲线
# 绘制结果`
plt.figure(figsize=(12, 6))
x_plot = np.linspace(0, 1, 100)
# 绘制训练集数据和拟合曲线
plt.subplot(2, 2, 1)
plt.scatter(x, y, label='Training data', color='blue')
plt.plot(x_plot, p_over(x_plot), label="predict data")
plt.title('1. Supersaturation fitting curve')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
# 绘制测试集数据和拟合曲线
plt.subplot(2, 2, 2)
plt.scatter(x, y, label='Training data', color='green')
plt.plot(x_plot, p_under(x_plot), label="predict data")
plt.title('2. Undersaturated fitting curve')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
# 绘制测试集数据和拟合曲线
plt.subplot(2, 2, 3)
plt.scatter(x, y, label='Training data', color='green')
plt.plot(x_plot, p_is1(x_plot), label="predict data")
plt.title('3. Three order fitting curve')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
# 绘制测试集数据和拟合曲线
plt.subplot(2, 2, 4)
plt.scatter(x, y, label='Training data', color='green')
plt.plot(x_plot, p_is2(x_plot), label="predict data")
plt.title('4. Four order fitting curve')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.tight_layout()
plt.show()
- 图一为过拟合图像
- 图二为欠拟合图像
3.2 过拟合
过拟合是指模型在训练数据上表现得非常好,能够很好地拟合训练数据中的模式和细节,但在新的、未见过的数据(测试数据)上表现却很差,泛化能力弱的现象。简单来说,就是模型过度学习了训练数据中的噪声和特殊情况,而没有真正捕捉到数据背后的一般规律,从而导致在面对新数据时无法准确预测或分类。
解决方法:
- 增加训练数据:获取更多的数据进行训练,使模型能够学习到更多的样本特征,减少对训练数据中噪声和特殊情况的依赖,提高模型的泛化能力。
- 降低模型复杂度:可以采用简化模型结构的方法,如减少神经网络的层数或神经元数量、限制决策树的深度等。也可以使用正则化方法,如 L1 和 L2 正则化,通过在损失函数中添加惩罚项来限制模型参数的大小,防止模型过度拟合。
- 采用早停法:在训练过程中,监控模型在验证集上的性能,当验证集上的性能不再提升甚至开始下降时,停止训练,避免模型过度拟合训练数据。
- 使用集成学习:将多个不同的模型进行组合,如随机森林、梯度提升树等集成算法,通过综合多个模型的预测结果来降低过拟合的风险,提高模型的稳定性和泛化能力。
3.3 欠拟合
欠拟合是指模型在训练数据和新数据上的表现都很差,无法很好地捕捉数据中的规律,导致模型的预测能力和泛化能力都不足。简单来说,就是模型还没有充分学习到数据中的特征和关系,对数据的拟合程度过低,不能很好地对数据进行建模和预测。
解决方法:
- 增加模型复杂度:选择更复杂的模型结构,如使用多层神经网络代替单层神经网络,增加决策树的深度或节点数量等,以提高模型的表达能力,使其能够更好地拟合数据中的复杂关系。
- 特征工程:对数据进行更深入的特征提取和选择,挖掘更多有价值的特征,或者对现有特征进行组合、变换等操作,让模型有更多的信息可以学习。例如对文本数据进行词向量表示、对图像数据提取更多的特征描述子等。
- 提高数据质量:对训练数据进行清洗,去除噪声和异常值,对缺失值进行处理,确保数据的准确性和完整性,为模型提供更好的学习样本。
- 增加训练时间和数据量:适当延长模型的训练时间,让模型有足够的时间进行学习和收敛。同时,增加训练数据的数量,使模型能够学习到更多的数据特征和规律,提高模型的泛化能力。