Python 确定多项式拟合/回归的阶数

本文探讨了如何使用多项式回归分析预测数据,通过调整多项式的最高阶数,寻找最佳拟合模型。利用Python的scikit-learn库进行数据分析,比较不同阶数下的均方根误差(RMSE)和R²评分,确定最优模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过 1至10 阶来拟合对比 均方误差及R评分,可以确定最优的“最大阶数”。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression,Perceptron
from sklearn.metrics import mean_squared_error,r2_score
from sklearn.model_selection import train_test_split

X = np.array([-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10]).reshape(-1, 1)
y = np.array(2*(X**4) + X**2 + 9*X + 2)
#y = np.array([300,500,0,-10,0,20,200,300,1000,800,4000,5000,10000,9000,22000]).reshape(-1, 1)

x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
rmses = []
degrees = np.arange(1, 10)
min_rmse, min_deg,score = 1e10, 0 ,0

for deg in degrees:
    # 生成多项式特征集(如根据degree=3 ,生成 [[x,x**2,x**3]] )
    poly = PolynomialFeatures(degree=deg, include_bias=False)
    x_train_poly = poly.fit_transform(x_train)

    # 多项式拟合
    poly_reg = LinearRegression()
    poly_reg.fit(x_train_poly, y_train)
    #print(poly_reg.coef_,poly_reg.intercept_) #系数及常数
    
    # 测试集比较
    x_test_poly = poly.fit_transform(x_test)
    y_test_pred = poly_reg.predict(x_test_poly)
    
    #mean_squared_error(y_true, y_pred) #均方误差回归损失,越小越好。
    poly_rmse = np.sqrt(mean_squared_error(y_test, y_test_pred))
    rmses.append(poly_rmse)
    # r2 范围[0,1],R2越接近1拟合越好。
    r2score = r2_score(y_test, y_test_pred)
    
    # degree交叉验证
    if min_rmse > poly_rmse:
        min_rmse = poly_rmse
        min_deg = deg
        score = r2score
    print('degree = %s, RMSE = %.2f ,r2_score = %.2f' % (deg, poly_rmse,r2score))
        
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(degrees, rmses)
ax.set_yscale('log')
ax.set_xlabel('Degree')
ax.set_ylabel('RMSE')
ax.set_title('Best degree = %s, RMSE = %.2f, r2_score = %.2f' %(min_deg, min_rmse,score))  
plt.show()

 

因为因变量 Y = 2*(X**4) + X**2 + 9*X + 2 ,自变量和因变量是完整的公式,看图很明显,degree >=4 的都符合,拟合函数都正确。(RMSE 最小,R平方非负且接近于1,则模型最好)

如果将 Y 值改为如下:

y = np.array([300,500,0,-10,0,20,200,300,1000,800,4000,5000,10000,9000,22000]).reshape(-1, 1)

degree=3 是最好的,且 r 平方也最接近于1(注意:如果 R 平方为负数,则不准确,需再次测试。因样本数据较少,可能也会判断错误)。

 

