我有一个数据集,包含1125行和64列。前554行属于一个类别,其余行属于另一个类别。目标函数
需要在R_1和R_2的条件下最小化,其中R_1和R_2都是行向量(1 x 64)。x_i和x_l是数据矩阵中的行。我试图使用优化工具箱来最小化这个目标函数,但我在尝试将目标函数转换为所需形式时遇到了错误。这是我目前的代码
data = xlsread('data.xlsx');dat1 = data(1:554,:);dat2 = data(555:1125,:);f1 = @(x) 0;f2 = @(x) 0;%% 对于标记为0的数字for i = 1:554 f1 = @(x) f1 + (dat1(i,:) - x(1)).^2;end%% 对于标记为1的数字for j = 1:571 f2 = @(x) f2 + (dat2(j,:) - x(2)).^2;end%% 最终的目标函数f = @(x) 1/554*f1 + 1/571*f2;%%x = fminunc(f);
请指导我如何在Matlab中正确构建这种类型的目标函数
回答:
你的代码没有任何意义。以下是一些问题
f1 = @(x) 0;
和f2 = @(x) 0
定义了总是返回零的匿名函数。这有什么用意?- 对
f1
、f2
、f
的每次后续定义都试图对匿名函数进行算术运算。你的期望是什么? x = fminunc(f);
缺少一个参数,它还需要一个初始猜测。这不仅是为了初始化算法,也是为了让fminunc
知道传递给f
的输入应该具有的维度。
对于你的情况,f
应该定义为传递给它的值一半指的是R1
,另一半指的是R2
。例如,定义如下
l2_sq = @(x) sum(x.^2,2); % 返回每行x的norm(x,2)^2f1 = @(R1) sum(l2_sq(bsxfun(@minus, dat1, R1)));f2 = @(R2) sum(l2_sq(bsxfun(@minus, dat2, R2)));f3 = @(R1,R2) -10 * norm(R1-R2,1);f = @(R) f1(R(1:64)) + f2(R(65:128)) + f3(R(1:64), R(65:128));
由于组合的R
向量有128个元素,我们需要生成一个包含128个元素的初始猜测。在这种情况下,我们可以使用随机高斯噪声
R0 = randn(1,128);
最后,调用fminunc
如下
Rhat = fminunc(f, R0);R1 = Rhat(1:64);R2 = Rhat(65:128);
其中R1
和R2
是优化后的值。
注意 在MATLAB 2016b及更新版本中,隐式扩展允许你用更高效的dat1 - R1
替换bsxfun(@minus, dat1, R1)
。对bsxfun(@minus, dat2, R2)
同样适用。