如何用Numpy估计参数线性、自变量非线性函数的参数?
非线性自变量、线性参数的拟合方法
你的问题本质是线性回归的扩展应用——虽然函数对自变量x是非线性的,但对参数th是线性的,只要把非线性的自变量部分转换成新的特征,就能用你熟悉的最小二乘法求解。
核心思路
把原函数中的非线性项(比如sin(x₁)、x₁x₂)当作新的特征,构造一个新的特征矩阵,这样问题就转化为标准的线性回归:y = X_new @ th + ε,其中th = [th₀, th₁, th₂],ε是误差项。
具体步骤
构造新特征矩阵
X_new
对每个包含x₁和x₂的样本,生成三个特征:- 第一个特征恒为1(对应
th₀的常数项) - 第二个特征是
sin(x₁)(对应th₁的系数项) - 第三个特征是
x₁*x₂(对应th₂的系数项)
假设你有N个样本,原来的x是N×2的矩阵,那么X_new就是N×3的矩阵,每一行格式为[1, sin(x₁_i), x₁_i*x₂_i]。
- 第一个特征恒为1(对应
用最小二乘法求解参数
th
构造好X_new后,就可以用线性回归的方法求解:- 方法一:用你提到的
np.linalg.solve(要求X_new.T @ X_new是可逆矩阵) - 方法二:用
np.linalg.lstsq(更稳健,不需要矩阵可逆,适合样本量大于特征数的场景)
- 方法一:用你提到的
代码示例
import numpy as np # 模拟样本数据 np.random.seed(42) N = 100 x1 = np.random.uniform(0, 2*np.pi, N) x2 = np.random.uniform(-5, 5, N) # 真实参数 th_true = [2, 3, -0.5] # 生成带噪声的目标数组y y = th_true[0] + th_true[1]*np.sin(x1) + th_true[2]*x1*x2 + np.random.normal(0, 0.5, N) # 构造新特征矩阵 X_new = np.column_stack([ np.ones(N), # 常数项特征 np.sin(x1), # sin(x1)特征 x1 * x2 # x1*x2特征 ]) # 方法1:使用np.linalg.solve求解 th_est1 = np.linalg.solve(X_new.T @ X_new, X_new.T @ y) # 方法2:使用np.linalg.lstsq求解(更稳健) th_est2, _, _, _ = np.linalg.lstsq(X_new, y, rcond=None) print("真实参数:", th_true) print("solve估计参数:", np.round(th_est1, 3)) print("lstsq估计参数:", np.round(th_est2, 3))
为什么可行?
因为我们只是对自变量做了特征变换,模型本身依然是参数的线性组合,完全符合线性回归的假设,所以最小二乘法依然适用,求解出来的th就是使预测值和目标数组y误差最小的参数。
内容的提问来源于stack exchange,提问作者matti1499
相关产品推荐
相关产品推荐

