Python Scipy&;优化:最小化示例,如何添加约束?

Python Scipy&;优化:最小化示例,如何添加约束?,python,scipy,Python,Scipy,我有一个数据集,我想用最小二乘法找到一个混合高斯模型 代码如下所示: from sklearn.neighbors import KernelDensity kde = KernelDensity().fit(sample) def gaussian_2d(x,y,meanx,meany,sigx,sigy,rho): # rho <= 1 part1 = 1/(2*np.pi*sigx*sigy*sqrt(1-0.5**2)) part2 = -1/2*(1-r

我有一个数据集,我想用最小二乘法找到一个混合高斯模型

代码如下所示:

from sklearn.neighbors import KernelDensity
kde = KernelDensity().fit(sample)

def gaussian_2d(x,y,meanx,meany,sigx,sigy,rho):
    # rho <= 1
    part1 = 1/(2*np.pi*sigx*sigy*sqrt(1-0.5**2))
    part2 = -1/2*(1-rho**2)
    part3 = (((x-meanx)/sigx)**2-2*rho*(x-meanx)*(y-meany)/(sigx*sigy)+((y-meany)/sigy)**2)
    return part1*exp(part2*part3)

def square_error(f1,f2, u1,v1,sigu1,sigv1,rho1, u2,v2,sigu2,sigv2,rho2, u3,v3,sigu3,sigv3,rho3):
    # 1. Generate Mixed Gaussian Model
    def gaussian1(x,y):
        return gaussian_2d(x,y,u1,v1,sigu1,sigv1,rho1)
    def gaussian2(x,y):
        return gaussian_2d(x,y,u2,v2,sigu2,sigv2,rho2)
    def gaussian3(x,y):
        return gaussian_2d(x,y,u3,v3,sigu3,sigv3,rho3)
    mixed_model = f1*gaussian1(x,y)+f2*gaussian2(x,y)+(1-f1-f2)*gaussian3(x,y)
    # 2. Calculate the sum of square error
    sum_error = 0
    for point in sample:
        error = (exp(mixed_model(point)) - exp(kde.score(point)))**2
        sum_error += error
    return sum_error

# How can I add constraints:
# f1+f2 <= 1
# rho1,2,3 <= 1
result = sp.optimize.minimize(square_error)

但是它给了我
TypeError:square_error()正好接受了17个参数(1个给定)
,有什么问题吗?

如果解算器支持,你只能添加边界,所以只适用于
method='L-BFGS-B'
TNC
SLSQP

边界通过长度与参数数量对应的
(min,max)
元组序列传递。使用3个参数进行拟合的示例如下:

result = sp.optimize.minimize(
                        square_error,
                        method='L-BFGS-B',
                        bounds=[(0., 5.), (None, 1.e4), (None, None)])
这里,
None
对应于no-bound。
恐怕对参数组合的约束,如f1+f2
恐怕对参数组合的约束,如f1+f2,您能提供链接吗?我指的是包含在
scipy.minimize
中的解算器。请看一下
约束
关键字。OP试图定义约束而不是简单的边界。谢谢你指出这一点,我恐怕我误解了OP。我会相应地更新我的答案。同时,请查看一个很好的答案。对于
np.随机.多变量_normal
,我需要确切的概率密度值,模块似乎只提供
样本
?可能的
result = sp.optimize.minimize(
                        square_error,
                        method='L-BFGS-B',
                        bounds=[(0., 5.), (None, 1.e4), (None, None)])
def square_error(f1,f2, other_args):
    if f1+f2 <= 1:
        return np.inf
    # rest of the cost function