### Python 中的自适应多项式拟合实现 #### 方法概述 在 Python 中,可以通过多种方式实现自适应多项式拟合。这通常涉及动态调整多项式阶数或其他参数以更好地匹配数据特征。下面介绍两种常见的方法:一是基于 NumPy 和 SciPy 的手动实现;二是借助现有的机器学习工具包(如 Scikit-Learn)进行更复杂的建模。 --- #### 手动实现自适应多项式拟合 以下是一个简单的例子,展示如何使用 NumPy 动态调整多项式阶数来进行拟合: ```python import numpy as np import matplotlib.pyplot as plt def adaptive_poly_fit(x, y, max_degree=10, threshold=1e-3): """ 自适应多项式拟合函数 :param x: 输入数据点 (numpy array) :param y: 输出数据点 (numpy array) :param max_degree: 最大允许的多项式阶数 :param threshold: 改善阈值,当误差改进小于该值时停止增加阶数 :return: 拟合后的多项式系数和使用的阶数 """ best_coeffs = None min_error = float('inf') current_degree = 1 while current_degree <= max_degree: coeffs = np.polyfit(x, y, deg=current_degree) # 使用当前阶数拟合 poly_func = np.poly1d(coeffs) # 创建多项式对象 residuals = y - poly_func(x) # 计算残差 error = np.sum(residuals ** 2) # 平方误差 if error < min_error - threshold: # 如果有显著改进,则更新最优解 min_error = error best_coeffs = coeffs else: break # 否则终止迭代 current_degree += 1 # 增加阶数继续尝试 return best_coeffs, current_degree - 1 # 返回最佳系数和对应的阶数 # 测试数据 rng = np.random.default_rng(seed=42) x = np.linspace(0, 10, 100) y_true = 2 * x**3 - 5 * x**2 + 3 * x - 7 # 真实模型 noise = rng.normal(scale=10, size=x.shape) # 添加噪声 y_noisy = y_true + noise coefficients, degree_used = adaptive_poly_fit(x, y_noisy) print(f"Best Polynomial Degree Used: {degree_used}") print(f"Coefficients: {coefficients}") poly_function = np.poly1d(coefficients) plt.figure(figsize=(8, 6)) plt.scatter(x, y_noisy, label="Noisy Data", color='blue', s=10) plt.plot(x, poly_function(x), label=f"Fitted Poly ({degree_used}th)", color='red') plt.legend() plt.show() ``` 上述代码实现了自适应多项式拟合的功能[^1]。它会逐步增加多项式阶数直到满足特定条件为止,并返回最适合的数据表示形式及其对应阶数。 --- #### 利用 Scikit-Learn 进行高级拟合 Scikit-Learn 提供了强大的管道功能,可以轻松集成多项式特征扩展与回归分析。这里给出一个示例: ```python from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import Ridge from sklearn.pipeline import make_pipeline from sklearn.metrics import mean_squared_error def sk_adaptive_poly_fit(x, y, degrees_range=[1, 2, 3, 4, 5]): """ 使用 Scikit-Learn 实现自适应多项式拟合 :param x: 输入数据点 (numpy array 或 list) :param y: 输出数据点 (numpy array 或 list) :param degrees_range: 考虑的多项式阶数组成的列表 :return: 最优模型及对应的阶数 """ x = np.array(x).reshape(-1, 1) # 将输入转换为二维列向量 y = np.array(y) best_model = None min_mse = float('inf') optimal_degree = None for d in degrees_range: model = make_pipeline(PolynomialFeatures(degree=d), Ridge(alpha=1)) # 构造带正则化的多项式回归模型 model.fit(x, y) predictions = model.predict(x) mse = mean_squared_error(y, predictions) if mse < min_mse: min_mse = mse best_model = model optimal_degree = d return best_model, optimal_degree model, opt_deg = sk_adaptive_poly_fit(x, y_noisy, degrees_range=[1, 2, 3, 4]) predictions = model.predict(np.array(x).reshape(-1, 1)) plt.figure(figsize=(8, 6)) plt.scatter(x, y_noisy, label="Data Points", color='green', s=10) plt.plot(x, predictions, label=f"SkLearn Fit (Degree={opt_deg})", color='purple') plt.legend() plt.show() ``` 这段代码展示了如何通过遍历可能的多项式阶数范围找到最适配的一个,并应用岭回归减少过拟合风险[^3]。 --- #### 工具库推荐 除了自己编写外,还可以考虑一些专门针对信号处理或优化问题开发的第三方库: - **NumPy & SciPy**: 提供基础支持。 - **SymPy**: 符号计算有助于解析表达式生成。 - **TensorFlow/Keras**: 对于更高维度非线性映射特别有用。 - **PolyFitting**: 是一个小众但专注于高效多项式操作的小型开源项目[^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值