Python数据拟合实战:线性、多项式与对数模型全解析
1. 项目概述从数据点到趋势线的实战旅程在数据分析、机器学习乃至工程应用的日常里我们常常面对一堆看似杂乱的数据点。这些点背后隐藏着怎样的规律是简单的直线关系还是更复杂的曲线今天我们不谈高深的理论就聊聊怎么用Python这把“瑞士军刀”把手头的数据点变成一条条有意义的趋势线——也就是拟合。无论是简单的线性关系还是需要弯折几次的多项式甚至是增长迅猛的对数曲线Python都能帮你轻松搞定。这篇文章就是一份面向实践者的“操作手册”我会结合自己处理传感器数据、用户增长分析等实际项目的经验带你一步步走通线性拟合、多项式拟合和对数拟合的全过程重点不是推导公式而是怎么写代码、怎么调参数、怎么避开那些新手常踩的坑。2. 环境准备与核心工具库工欲善其事必先利其器。用Python做科学计算和拟合离不开几个核心库。别被吓到它们的安装和使用比想象中简单得多。2.1 必备库的安装与验证首先确保你的Python环境已经就绪。我强烈建议使用Anaconda来管理环境它能避免很多依赖冲突的麻烦。如果你习惯用pip也完全没问题。打开你的终端Windows上是CMD或PowerShellmacOS/Linux上是Terminal依次执行以下命令来安装我们需要的库pip install numpy matplotlib scipy scikit-learn简单解释一下这几个库的分工NumPy它是整个科学计算生态的基石提供了强大的多维数组对象和数学函数。我们的数据点通常就用NumPy数组来存储和操作。Matplotlib绘图神器。拟合结果好不好画出来一看便知。它负责将数据和拟合曲线可视化。SciPy一个专注于科学计算的库它提供了scipy.optimize.curve_fit这个强大的函数是我们进行非线性拟合比如对数拟合的主力工具。scikit-learn虽然以机器学习库闻名但其linear_model模块中的LinearRegression提供了非常清晰、功能丰富的线性回归接口适合需要更严谨统计信息如R²分数的场景。安装完成后可以在Python交互环境或一个脚本的开头导入它们验证是否成功import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit from sklearn.linear_model import LinearRegression from sklearn.metrics import r2_score print(所有库导入成功)注意如果遇到安装超时或速度慢的问题可以使用国内的镜像源例如清华源pip install numpy matplotlib scipy scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple。另外确保你的pip版本是最新的pip install --upgrade pip这能减少很多奇怪的问题。2.2 数据准备与生成模拟数据在实际项目中数据可能来自CSV文件、数据库或者API。为了演示的通用性我们先学习如何生成一份可控的模拟数据这样你能清楚地知道“标准答案”便于理解拟合的效果。假设我们要研究一个物理实验中弹簧伸长量x与所受拉力y的关系。根据胡克定律在弹性限度内这应该是一个线性关系但测量总会引入一些随机误差。# 生成模拟数据线性关系 随机噪声 np.random.seed(42) # 设置随机种子确保每次运行生成的数据一致 x np.linspace(0, 10, 50) # 在0到10之间生成50个均匀分布的点作为自变量 k_true 2.5 # 真实的斜率 b_true 1.0 # 真实的截距 noise np.random.randn(50) * 2 # 生成均值为0标准差为2的正态分布噪声 y k_true * x b_true noise # 带噪声的因变量 # 可视化原始数据 plt.figure(figsize(10, 6)) plt.scatter(x, y, alpha0.6, label原始数据点 (带噪声)) plt.plot(x, k_true * x b_true, r--, label真实的理论关系, linewidth2) plt.xlabel(自变量 X (例如伸长量)) plt.ylabel(因变量 Y (例如拉力)) plt.title(模拟数据与真实关系) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.show()这段代码会生成一张散点图红色的虚线是隐藏的“真实”线性关系蓝色的点是我们在实验中可能测到的、带有随机误差的数据。我们接下来的所有拟合工作目标就是从这些蓝色的散点中尽可能准确地还原出那条红色的线。3. 线性拟合抓住最直接的关联线性拟合也叫线性回归是寻找一条直线y k*x b使得所有数据点到这条直线的垂直距离残差的平方和最小。这就是经典的最小二乘法。3.1 使用NumPy进行快速拟合对于简单的线性拟合NumPy的polyfit函数是最快捷的选择。它虽然叫“poly”多项式但指定阶数为1时就是线性拟合。# 使用 numpy.polyfit 进行一阶线性拟合 coefficients np.polyfit(x, y, 1) # 参数x数据 y数据 多项式阶数1代表线性 k_fit_np, b_fit_np coefficients # 解包出斜率和截距 print(fNumPy 拟合结果斜率 k {k_fit_np:.4f}, 截距 b {b_fit_np:.4f}) print(f真实参数斜率 k {k_true:.4f}, 截距 b {b_true:.4f}) # 用拟合出的参数生成拟合直线上的点 y_fit_np k_fit_np * x b_fit_np # 计算R平方值决定系数评估拟合优度 residuals y - y_fit_np ss_res np.sum(residuals**2) # 残差平方和 ss_tot np.sum((y - np.mean(y))**2) # 总平方和 r_squared_np 1 - (ss_res / ss_tot) print(f拟合优度 R² {r_squared_np:.4f})np.polyfit直接返回了多项式的系数对于一阶就是[k, b]。R²越接近1说明直线对数据的解释能力越强。这里我们的数据就是根据线性关系生成的所以R²通常会很高比如0.95以上。3.2 使用scikit-learn进行标准化建模scikit-learn的接口更接近机器学习的工作流适合更复杂的回归任务比如多元线性回归。它的优势在于提供了统一的fit、predict接口和丰富的模型评估工具。# 使用 scikit-learn 的 LinearRegression # 注意sklearn 通常要求特征 X 是二维数组即使只有一维特征 X_sklearn x.reshape(-1, 1) model_lr LinearRegression() model_lr.fit(X_sklearn, y) # 训练模型 k_fit_sk model_lr.coef_[0] # 斜率 b_fit_sk model_lr.intercept_ # 截距 y_pred_sk model_lr.predict(X_sklearn) # 预测值 print(f\nscikit-learn 拟合结果斜率 k {k_fit_sk:.4f}, 截距 b {b_fit_sk:.4f}) print(f模型评分 R² {model_lr.score(X_sklearn, y):.4f}) # 可视化对比 plt.figure(figsize(10, 6)) plt.scatter(x, y, alpha0.6, label原始数据) plt.plot(x, y_fit_np, g-, labelfNumPy 拟合 (R²{r_squared_np:.3f}), linewidth2) plt.plot(x, y_pred_sk, r--, labelfsklearn 拟合 (R²{model_lr.score(X_sklearn, y):.3f}), linewidth2, alpha0.8) plt.plot(x, k_true * x b_true, k:, label真实关系, linewidth2) plt.xlabel(X) plt.ylabel(Y) plt.title(线性拟合方法对比) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.show()你会看到两种方法得到的直线几乎重合并且都紧密围绕在真实关系线周围。scikit-learn的.score()方法默认返回的就是R²分数非常方便。实操心得对于简单的一元线性拟合np.polyfit足够快且代码简洁。但如果你的项目未来可能扩展到多元回归多个x预测一个y或者需要集成到更大的机器学习流水线中从一开始就使用scikit-learn的LinearRegression会是更规范、更具扩展性的选择。它还能方便地输出模型的统计显著性信息需结合statsmodels库。4. 多项式拟合应对更复杂的曲线关系当数据点呈现明显的曲线趋势时线性模型就力不从心了。这时多项式拟合就该登场了。它的形式是y a_n * x^n ... a_1 * x a_0。4.1 理解多项式阶数的选择阶数n是多项式拟合中最关键的参数。阶数太低模型欠拟合无法捕捉数据的弯曲阶数太高模型过拟合会疯狂追逐每一个数据点包括噪声导致在新数据上表现极差。我们生成一组具有二次方抛物线趋势的数据来演示# 生成模拟数据二次关系 噪声 np.random.seed(123) x_poly np.linspace(-3, 3, 30) a_true, b_true, c_true 0.5, -1, 2 # 真实参数y 0.5*x^2 -1*x 2 y_poly a_true * x_poly**2 b_true * x_poly c_true np.random.randn(30) * 0.5 plt.scatter(x_poly, y_poly, label数据点) plt.plot(x_poly, a_true*x_poly**2 b_true*x_poly c_true, k--, label真实二次曲线, alpha0.7) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.title(二次关系模拟数据) plt.show()4.2 使用np.polyfit进行多项式拟合np.polyfit同样可以处理多项式拟合只需改变阶数参数deg。# 尝试用不同阶数进行拟合 degrees [1, 2, 5, 10] # 分别尝试1阶线性2阶二次5阶10阶 colors [green, red, blue, orange] x_plot np.linspace(x_poly.min(), x_poly.max(), 300) # 用于绘制平滑曲线的密集点 plt.figure(figsize(12, 8)) plt.scatter(x_poly, y_poly, s50, label数据点, zorder5) for deg, color in zip(degrees, colors): # 拟合 coeffs np.polyfit(x_poly, y_poly, deg) # 生成多项式函数并计算y值 p np.poly1d(coeffs) # np.poly1d 用系数创建一个多项式函数对象 y_plot p(x_plot) # 计算训练数据上的R² y_pred p(x_poly) r2 r2_score(y_poly, y_pred) plt.plot(x_plot, y_plot, colorcolor, linewidth2, labelf{deg}阶拟合 (R²{r2:.4f}), alpha0.8) plt.plot(x_plot, a_true*x_plot**2 b_true*x_plot c_true, k:, linewidth3, label真实关系) plt.legend() plt.xlabel(X) plt.ylabel(Y) plt.title(不同阶数多项式拟合对比警惕过拟合) plt.grid(True, linestyle--, alpha0.5) plt.ylim(y_poly.min()-1, y_poly.max()1) plt.show()从图中你可以清晰地看到1阶绿色一条直线明显欠拟合无法描述数据的弯曲。2阶红色一条抛物线与真实的黑色虚线几乎重合拟合效果很好R²也很高。5阶蓝色曲线开始出现不必要的波动虽然训练数据上的R²可能更高但已经开始学习噪声。10阶橙色曲线剧烈震荡穿过了几乎所有数据点这是典型的过拟合。它在训练集上表现“完美”但毫无预测能力。核心技巧如何选择阶数没有绝对标准但可以遵循以下步骤1)可视化先画散点图观察趋势。2)从低阶开始先尝试2阶或3阶。3)看指标关注R²但更要关注其在验证集或测试集上的表现交叉验证。4)奥卡姆剃刀原则在拟合效果相近时优先选择更简单的模型阶数更低。对于本例2阶就是最佳选择。4.3 多项式拟合的系数解读与函数构造np.polyfit返回的系数数组下标对应着从高次到低次的系数。np.poly1d是一个非常好用的工具它能将这些系数变成一个可调用的函数。# 以2阶拟合为例 coeffs_deg2 np.polyfit(x_poly, y_poly, 2) print(f2阶拟合系数从x^2到常数项{coeffs_deg2}) # 使用 poly1d 创建多项式函数 poly_func np.poly1d(coeffs_deg2) print(f\n生成的多项式函数为\n{poly_func}) print(f\n当 x1 时函数的预测值为{poly_func(1):.4f}) print(f也可以直接计算{coeffs_deg2[0]*1**2 coeffs_deg2[1]*1 coeffs_deg2[2]:.4f}) # 你可以像使用普通函数一样使用它 x_new np.array([0.5, 1.5, 2.5]) y_new_pred poly_func(x_new) print(f\n对新数据点 {x_new} 的预测值为{y_new_pred})5. 非线性拟合以对数拟合为例当数据呈现对数增长或衰减趋势时例如某些生物生长初期、声音的感知强度与物理强度的关系我们就需要用到非线性拟合。这里scipy.optimize.curve_fit是绝对的主力。5.1 定义拟合函数模型curve_fit的核心思想是你告诉它一个函数的形式模型它帮你找到最优的函数参数。以对数拟合为例我们假设模型为y a * ln(x) b自然对数或y a * log10(x) b常用对数。# 生成模拟的对数关系数据 np.random.seed(2023) x_log np.linspace(1, 50, 40) # 注意对数函数的定义域要求 x 0 a_true_log, b_true_log 3.0, 5.0 y_log_true a_true_log * np.log(x_log) b_true_log # 使用自然对数 ln noise_log np.random.randn(40) * 0.8 y_log y_log_true noise_log plt.scatter(x_log, y_log, label模拟数据 (y a*ln(x)bnoise)) plt.plot(x_log, y_log_true, k--, labelf真实关系: a{a_true_log}, b{b_true_log}) plt.xlabel(X (必须0)) plt.ylabel(Y) plt.title(对数关系模拟数据) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.show()5.2 使用curve_fit进行参数估计现在我们假装不知道真实的a和b用curve_fit来估计它们。# 第一步定义你想要拟合的函数形式 def log_func(x, a, b): 对数函数模型y a * ln(x) b return a * np.log(x) b # 第二步调用 curve_fit 进行拟合 # 参数模型函数、自变量数据、因变量数据 # 返回最优参数(popt)、参数的估计协方差矩阵(pcov) popt, pcov curve_fit(log_func, x_log, y_log) a_fit, b_fit popt print(f拟合参数a {a_fit:.4f}, b {b_fit:.4f}) print(f真实参数a {a_true_log:.4f}, b {b_true_log:.4f}) # 第三步使用拟合参数进行预测和绘图 y_log_fit log_func(x_log, a_fit, b_fit) x_plot_dense np.linspace(x_log.min(), x_log.max(), 300) y_plot_dense log_func(x_plot_dense, a_fit, b_fit) # 计算R² r2_log r2_score(y_log, y_log_fit) print(f对数拟合 R² {r2_log:.4f}) plt.figure(figsize(10, 6)) plt.scatter(x_log, y_log, alpha0.7, label数据点) plt.plot(x_plot_dense, y_plot_dense, r-, linewidth3, labelf拟合曲线: y{a_fit:.2f}*ln(x){b_fit:.2f} (R²{r2_log:.3f})) plt.plot(x_log, y_log_true, k:, linewidth2, label真实关系) plt.xlabel(X) plt.ylabel(Y) plt.title(使用 curve_fit 进行对数拟合) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.show()curve_fit的强大之处在于你可以定义任何形式的函数模型只要你能用Python函数写出来它就能尝试去拟合。比如指数函数a * exp(b*x) c、幂函数a * x**b等等。5.3 拟合质量评估与参数边界约束pcov参数的协方差矩阵可以用来估算参数的标准误差。其对角线元素的平方根就是对应参数的近似标准误差。# 计算参数的标准误差 perr np.sqrt(np.diag(pcov)) # 取协方差矩阵对角线的平方根 print(f参数 a 的标准误差{perr[0]:.4f}) print(f参数 b 的标准误差{perr[1]:.4f}) # 通常参数值与其标准误差的绝对值之比类似t统计量远大于2可以认为该参数是显著的。 # 有时我们根据物理意义或先验知识知道参数的大致范围。 # curve_fit 允许通过 bounds 参数设置上下界 # 例如假设我们知道斜率 a 应该是正数且截距 b 在 0 到 10 之间 lower_bounds [0, 0] # [a_min, b_min] upper_bounds [np.inf, 10] # [a_max, b_max] popt_bounded, pcov_bounded curve_fit(log_func, x_log, y_log, bounds(lower_bounds, upper_bounds)) print(f\n带边界约束的拟合参数a {popt_bounded[0]:.4f}, b {popt_bounded[1]:.4f})注意事项curve_fit默认使用非线性最小二乘法对于复杂的模型或不好的初始值可能会收敛到局部最优解而非全局最优。如果拟合结果不理想可以尝试提供初始参数猜测值p0参数这能极大地帮助算法找到正确的解。例如popt, pcov curve_fit(log_func, x_log, y_log, p0[2, 6])。6. 综合案例与高级技巧掌握了三种基本拟合方法后我们来看一个更贴近实际的综合案例并探讨一些提升拟合效果和可靠性的技巧。6.1 案例传感器温度校准假设你有一个温度传感器其输出电压V与环境温度T的关系理论上是指数衰减的V A * exp(-B * T) C。你通过实验测量了一组(T, V)数据现在需要拟合出参数A, B, C以便用输出电压反推温度。# 模拟传感器数据 np.random.seed(99) T_data np.linspace(10, 50, 25) # 温度范围10-50°C A_true, B_true, C_true 5.0, 0.05, 0.5 V_true A_true * np.exp(-B_true * T_data) C_true V_data V_true np.random.randn(25) * 0.05 # 加入微小噪声 # 定义指数衰减模型 def exp_decay(T, A, B, C): return A * np.exp(-B * T) C # 提供初始猜测值很重要对于指数衰减A约等于数据最大值B是正小数C约等于数据最小值或基线 initial_guess [V_data.max(), 0.1, V_data.min()] popt_sensor, pcov_sensor curve_fit(exp_decay, T_data, V_data, p0initial_guess) A_fit, B_fit, C_fit popt_sensor print(f拟合参数A{A_fit:.4f}, B{B_fit:.4f}, C{C_fit:.4f}) print(f真实参数A{A_true:.4f}, B{B_true:.4f}, C{C_true:.4f}) # 可视化 T_plot np.linspace(T_data.min(), T_data.max(), 200) V_plot_fit exp_decay(T_plot, A_fit, B_fit, C_fit) plt.figure(figsize(10, 6)) plt.scatter(T_data, V_data, label传感器实测数据) plt.plot(T_plot, V_plot_fit, r-, linewidth2, labelf拟合曲线: V{A_fit:.2f}*exp(-{B_fit:.3f}*T){C_fit:.2f}) plt.plot(T_data, V_true, k--, alpha0.7, label真实物理关系) plt.xlabel(温度 T (°C)) plt.ylabel(输出电压 V (V)) plt.title(传感器温度特性曲线拟合 (指数衰减模型)) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.show() # 利用拟合模型进行反推已知电压V求温度T # 这需要解方程V_measured A_fit * exp(-B_fit * T) C_fit # 可以推导出T - (1/B_fit) * log((V_measured - C_fit) / A_fit) def voltage_to_temp(V_meas, A, B, C): 将测量电压转换为温度 return - (1/B) * np.log((V_meas - C) / A) V_measured_example 2.0 T_inferred voltage_to_temp(V_measured_example, A_fit, B_fit, C_fit) print(f\n当测量到电压为 {V_measured_example} V 时推断温度为 {T_inferred:.2f} °C)6.2 数据预处理与拟合稳健性拟合的成败很大程度上取决于数据质量。两个关键的预处理步骤是数据清洗和特征缩放。异常值处理严重偏离主体的数据点会极大地扭曲拟合结果。可以使用统计学方法如3σ原则或可视化方法识别并处理异常值。# 简单的基于标准差Z-score的异常值过滤示例针对线性数据 from scipy import stats z_scores np.abs(stats.zscore(np.column_stack((x, y)), axis0)) # 假设我们过滤掉任一维度上Z-score大于3的点 threshold 3 outlier_mask (z_scores threshold).all(axis1) x_clean, y_clean x[outlier_mask], y[outlier_mask] print(f原始数据点{len(x)} 清洗后数据点{len(x_clean)}) # 然后用 x_clean, y_clean 去做拟合特征缩放对于多项式拟合尤其重要当x的值很大时比如几千、几万x的高次幂x^2,x^3...会变得极其巨大导致计算中的数值不稳定“溢出”。将x标准化到[0,1]或[-1,1]区间可以解决这个问题。# 最小-最大缩放 x_original np.array([1000, 2000, 3000, 4000]) x_min, x_max x_original.min(), x_original.max() x_scaled (x_original - x_min) / (x_max - x_min) # 缩放到[0,1] # 对缩放后的 x_scaled 进行高阶多项式拟合 # 注意拟合出的系数是针对缩放后数据的。预测新数据时需要先将新数据用同样的 min, max 进行缩放。6.3 模型评估与交叉验证我们之前一直用R²在训练数据上评估这容易导致对过拟合模型过于乐观。更可靠的方法是使用交叉验证。from sklearn.model_selection import cross_val_score from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import make_pipeline from sklearn.linear_model import LinearRegression # 假设我们想评估一个3阶多项式模型 degree 3 # 创建一个管道先构造多项式特征再进行线性回归 model_poly make_pipeline(PolynomialFeatures(degree), LinearRegression()) # 使用5折交叉验证计算R²分数 # cv5 表示将数据分成5份轮流用其中4份训练1份测试重复5次 scores cross_val_score(model_poly, x_poly.reshape(-1,1), y_poly, cv5, scoringr2) print(f3阶多项式模型的5折交叉验证R²分数{scores}) print(f 平均R²分数{scores.mean():.4f} (/- {scores.std()*2:.4f})) # 如果交叉验证的分数远低于在全部训练数据上拟合的分数说明模型很可能过拟合了。7. 常见问题与排查技巧实录在实际操作中你肯定会遇到各种报错和不如预期的结果。这里记录了几个最常见的问题和我的解决思路。7.1 拟合失败或结果荒谬问题表现curve_fit报错如RuntimeError或拟合出的曲线完全偏离数据点。排查思路检查模型函数定义确保你的Python函数数学上是正确的。特别是对数函数log输入必须大于0。提供初始猜测值(p0)这是解决非线性拟合失败最有效的方法。根据你对物理过程的理解给参数一个合理的初始估计。比如指数衰减的B参数应该是正数。检查数据范围对于指数、对数等函数数据范围可能导致计算溢出如exp(1000)。考虑对数据进行缩放。尝试不同的拟合方法curve_fit默认使用Levenberg-Marquardt算法。对于有边界的问题它内置了处理能力。对于特别难的问题可以查阅scipy.optimize的其他函数如least_squares。7.2 过拟合与欠拟合的判断问题表现模型在训练数据上表现完美但在新数据上预测不准过拟合或者模型在训练数据上就表现很差欠拟合。判断与解决可视化是第一道防线永远把拟合曲线和原始数据画在一起看过拟合的曲线会“抖动”得很厉害欠拟合的曲线则过于平滑抓不住趋势。使用交叉验证如上节所述这是量化评估模型泛化能力的标准方法。解决过拟合降低多项式阶数增加训练数据量使用正则化如Ridge Regression, Lasso Regression在sklearn中很容易实现。解决欠拟合增加多项式阶数为非线性模型添加更多特征项检查是否使用了错误的模型比如用线性模型去拟合指数数据。7.3 拟合优度R²的理解误区常见误区认为R²越高越好盲目追求高R²。正确理解R²表示模型解释的数据方差比例。但要注意R²高不一定代表模型好可能过拟合。对于非线性模型如通过curve_fit拟合的计算R²时要注意其定义是基于线性模型的延伸虽然常用但解释力会打折扣。更推荐同时使用**均方根误差(RMSE)或平均绝对误差(MAE)**等绝对误差指标。比较不同数据集上的R²没有意义。R²的高低与数据自身的波动范围有关。from sklearn.metrics import mean_squared_error, mean_absolute_error # 计算RMSE和MAE y_pred model_lr.predict(X_sklearn) # 以之前的线性模型为例 rmse np.sqrt(mean_squared_error(y, y_pred)) mae mean_absolute_error(y, y_pred) print(fRMSE: {rmse:.4f}, MAE: {mae:.4f}) # RMSE和MAE的量纲与y相同更直观。例如如果y是温度(°C)RMSE1.2表示平均预测误差在1.2°C左右。7.4 多项式拟合中的数值不稳定问题问题表现高阶多项式拟合时系数变得异常大或者np.polyfit抛出RankWarning警告。根本原因当阶数较高时范德蒙矩阵由x的幂次构成的条件数会变得非常大成为病态矩阵微小扰动会导致解的巨大变化。解决方案缩放数据如前所述将x缩放到[-1, 1]区间。这是最推荐的做法。使用正交多项式numpy提供了numpy.polynomial子模块如Polynomial,Chebyshev它们使用在特定区间上正交的多项式基数值稳定性好得多。from numpy.polynomial import Polynomial # 使用 Polynomial.fit 它内部会处理缩放 p_poly_obj Polynomial.fit(x_poly, y_poly, deg2) # 拟合2阶 # 注意Polynomial返回的系数顺序是 [c0, c1, c2,...] (低次到高次)与poly1d相反 print(p_poly_obj.convert().coef) # .convert() 可以转换到标准幂基表示最后我想分享的一点个人体会是拟合的本质是一种“妥协的艺术”。我们不是在寻找一个穿过所有点的完美数学曲线而是在寻找一个能抓住数据主要趋势、并且能用于可靠预测的简化模型。因此理解你的数据来源物理背景、业务逻辑比精通任何一个拟合函数都更重要。它决定了你应该选择哪种模型以及如何解释拟合结果。当你对数据和模型都有了直觉再配合Python这些强大的工具从数据中挖掘规律就会变成一件充满乐趣的事情。