Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python lmfit最小化失败,返回ValueError:数组太大_Python_Optimization_Lmfit - Fatal编程技术网

Python lmfit最小化失败,返回ValueError:数组太大

Python lmfit最小化失败,返回ValueError:数组太大,python,optimization,lmfit,Python,Optimization,Lmfit,我试图使用“暴力”方法最小化20个变量的函数。它因一个神秘的错误而失败。以下是完整的代码: import random import numpy as np import lmfit def progress_update(params, iter, resid, *args, **kws): pass #print(resid) def score(params, data = None): parvals = params.valuesdict() M =

我试图使用“暴力”方法最小化20个变量的函数。它因一个神秘的错误而失败。以下是完整的代码:

import random
import numpy as np
import lmfit

def progress_update(params, iter, resid, *args, **kws):
    pass
    #print(resid)

def score(params, data = None):
    parvals = params.valuesdict()
    M = data
    X_params = []
    Y_params = []
    for i in range(M.shape[0]):
        X_params.append(parvals['x'+str(i)])
    for j in range(M.shape[1]):
        Y_params.append(parvals['y'+str(i)])
    return diff(M, X_params, Y_params)


def diff(M, X_params, Y_params):
    total = 0
    for i in range(M.shape[0]):
        for j in range(M.shape[1]):
            total += abs(M[i,j] - (X_params[i] - Y_params[j])**2)
    return total

dim = 10
random.seed(0)
M = np.empty((dim, dim))

for i in range(M.shape[0]):
    for j in range(M.shape[1]):
        M[i,j] = i*random.random()+j**2

params = lmfit.Parameters()
for i in range(M.shape[0]):
    params.add('x'+str(i), value=random.random()*10, min=0, max=10)
for j in range(M.shape[1]):
    params.add('y'+str(j), value=random.random()*10, min=0, max=10)

result = lmfit.minimize(score, params, method='brute', kws={'data': M},  iter_cb=progress_update)
但是,这在以下情况下失败:

ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.

是什么导致此问题?

是什么导致此问题

你不能强行解决高维问题,因为强行解决方法(时间和内存,如果实现得很幼稚的话)

更直接地说,lmfit在引擎盖下使用numpy(*),它的最大大小是它可以分配多少数据。您的初始数据结构不是太大(10x10),它是导致问题的蛮力所需的组合表

如果您愿意破解实现,可以切换到稀疏内存结构。但这并不能解决数学问题

关于高维优化

尝试不同的最小化方法,但要注意:在高维空间中全局最小化是非常困难的。像/这样的“局部极小”方法可能更有效

我不想悲观,但一般来说,高级优化是非常困难的,我担心这超出了所谓的问题的范围

切实可行的备选方案

梯度下降比一般优化更适合机器学习;覆盖范围,以及。我从那里开始。这是可能的,但不是必须的

从scipy关于无约束最小化的文档中,您有许多选择:

方法Nelder-Mead使用单纯形算法[],[]。该算法 在许多应用中都是健壮的。然而,如果 导数可以信任,其他算法使用第一个和/或 二阶导数信息可能是更好的选择 一般表现

方法Powell是对Powell方法[]的修改,该方法是 共轭方向法。它执行顺序一维搜索 沿方向集的每个向量的最小化(图中的direc场) 选项和信息),它在主 最小化循环。函数不需要是可微的,并且 衍生品被采用

还有更多基于导数的方法可用。(一般来说,当你有衍生工具信息可用时,你会做得更好。)


脚注/查看源代码

(*)此处的实际错误,基于numpy实现。引述:

`if (npy_mul_with_overflow_intp(&nbytes, nbytes, dim)) {
    PyErr_SetString(PyExc_ValueError,
        "array is too big; `arr.size * arr.dtype.itemsize` "
        "is larger than the maximum possible size.");
    Py_DECREF(descr);
    return NULL;`

非常感谢。那么它能应付的最大规模是多少呢?我还发布了一个关于全局优化器失败的相关问题。高阿努什,编辑了一点,我会补充一点。这几乎可以肯定是依赖于实现的,如果在引擎盖下使用稀疏/迭代器结构,这一点会大大提高。一句话:网格搜索在这里不是一个好主意。@en_Knight说lmfit“在引擎盖下使用熊猫”是不正确的。事实并非如此。与Python一样,它应该只受物理内存的限制。但是en_Knight是正确的,这个错误(来自numpy)的产生是因为你要求一个20维的网格,每个网格有10个步骤。这是10*20次功能评估。如果每个函数评估需要1毫秒,那么总运行时间将为30亿年。蛮力方法适用于2个或3个或可能4个可变参数。@en_Knight为方便起见,它可以处理pandas.Series中的数据,这就是它导入pandas的原因。但是这些被转换为numpy数组。在引擎盖下,这一切都是裸体和肌肉,而不是熊猫。Pandas未用于实际计算的任何部分,与此处的错误消息无关。当然,用户的问题是因为暴力方法不能扩展到高维(变量)问题,但这不是pandas或numpy的错。再说一次,这个问题是可并行化的,所以如果你有10亿个计算节点,只需要3年就可以解决;)@再次感谢您的投入。在答案中,我将pandas切换到numpy,并将指针保持在实际异常的位置。我同意根本问题是算法——我将尝试重构答案以使其更清晰。暴力中缺乏可伸缩性的原因有两个:1)时间复杂性,这不是用户遇到的实际问题(它根本没有运行,更不用说多年了)。2) 是内存复杂性,可以通过强制numpy使用稀疏矩阵而不是密集矩阵或使用迭代器来解决。。。