尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从最小二乘法到稳健回归:数据拟合的核心算法与Python实战

从最小二乘法到稳健回归:数据拟合的核心算法与Python实战 1. 从“差不多就行”到“严丝合缝”为什么我们需要拟合算法在数学建模和数据分析的日常工作中我们常常会遇到这样的场景手头有一堆散乱的数据点它们看起来似乎遵循着某种规律但又无法用一条完美的直线或曲线直接穿过每一个点。比如你记录了连续一周内每天的气温和冰淇淋销量想找出它们之间的关系或者你测量了不同浓度下化学反应的速率试图建立一个预测模型。这时候你需要的不是精确穿过每个点的“插值”而是一种能抓住数据整体趋势、忽略个别噪声的“概括”方法。这就是拟合算法要解决的核心问题。简单来说拟合就是用一个已知形式的函数比如一次函数、二次函数、指数函数等去“贴近”一组观测数据使得这个函数在整体上与所有数据点的“距离”之和最小。它承认数据存在误差追求的是对潜在规律的“最佳”描述而不是对每个点的“精确”复现。从最简单的线性回归到复杂的非线性拟合再到如今机器学习中无处不在的损失函数最小化其思想内核一脉相承。掌握拟合意味着你掌握了从混沌数据中提炼简洁数学规律的基本功这是从数据描述走向预测和决策的关键一步。2. 拟合与插值的本质区别追求“趋势”还是“精确”在深入拟合算法之前必须先厘清一个初学者极易混淆的概念拟合与插值。虽然两者都涉及用函数描述数据但目的和适用场景截然不同。插值的核心要求是构造的函数曲线必须精确地穿过每一个给定的数据点。它假设我们提供的数据点是绝对准确、没有误差的目标是在这些已知点之间进行“填充”或“预测”。常见的插值方法有拉格朗日插值、牛顿插值、样条插值等。想象一下你有一张精确的等高线地图上的几个点插值就是帮你画出穿过这些点的平滑等高线。拟合则恰恰相反。它承认观测数据存在测量误差、随机噪声或本身的不确定性。拟合的目标不是穿过每一个点而是找到一个函数使得该函数与所有数据点的“总体偏差”最小。这个函数是对数据背后隐藏规律的一种估计和近似。继续用地图的比喻拟合就像是你根据一片区域散乱的海拔测量数据这些数据可能有误差去推断出这片区域大致的坡度趋势线。为什么这个区别如此重要因为误用会导致完全错误的结论。如果你用插值方法去处理带有明显噪声的实验数据得到的将是一条扭曲、振荡剧烈的曲线这种现象在多项式插值中尤为明显称为“龙格现象”它过度拟合了噪声完全无法反映真实规律。而用拟合方法处理本应精确的基准数据则会丢失关键信息。因此选择哪种方法首先取决于你对数据性质的判断数据是精确的基准点还是带有误差的观测样本3. 最小二乘法拟合世界的“基石”与“标尺”谈到拟合几乎无法绕过最小二乘法。它不仅是线性拟合的标准方法更是众多复杂拟合算法的思想源头。理解最小二乘法就握住了打开拟合世界大门的钥匙。3.1 核心思想如何定义“最佳”假设我们有一组数据点(x_i, y_i), i1,2,...,n我们想用一条直线y kx b去拟合它们。对于每一个数据点用直线预测的值是(k*x_i b)而实际值是y_i它们之间的差值e_i y_i - (k*x_i b)称为残差。那么怎样才算“最佳”拟合最小二乘法给出的答案是找到参数k和b使得所有数据点的残差平方和达到最小。即最小化目标函数S Σ(e_i)^2 Σ [y_i - (k*x_i b)]^2为什么是“平方和”而不是简单的“绝对值和”这背后有深刻的数学和统计考量数学处理简便平方函数处处可导这使得我们可以通过求导数为零的方法即正规方程组来解析地求出最优参数k和b计算非常高效。对大误差的惩罚更重平方项会放大较大残差的影响。这意味着拟合直线会努力避免出现个别偏离特别远的点从而使拟合结果对异常值相对更稳健当然异常值影响依然存在这引出了后续的稳健拟合方法。统计意义在误差服从正态分布的假设下最小二乘估计得到的参数是“最优线性无偏估计”。3.2 从直线到曲线多项式拟合一旦掌握了最小二乘的思想将其从直线推广到曲线就顺理成章。多项式拟合是其中最直接的应用。我们不再局限于y kx b而是使用更高次的多项式y a_0 a_1*x a_2*x^2 ... a_m*x^m目标同样是找到一组系数[a_0, a_1, ..., a_m]使得多项式预测值与实际值的残差平方和最小。尽管函数形式变复杂了但“最小化平方和”的核心目标没变求解方法也从二元一次方程组变成了求解一个线性方程组涉及范德蒙德矩阵。这里有一个至关重要的经验多项式阶数m的选择是艺术也是科学。m太小例如用直线去拟合明显弯曲的数据模型过于简单无法捕捉数据特征称为“欠拟合”。m太大模型会变得极其复杂不仅会拟合规律还会连数据中的噪声也一并拟合进去导致曲线剧烈震荡预测新数据的能力极差称为“过拟合”。一个实用的技巧是多项式阶数最高不要超过数据点个数减1因为n个点可以唯一确定一个n-1次多项式但那已经是插值了。通常从低阶如123开始尝试观察拟合效果和残差分布并利用交叉验证等方法来确定合适的阶数。3.3 正规方程与数值计算对于线性最小二乘问题包括多项式拟合因为对系数而言它是线性的我们可以通过求解正规方程来得到解析解。以简单线性回归为例最优k和b满足k (nΣx_i y_i - Σx_i Σy_i) / (nΣx_i^2 - (Σx_i)^2) b (Σy_i - kΣx_i) / n对于更高维度的多元线性回归或多项式拟合正规方程可以写成矩阵形式(X^T X) β X^T Y其中X是设计矩阵β是待求系数向量Y是观测值向量。求解β (X^T X)^{-1} X^T Y即可。注意在实际编程计算中不建议直接对矩阵(X^T X)求逆。当X的列之间存在近似线性关系多重共线性时(X^T X)可能接近奇异矩阵求逆会带来巨大的数值误差。更稳健的方法是使用QR分解或奇异值分解等数值算法来求解。例如在Python的NumPy中np.linalg.lstsq函数就默认使用了SVD方法。4. 超越线性非线性拟合与优化算法现实世界的关系远非都是线性的。人口增长可能符合指数模型药物浓度衰减可能符合指数衰减模型这些模型的参数如指数函数的底数无法通过线性变换转化为线性最小二乘问题。这时我们就进入了非线性拟合的领域。4.1 问题转化从“线性”到“非线性”非线性拟合的模型形式如y f(x, β)其中f是非线性函数β是待估参数向量。例如指数模型y a * exp(b*x)参数β [a, b]幂律模型y a * x^b参数β [a, b]对数模型y a b * ln(x)对于这类问题最小二乘的目标函数变为S(β) Σ [y_i - f(x_i, β)]^2。由于f关于β是非线性的我们无法再通过解线性方程组得到解析解。4.2 迭代求解梯度下降与高斯-牛顿法非线性最小二乘问题通常通过迭代优化算法求解。核心思想是从一个初始参数猜测β_0开始沿着使目标函数S(β)下降最快的方向负梯度方向不断更新参数直至收敛到最小值点附近。1. 梯度下降法最直观的优化方法。更新公式为β_{new} β_{old} - η * ∇S(β_{old})其中η是学习率步长。它的优点是简单易懂但收敛速度可能较慢且需要精心调整学习率。2. 高斯-牛顿法专门为非线性最小二乘问题设计的更高效算法。它利用了最小二乘目标函数的特殊结构对残差函数r_i(β) y_i - f(x_i, β)进行一阶泰勒展开将每一步的迭代更新转化为一个线性最小二乘问题来求解。高斯-牛顿法在接近最优解时通常具有二次收敛速度非常快但它对初始值比较敏感且当残差较大或模型非线性很强时可能无法收敛。3. Levenberg-Marquardt 算法这可以说是实践中最常用、最鲁棒的非线性最小二乘求解器。它本质上是梯度下降法和高斯-牛顿法的混合体。当参数远离最优解时它更像梯度下降法保证稳定下降当接近最优解时它自动切换到高斯-牛顿法加速收敛。该算法能有效处理病态ill-conditioned问题对初始值的宽容度也更高。像 SciPy 库中的scipy.optimize.curve_fit函数其默认的核心算法就是 Levenberg-Marquardt。4.3 实操心得初始值、参数边界与收敛判断在实际进行非线性拟合时有以下几个坑需要特别注意初始参数值的选择至关重要。一个糟糕的初始值可能导致算法收敛到局部极小值甚至发散。提供初始值不是瞎猜利用物理/业务意义如果参数有明确意义如半衰期、饱和值可以根据经验或数据粗略估计一个范围。线性化近似对于某些模型可以通过变量变换化为线性问题先求一个粗略解。例如对y a*exp(b*x)两边取对数得到ln(y) ln(a) b*x先用线性拟合求出ln(a)和b的估计值再作为非线性拟合的初始值。多起点尝试从多个不同的初始值开始运行拟合算法观察它们是否收敛到同一组参数这有助于判断是否找到了全局最优。设定参数边界。很多参数有物理限制如浓度不能为负增长率有合理范围。在scipy.optimize.curve_fit中可以使用bounds参数来设定每个参数的上下限。这不仅能防止算法跑到无意义的区域还能显著提高收敛的稳定性和速度。不要盲目相信 R²。对于非线性拟合决定系数 R² 的计算和解释与线性模型有所不同有时甚至可能为负。更重要的是观察拟合曲线与数据点的视觉吻合度。残差图残差是否随机、均匀地分布在0轴上下如果残差呈现明显的规律如抛物线形说明模型形式可能选错了。参数的标准误差可靠的拟合结果应当给出参数估计的置信区间或标准误如果某个参数的标准误非常大说明该参数在数据中难以确定模型可能过于复杂或数据信息不足。5. 拟合优度评价不仅仅是R²完成拟合后如何判断这个拟合结果好不好“看起来挺像”显然不够专业。我们需要一套定量的评价体系。5.1 常用指标解读残差平方和这是最根本的指标即我们最小化的目标SSE Σ(y_i - ŷ_i)^2。其绝对值大小受数据量纲影响通常用于比较对同一数据集的不同模型。决定系数R² 1 - SSE/SST其中SST Σ(y_i - ȳ)^2是总平方和。R²衡量了模型解释的数据变异性的比例。越接近1说明模型对数据的解释能力越强。重要提示对于非线性拟合R²可能不在0到1之间且其“解释方差”的统计解释不再严格成立。它更多是作为一个描述性的拟合优度参考。调整后的R²当模型中加入更多变量如多项式的高次项时R²总会增加这可能导致过拟合。调整R²引入了惩罚项R²_adj 1 - [(1-R²)(n-1)/(n-p-1)]其中n是样本数p是参数个数。它更适用于比较不同复杂度的模型。均方根误差RMSE sqrt(SSE/n)。它的大小与因变量y有相同的量纲因此更直观。例如预测房价的模型RMSE是5万元我们可以直观理解为平均预测误差在5万元左右。赤池信息准则AIC 2p n*ln(SSE/n)。BIC与之类似。AIC/BIC不仅衡量拟合好坏SSE还惩罚模型复杂度p。在多个候选模型中AIC/BIC值最小的模型被认为是“最优”的它在拟合优度和模型简洁性之间取得了最佳平衡。这是模型比较中非常强大的工具。5.2 图形化诊断残差分析数字指标可能掩盖问题图形诊断则一目了然。绘制残差图以预测值ŷ或自变量x为横轴残差e为纵轴是必须的步骤。理想情况残差点随机、均匀地分布在横轴0线上下无明显规律且残差带宽大致恒定。出现问题漏斗形残差随ŷ增大而增大/减小说明可能存在异方差性最小二乘的假设不满足可能需要加权最小二乘或对变量进行变换如取对数。弯曲趋势残差呈现明显的曲线 pattern这强烈暗示你选择的模型函数形式不对遗漏了重要的非线性项或交互项。离群点个别点残差绝对值远大于其他点这些点可能是异常值需要审查数据或使用稳健拟合方法。6. 稳健回归当数据“不干净”时怎么办经典的最小二乘拟合有一个软肋它对异常值非常敏感。因为最小二乘最小化的是残差平方和一个远离群体的异常点会产生巨大的平方项从而将拟合直线“拉”向自己导致整个模型失真。6.1 异常值的破坏力假设你用最小二乘拟合一组基本呈线性关系的数据结果很好。此时你不小心误录入了一个数据点它的x值正常但y值错了10倍。当你重新拟合时会发现拟合直线发生了明显的偏移斜率可能都变了。这个“一粒老鼠屎坏了一锅粥”的现象就是最小二乘缺乏稳健性的体现。6.2 稳健拟合方法为了解决这个问题统计学家提出了多种稳健回归方法其核心思想是降低异常值在目标函数中的权重。最小一乘法将目标函数从最小化残差平方和改为最小化残差绝对值和S Σ|e_i|。这相当于用中位数而非平均数来估计中心趋势对异常值的敏感度大大降低。但代价是目标函数在零点不可导求解需要用线性规划等迭代算法计算比最小二乘复杂。M-估计法这是最小二乘法的直接推广。它不再使用平方损失ρ(e) e^2而是使用其他增长更慢的损失函数例如Huber损失在|e|较小时采用平方损失保证效率在|e|较大时采用线性损失降低异常值影响。Tukey双权损失当|e|超过某个阈值后损失函数不再增加从而完全“忽略”极端异常值。 通过迭代重加权最小二乘算法可以求解M-估计。RANSAC这是一种完全不同的思路尤其适用于数据中包含大量局外点的情况。其步骤是随机从数据中抽取最小样本集如拟合直线则抽2个点来估计一个模型。用这个模型去测试所有其他点将误差小于阈值的点标记为“内点”。重复以上过程多次最终选择内点数量最多的那个模型并用所有内点重新进行最小二乘拟合。 RANSAC在计算机视觉如从匹配点中估计基础矩阵中应用极广。实操选择建议对于一般数据分析如果怀疑有少量中度异常值可以尝试Huber回归或Tukey双权回归。如果数据污染非常严重异常点比例可能很高RANSAC是更安全的选择。大多数科学计算库如SciPy、statsmodels都提供了这些稳健回归的实现。7. 实战流程与工具选择以Python为例理论最终要落地。下面以一个完整的例子展示使用Python进行数据拟合的标准流程和关键代码。7.1 数据准备与探索假设我们有一组模拟数据反映某种材料的应力-应变关系初步判断可能符合指数饱和增长模型y a*(1 - exp(-b*x))。import numpy as np import matplotlib.pyplot as plt from scipy import optimize, stats # 生成模拟数据并加入一些噪声和异常值 np.random.seed(42) x_data np.linspace(0, 10, 50) a_true, b_true 5.0, 0.5 y_true a_true * (1 - np.exp(-b_true * x_data)) # 添加高斯噪声 noise np.random.normal(0, 0.2, y_true.shape) # 故意添加两个异常值 y_data y_true noise y_data[10] 3.0 # 加入一个正异常值 y_data[35] - 2.5 # 加入一个负异常值 # 可视化原始数据 plt.figure(figsize(10, 6)) plt.scatter(x_data, y_data, alpha0.7, labelRaw Data with Outliers) plt.plot(x_data, y_true, k--, lw2, labelTrue Underlying Model) plt.xlabel(Strain) plt.ylabel(Stress) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.title(Exploratory Data Plot) plt.show()这一步至关重要。通过可视化我们能清晰地看到数据的整体趋势、噪声水平和异常值的存在这直接影响了后续模型选择和拟合方法。7.2 模型定义与经典最小二乘拟合首先我们尝试使用经典的非线性最小二乘。# 1. 定义待拟合的模型函数 def exp_saturation_model(x, a, b): return a * (1 - np.exp(-b * x)) # 2. 使用 curve_fit 进行拟合 (默认使用Levenberg-Marquardt算法) popt, pcov optimize.curve_fit(exp_saturation_model, x_data, y_data) a_fit_ls, b_fit_ls popt print(f经典最小二乘拟合结果: a {a_fit_ls:.3f}, b {b_fit_ls:.3f}) # 计算拟合值及残差 y_pred_ls exp_saturation_model(x_data, a_fit_ls, b_fit_ls) residuals_ls y_data - y_pred_ls # 3. 可视化拟合结果与残差 fig, axes plt.subplots(1, 2, figsize(14, 5)) # 左图拟合曲线对比 axes[0].scatter(x_data, y_data, alpha0.6, labelData) axes[0].plot(x_data, y_true, k--, lw2, labelTrue Model) axes[0].plot(x_data, y_pred_ls, r-, lw2, labelfLS Fit: a{a_fit_ls:.2f}, b{b_fit_ls:.2f}) axes[0].set_xlabel(Strain) axes[0].set_ylabel(Stress) axes[0].legend() axes[0].grid(True, linestyle--, alpha0.5) axes[0].set_title(Model Fit Comparison) # 右图残差图 axes[1].scatter(y_pred_ls, residuals_ls, alpha0.6) axes[1].axhline(y0, colorr, linestyle--) axes[1].set_xlabel(Fitted Values) axes[1].set_ylabel(Residuals) axes[1].grid(True, linestyle--, alpha0.5) axes[1].set_title(Residual Plot of Least Squares Fit) # 标记异常值对应的残差 outlier_indices [10, 35] for idx in outlier_indices: axes[1].scatter(y_pred_ls[idx], residuals_ls[idx], colororange, s100, edgecolorsred, linewidth2) plt.tight_layout() plt.show()从残差图可以明显看到两个异常值橙色点的残差远大于其他点。经典最小二乘的拟合曲线红色已经被这两个点“拉”偏了与真实模型黑色虚线存在肉眼可见的偏差。7.3 引入稳健拟合接下来我们使用一个基于Huber损失的稳健拟合方法来做对比。SciPy的optimize.curve_fit可以通过loss参数指定稳健损失函数。# 使用Huber损失进行稳健拟合 # Huber损失在 |残差| delta 时用平方损失 delta 时用线性损失delta默认为1.345 popt_robust, pcov_robust optimize.curve_fit(exp_saturation_model, x_data, y_data, losshuber, f_scale1.0) # f_scale是尺度估计 a_fit_rob, b_fit_rob popt_robust print(f稳健(Huber)拟合结果: a {a_fit_rob:.3f}, b {b_fit_rob:.3f}) y_pred_rob exp_saturation_model(x_data, a_fit_rob, b_fit_rob) residuals_rob y_data - y_pred_rob # 综合对比可视化 plt.figure(figsize(10, 6)) plt.scatter(x_data, y_data, alpha0.6, labelData with Outliers, zorder1) plt.plot(x_data, y_true, k--, lw3, labelTrue Model, zorder2) plt.plot(x_data, y_pred_ls, r-, lw2, labelfClassic LS (a{a_fit_ls:.2f}, b{b_fit_ls:.2f}), zorder3) plt.plot(x_data, y_pred_rob, b-, lw2, labelfRobust Huber (a{a_fit_rob:.2f}, b{b_fit_rob:.2f}), zorder4) plt.xlabel(Strain) plt.ylabel(Stress) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.title(Comparison: Classic Least Squares vs. Robust Regression) plt.show() # 计算并对比评价指标 def calculate_metrics(y_true, y_pred): sse np.sum((y_true - y_pred)**2) rmse np.sqrt(sse / len(y_true)) # 计算R² (对于非线性模型仅供参考) ss_tot np.sum((y_true - np.mean(y_true))**2) r2 1 - sse/ss_tot return sse, rmse, r2 sse_ls, rmse_ls, r2_ls calculate_metrics(y_data, y_pred_ls) sse_rob, rmse_rob, r2_rob calculate_metrics(y_data, y_pred_rob) print(\n--- 拟合优度对比 (基于全部数据含异常值) ---) print(f经典最小二乘: SSE{sse_ls:.3f}, RMSE{rmse_ls:.3f}, R²{r2_ls:.3f}) print(f稳健Huber拟合: SSE{sse_rob:.3f}, RMSE{rmse_rob:.3f}, R²{r2_rob:.3f}) # 更合理的对比排除异常值后的拟合优度模拟我们已知异常值位置 mask np.ones(len(x_data), dtypebool) mask[outlier_indices] False x_clean, y_clean x_data[mask], y_data[mask] y_pred_ls_clean exp_saturation_model(x_clean, a_fit_ls, b_fit_ls) y_pred_rob_clean exp_saturation_model(x_clean, a_fit_rob, b_fit_rob) sse_ls_clean, rmse_ls_clean, _ calculate_metrics(y_clean, y_pred_ls_clean) sse_rob_clean, rmse_rob_clean, _ calculate_metrics(y_clean, y_pred_rob_clean) print(\n--- 拟合优度对比 (基于干净数据排除异常值) ---) print(f经典最小二乘在干净数据上的RMSE: {rmse_ls_clean:.3f}) print(f稳健Huber拟合在干净数据上的RMSE: {rmse_rob_clean:.3f})从对比图中可以清晰看到蓝色曲线代表的稳健拟合结果明显比红色曲线更贴近真实的黑色虚线模型。尽管在包含异常值的全体数据上稳健拟合的SSE和RMSE可能比经典最小二乘还大因为异常值贡献了巨大误差但当我们在干净数据上评估时稳健拟合的RMSE远小于经典最小二乘。这正说明了稳健拟合的价值它牺牲了对异常点的“拟合度”换来了对主体数据规律的更准确刻画。7.4 模型诊断与参数解读最后我们需要对稳健拟合的结果进行诊断和解读。# 稳健拟合的残差图 plt.figure(figsize(12, 4)) plt.subplot(1, 2, 1) plt.scatter(y_pred_rob, residuals_rob, alpha0.6) plt.axhline(y0, colorr, linestyle--) plt.xlabel(Fitted Values (Robust)) plt.ylabel(Residuals) plt.title(Residual Plot of Robust Fit) plt.grid(True, linestyle--, alpha0.5) # 残差分布直方图与Q-Q图检验正态性 plt.subplot(1, 2, 2) # 使用statsmodels的Q-Q图功能更便捷这里用概率图近似 from scipy import stats as scistats scistats.probplot(residuals_rob, distnorm, plotplt) plt.title(Q-Q Plot of Residuals (Robust Fit)) plt.grid(True, linestyle--, alpha0.5) plt.tight_layout() plt.show() # 参数置信区间估计基于协方差矩阵 perr np.sqrt(np.diag(pcov_robust)) # 参数的标准误差 print(f\n--- 稳健拟合参数估计 ---) print(f参数 a {a_fit_rob:.3f} ± {1.96*perr[0]:.3f} (95% CI)) print(f参数 b {b_fit_rob:.3f} ± {1.96*perr[1]:.3f} (95% CI)) print(f真实值: a {a_true}, b {b_true}) print(f参数估计值已非常接近真实值且置信区间较窄说明估计可靠。)稳健拟合的残差图显示除了两个被“降权”处理的异常点外其余残差随机分布在0线附近。Q-Q图也表明残差大致服从正态分布点基本落在对角线上满足许多统计推断的前提假设。从参数估计结果看稳健拟合恢复出的参数a和b非常接近我们生成数据时使用的真实值并且置信区间较窄这给了我们使用这个模型进行预测的信心。8. 总结与进阶思考走完这个完整的流程你应该对拟合算法有了从理论到实践的立体认识。拟合不是简单地调用一个curve_fit函数而是一个包含数据探索、模型选择、算法实施、结果诊断和模型评价的完整循环。在实际项目中我还有几点深刻的体会 第一可视化先行。在敲任何一行拟合代码之前先把数据画出来。眼睛是最好的异常检测器和模型选择器很多问题如异常值、非线性、异方差在图上无所遁形。 第二理解你的工具。知道最小二乘为什么怕异常值知道稳健回归如何“稳健”知道不同优化算法如LM算法的优缺点。这能让你在结果不理想时知道该调整哪个“旋钮”而不是盲目试错。 第三模型评估要全面。不要只看R²或RMSE。一定要画残差图进行残差分析。对于重要模型如果条件允许用预留的测试集数据或交叉验证来评估其泛化能力严防过拟合。 第四结果的物理/业务可解释性至关重要。拟合出的参数必须有意义。如果一个增长模型的增长率被拟合为负值或者一个饱和模型的饱和值远超物理上限那么无论拟合优度多高这个模型都是无效的。这时需要回头检查数据、模型形式或使用带约束的拟合。拟合是数据科学与数学建模的基石。从这条看似简单的“找曲线”开始你可以走向更广阔的天地例如逻辑回归、神经网络本质上是极其复杂的非线性拟合、时间序列分析等。掌握其精髓意味着你掌握了用数学语言描述和预测世界的一种基本能力。
返回列表