如何使用SciPy.optimize求解机器学习模型逆预测问题
代码存在的核心问题
你的反推逻辑无法正常运行,是几个明确的编码和逻辑错误导致的:
- 缺失依赖导入:代码调用了
train_test_split却未从sklearn.model_selection导入该方法,且模型拟合时直接传入全量X、y,前面的数据集拆分逻辑完全未生效。 - 优化目标逻辑完全错误:传入
minimize的匿名函数写死了输入值[[12,8]],返回值和待优化的变量x完全无关,优化器没有任何调整狗、猫数量的方向依据。你的需求本质是找一组[狗数,猫数]让模型预测的老鼠数等于目标值,因此目标函数必须以x为输入,最小化预测值和目标值的残差。 - 参数配置不合理:设置的变量边界
[(100,500), (100,150)]完全超出训练集覆盖的数值范围(训练集狗的数量最大值仅为19),树模型在训练分布外的预测结果无参考价值;eps参数设为弧度值也和当前数值优化场景不匹配。
修正后的可运行代码
以下是修正后的示例,以「反推老鼠数量为50时对应的狗、猫数量」为例:
from scipy.optimize import minimize from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split import numpy as np # 原始数据集 n_dogs = [10, 5, 5, 2, 19, 12, 1, 2] n_cats = [5, 100, 5, 3, 1000, 0, 1, 2] n_rats = [100, 0, 50, 30, 0, 1000, 10, 5] X = np.array([n_dogs, n_cats]).T y = np.array(n_rats) # 拆分数据集后用训练集拟合模型 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) model = RandomForestRegressor() model.fit(X_train, y_train) # 目标配置:需要达到的老鼠数量 target_rats = 50 # 边界调整到训练集覆盖的数值范围内,避免外推误差 bnds = [(1, 20), (0, 1000)] # 初始值设置在边界范围内 x0 = [5, 50] # 目标函数:最小化预测老鼠数和目标老鼠数的平方差 def objective(x): pred_rats = model.predict([x])[0] return (pred_rats - target_rats) ** 2 res = minimize(objective, x0, method='SLSQP', bounds=bnds, options={'eps': 1e-3}) print(res) # 输出反推结果 print(f"反推得到的狗数量:{res.x[0]:.1f},猫数量:{res.x[1]:.1f}") print(f"该组合下模型预测的老鼠数量:{model.predict([res.x])[0]:.1f}")
补充说明
- 随机森林属于分段常数的非光滑模型,
SLSQP这类基于梯度的优化器容易陷入局部最优,如果对结果精度要求高,可以替换为全局优化方法比如scipy.optimize.differential_evolution。 - 树模型仅在训练数据覆盖的数值范围内插值预测可靠,不要在训练分布外做反推。
内容的提问来源于stack exchange,提问作者Enyrb
相关产品推荐
相关产品推荐

