1

我有一个混合整数问题。我需要最小化一个函数,这是一个加权最小二乘回归,权重取决于回归(迭代地重新加权最小二乘)。7 个参数定义了我的分段回归。我需要在第一个猜测附近找到一个局部最小值。

我试图用 gekko 写这个问题,但不知何故我发现它很难实现。经过多次尝试,我停在“负自由度”。

无论如何,我决定蛮力解决这个问题。它有效,但速度很慢。我在 7D 中围绕我的工作点构建一个立方体(itertools),并计算 3^7 点中的每个点的加权平方误差。我对每个维度都有边界,有时我的工作点位于我的 7D 域的一个面上。从技术上讲,我有 2^p * 3^(7-p) 点。我现在有一个所有值的列表,找到最小值,将我的工作点移到那里并重新开始构建一个立方体,不包括我在前面的循环步骤中已经计算的所有点。

现在我想通过计算我的工作点的梯度来加速它并更快地移动(在我的循环中跳过一两步)。np.gradient 需要一个 7d 数组才能正确执行。

给定一个点,以及围绕该点的 7 个范围,如何以有效的方式制作 7D 数组?如何用我的函数值制作这个数组的图像?

请不要说 7 for 循环。

4

1 回答 1

1

无论您的函数是否是矢量化的,您都可以使用以下方法np.indices

base_grid = np.indices(7 * (3,), sparse=False) - 1

-1, 0, 1这会产生您需要的所有组合的数组。np.meshgrid做了类似的事情,但是数组将被分成一个元组,这很不方便。

在每次迭代中,您使用您的步长(比例)和偏移量修改网格:

current_grid = base_grid * scale + offset

如果你的函数是向量化的,你直接调用它,网格就是7个3x3x3x3x3x3x3数组。如果它接受七个输入,只需使用星形扩展。

如果你的函数没有向量化,你仍然可以在一个循环中遍历相应的元素,而不是七个循环,使用np.nditer

with np.nditer([current_grid, None],
        op_axes=[list(range(1, current_grid.ndim)), None]) as it:
    for x, y in it:
        y[:] = f(*x)
    j = it.operands[1]
于 2021-01-22T16:18:18.740 回答