You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Scipy拟合含未知形状参数矩阵C的函数?

拟合动态形状系数矩阵的二元多项式方案

核心问题是scipy的拟合函数仅支持一维参数数组,而你的系数矩阵C是运行时确定形状的二维结构(甚至可能每行长度不一致)。解决方案是将C扁平化作为拟合参数,同时提前记录C的形状信息,在拟合函数内部将参数恢复为原结构。

方案一:使用scipy.optimize.curve_fit

步骤说明

  1. 提取C的形状信息:行数、每行的列数列表
  2. 用闭包封装形状信息,生成符合curve_fit要求的目标函数(输入为自变量数组+扁平化参数,输出为预测值数组)
  3. 将初始C扁平化作为初始参数,执行拟合
  4. 将拟合得到的扁平化参数恢复为原C结构

代码示例

import numpy as np
from scipy.optimize import curve_fit

def make_fit_func(rows, cols_per_row):
    """生成拟合用的目标函数,封装C的形状信息"""
    def fit_func(x, *params):
        x0, x1 = x
        # 将扁平化参数恢复为C的结构
        C = []
        idx = 0
        for cols in cols_per_row:
            row = np.array(params[idx:idx+cols])
            C.append(row)
            idx += cols
        
        # 向量化计算预测值(避免循环样本,提升效率)
        result = 0.0
        for i in range(rows):
            # 计算x0的各次幂:shape=(样本数, 该行列数)
            x0_pows = x0[:, None] ** np.arange(cols_per_row[i])
            # 计算x1的i次幂:shape=(样本数,)
            x1_pow = x1 ** i
            # 累加该行的贡献
            result += (x0_pows @ C[i]) * x1_pow
        return result
    return fit_func

# ---------------------- 示例:生成测试数据 ----------------------
# 真实系数矩阵(形状运行时确定)
true_C = [[1.2, 0.8], [0.9]]
rows = len(true_C)
cols_per_row = [len(row) for row in true_C]
# 扁平化初始参数(可加噪声模拟初始猜测)
initial_params = np.concatenate(true_C) + np.random.normal(0, 0.1, size=len(np.concatenate(true_C)))

# 生成自变量样本
x0 = np.linspace(0, 5, 100)
x1 = np.linspace(0, 3, 100)
# 生成带噪声的目标值
y_true = []
for xi, yi in zip(x0, x1):
    r = 0
    for i in range(rows):
        for j in range(len(true_C[i])):
            r += xi**j * yi**i * true_C[i][j]
    y_true.append(r)
y = np.array(y_true) + np.random.normal(0, 0.2, size=len(y_true))

# ---------------------- 执行拟合 ----------------------
fit_func = make_fit_func(rows, cols_per_row)
popt, pcov = curve_fit(fit_func, (x0, x1), y, p0=initial_params)

# 将拟合参数恢复为C结构
fitted_C = []
idx = 0
for cols in cols_per_row:
    fitted_C.append(popt[idx:idx+cols].tolist())
    idx += cols

print("真实C:", true_C)
print("拟合C:", fitted_C)

方案二:使用scipy.optimize.least_squares

least_squares需要残差函数(预测值与真实值的差),思路与curve_fit一致,仅需调整函数签名为接受扁平化参数,返回残差数组。

代码示例

import numpy as np
from scipy.optimize import least_squares

def make_residual_func(x0, x1, y_true, rows, cols_per_row):
    """生成残差函数,封装数据和C的形状信息"""
    def residual_func(params):
        # 将扁平化参数恢复为C的结构
        C = []
        idx = 0
        for cols in cols_per_row:
            row = np.array(params[idx:idx+cols])
            C.append(row)
            idx += cols
        
        # 向量化计算预测值
        result = 0.0
        for i in range(rows):
            x0_pows = x0[:, None] ** np.arange(cols_per_row[i])
            x1_pow = x1 ** i
            result += (x0_pows @ C[i]) * x1_pow
        # 返回残差
        return result - y_true
    return residual_func

# 使用示例数据(同方案一)
residual_func = make_residual_func(x0, x1, y, rows, cols_per_row)
result = least_squares(residual_func, initial_params)

# 恢复拟合的C结构
fitted_C_ls = []
idx = 0
for cols in cols_per_row:
    fitted_C_ls.append(result.x[idx:idx+cols].tolist())
    idx += cols

print("least_squares拟合C:", fitted_C_ls)

关键注意点

  • 若样本量较大,务必使用向量化计算替代循环,避免性能瓶颈
  • 初始参数p0需根据实际情况合理设置,若初始值偏离过大可能导致拟合失败
  • 对于不规则形状的C(如示例中的[[1.,1.],[1.]]),代码同样适用,只需正确传递cols_per_row列表即可

内容的提问来源于stack exchange,提问作者Bagnarol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 06:56:55