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

Python多变量曲线拟合(线性/非线性)触发IndexError求助

多变量曲线拟合(多元线性+Sigmoid)的IndexError解决

问题背景

需要用Python实现多变量函数拟合,包含多元线性拟合和非线性Sigmoid拟合,数据处理后得到包含Area、Room、Parking、Warehouse、Elevator、Address、Price的数值型DataFrame,拟合公式如下:

  • 多元线性拟合:Y = aX1 + bX2 +cX3 + dX4 + gX5 + hX6
  • 非线性Sigmoid拟合:Y = 1 / (1 + e^beta1(X - beta2)),其中X为aX1 + bX2 +cX3 + dX4 + gX5 + hX6

当前调用curve_fit(Multiple_Sigmoid_f, X_train, Y_real_train)时触发IndexError: invalid index to scalar variable,错误栈指向拟合函数中对Numeric_HDS的索引操作。

错误原因

  1. 函数参数顺序不符合curve_fit要求:curve_fit要求拟合函数的第一个参数是输入数据xdata,后续是待拟合参数,原函数把待拟合参数放在最前面、输入数据放在最后,导致参数传递混乱。
  2. 数据维度处理错误:X_train被转置为(6, N)形状,但函数内按行索引提取特征,与实际数据维度不匹配;同时curve_fit会将xdata作为单个参数传入,导致函数内对其索引时出现标量索引错误。

修正方案

1. 重构拟合函数的参数顺序与数据处理逻辑

curve_fit要求函数签名为func(xdata, *params),其中xdata是(N,6)形状的特征矩阵(N为样本数),*params是所有待拟合参数。

多元线性拟合函数

def Multiple_f(xdata, theta1, theta2, theta3, theta4, theta5, theta6):
    # xdata为(N,6)数组,每行对应一个样本的6个特征
    Area = xdata[:, 0]
    Room = xdata[:, 1]
    Parking = xdata[:, 2]
    Warehouse = xdata[:, 3]
    Elevator = xdata[:, 4]
    Address = xdata[:, 5]
    Y = theta1*Area + theta2*Room + theta3*Parking + theta4*Warehouse + theta5*Elevator + theta6*Address
    return Y

Sigmoid拟合函数

import numpy as np

def Multiple_Sigmoid_f(xdata, beta1, beta2, theta1, theta2, theta3, theta4, theta5, theta6):
    Area = xdata[:, 0]
    Room = xdata[:, 1]
    Parking = xdata[:, 2]
    Warehouse = xdata[:, 3]
    Elevator = xdata[:, 4]
    Address = xdata[:, 5]
    X = theta1*Area + theta2*Room + theta3*Parking + theta4*Warehouse + theta5*Elevator + theta6*Address
    Y = 1 / (1 + np.exp(beta1*(X - beta2)))
    return Y

2. 修正训练集特征维度

取消对特征矩阵的转置操作,保持(N,6)的样本-特征结构:

# 提取训练集特征,保持(N,6)形状
X_train = np.asanyarray(train[["Area","Room","Parking","Warehouse","Elevator","Address"]])
Y_real_train = np.asanyarray(train["Price"])

3. 正确调用curve_fit

必须提供初始参数p0帮助拟合算法收敛,尤其是Sigmoid拟合,初始值对结果影响较大:

多元线性拟合调用

from scipy.optimize import curve_fit

# 线性拟合初始参数设为全1
p0_linear = [1, 1, 1, 1, 1, 1]
popt_linear, pcov_linear = curve_fit(Multiple_f, X_train, Y_real_train, p0=p0_linear)
print("线性拟合参数:", popt_linear)

Sigmoid拟合调用

# 基于线性拟合结果生成Sigmoid初始参数,提升收敛性
X_linear = (popt_linear[0]*X_train[:,0] + popt_linear[1]*X_train[:,1] + 
            popt_linear[2]*X_train[:,2] + popt_linear[3]*X_train[:,3] + 
            popt_linear[4]*X_train[:,4] + popt_linear[5]*X_train[:,5])
p0_sigmoid = [0.0001, np.mean(X_linear)] + list(popt_linear)
popt_sigmoid, pcov_sigmoid = curve_fit(Multiple_Sigmoid_f, X_train, Y_real_train, p0=p0_sigmoid)
print("Sigmoid拟合参数:", popt_sigmoid)

4. 测试拟合效果

用测试集验证拟合结果:

X_test = np.asanyarray(test[["Area","Room","Parking","Warehouse","Elevator","Address"]])
Y_real_test = np.asanyarray(test["Price"])

# 线性拟合预测
Y_pred_linear = Multiple_f(X_test, *popt_linear)
# Sigmoid拟合预测
Y_pred_sigmoid = Multiple_Sigmoid_f(X_test, *popt_sigmoid)

# 打印前5组对比结果
print("真实值 | 线性预测值 | Sigmoid预测值")
for y_true, y_lin, y_sig in zip(Y_real_test[:5], Y_pred_linear[:5], Y_pred_sigmoid[:5]):
    print(f"{y_true:.2f} | {y_lin:.2f} | {y_sig:.2f}")

关键优化说明

  • Sigmoid函数的值域是(0,1),但原始Price为较大数值(20000-79000),直接拟合会导致效果极差。建议先对Price做归一化处理(如除以最大值缩放到(0,1)区间),拟合后再反归一化得到实际价格:
# 归一化训练集标签
Y_max = Y_real_train.max()
Y_train_norm = Y_real_train / Y_max

# 用归一化数据拟合Sigmoid
popt_sigmoid, pcov_sigmoid = curve_fit(Multiple_Sigmoid_f, X_train, Y_train_norm, p0=p0_sigmoid)

# 预测后反归一化得到实际价格
Y_pred_sigmoid = Multiple_Sigmoid_f(X_test, *popt_sigmoid) * Y_max

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:10:54