我很擅长scipy并在python中进行数据分析。我试图解决以下正则化优化问题,不幸的是我从scipy文档中无法理解。我期待使用scipy.optimize
解决以下约束优化问题这是我希望最小化的功能:
这里A是m×n矩阵,最小化中的第一项是残差平方和,第二项是稀疏n×n矩阵W的矩阵frobenius(L2范数),第三项是相同矩阵W的L1范数。
在函数A中是m×n矩阵,最小化中的第一项是残差平方和,第二项是稀疏n×n矩阵W的矩阵frobenius(L2范数),第三项是一个是相同矩阵W的L1范数。
我想知道如何根据以下限制最小化此功能:
wj >= 0 wj,j = 0
我想使用坐标下降(或scipy.optimize提供的任何其他方法)来解决上述问题。我想如何实现这一目标,因为我不知道如何采用frobenius规范或如何调整参数beta和lambda或者scipy.optimize是否会调整并为我返回参数。关于这些问题的任何帮助将不胜感激。
提前致谢!
答案 0 :(得分:6)
m和n有多大?
以下是如何使用fmin的基本示例:
from scipy import optimize
import numpy as np
m = 5
n = 3
a = np.random.rand(m, n)
idx = np.arange(n)
def func(w, beta, lam):
w = w.reshape(n, n)
w2 = np.abs(w)
w2[idx, idx] = 0
return 0.5*((a - np.dot(a, w2))**2).sum() + lam*w2.sum() + 0.5*beta*(w2**2).sum()
w = optimize.fmin(func, np.random.rand(n*n), args=(0.1, 0.2))
w = w.reshape(n, n)
w[idx, idx] = 0
w = np.abs(w)
print w
如果你想使用坐标下降,你可以通过theano实现它。
答案 1 :(得分:3)
你的问题似乎是为cvxopt量身定做的 - http://cvxopt.org/ 特别是 http://cvxopt.org/userguide/solvers.html#problems-with-nonlinear-objectives
使用fmin可能会更慢,因为它没有利用渐变/ Hessian信息。
HYRY的答案中的代码也有一个缺点,就fmin而言,对角线W是一个变量,fmin会尝试移动W对角线值,直到它意识到它们没有做任何事情(因为目标函数将它们重置为零)。这是HYRY代码的cvxopt中的实现,它明确地强制执行零约束并使用渐变信息,警告:我无法为你的目标派生出Hessian ......你也可以仔细检查渐变:
'''CVXOPT version:'''
from numpy import *
from cvxopt import matrix, mul
''' warning: CVXOPT uses column-major order (Fortran) '''
m = 5
n = 3
n_active = (n)*(n-1)
A = matrix(random.rand(m*n),(m,n))
ids = arange(n)
beta = 0.1;
lam = 0.2;
W = matrix(zeros(n*n), (n,n));
def cvx_objective_func(w=None, z=None):
if w is None:
num_nonlinear_constraints = 0;
w_0 = matrix(1, (n_active,1), 'd');
return num_nonlinear_constraints, w_0
#main call:
'calculate objective:'
'form W matrix, warning _w is column-major order (Fortran)'
'''column-major order!'''
_w = matrix(w, (n, n-1))
for k in xrange(n):
W[k, 0:k] = _w[k, 0:k]
W[k, k+1:n] = _w[k, k:n-1]
squared_error = A - A*W
objective_value = .5 * sum( mul(squared_error,squared_error)) +\
.5* beta*sum(mul(W,W)) +\
lam * sum(abs(W));
'not sure if i calculated this right...'
_Df = -A.T*(squared_error) + beta*W + lam;
'''column-major order!'''
Df = matrix(0., (1, n*(n-1)))
for jdx in arange(n):
for idx in list(arange(0,jdx)) + list(arange(jdx+1,n)):
idx = int(idx);
jdx = int(jdx)
Df[0, jdx*(n-1) + idx] = _Df[idx, jdx]
if z is None:
return objective_value, Df
'''Also form hessian of objective+non-linear constraints
(but there are no nonlinear constraints) :
This is the trickiest part...
WARNING: H is for sure coded wrong'''
H = matrix(1., (n_active, n_active))
return objective_value, Df, H
m, w_0 = cvx_objective_func()
print cvx_objective_func(w_0)
G = -matrix(diag(ones(n_active),), (n_active,n_active))
h = matrix(0., (n_active,1), 'd')
from cvxopt import solvers
print solvers.cp(cvx_objective_func, G=G, h=h)
话虽如此,消除HYRY代码中的等式/不等式约束的技巧非常可爱