我在MATLAB中编写了一个小程序,使用TU游戏的多线性扩展来计算Shapley值 。但是,我运行MATLAB的符号数学工具箱时遇到了 问题。在 该程序我不得不集成一组函数来获得Shapley值 。然而,MATLAB程序内我不能使用 的INT()命令什么是matlabFunction的好替代品?
Error using sym/subsindex (line 663) Ivalid indexing or function definition. When defining a function, ensure that the body of the function is a SYM object. When indexing, the input must be numeric, logical or ':'.
Error in ShapleyValueML (line 65)shv(jj)=int(dfy,0,1)
因此我必须使用积分()来代替。在这种情况下,I 需要使用matlabFunction()将该组表达式转换为MATLAB函数句柄 。但是,在我访问此命令的所有Linux机器上(MATLAB R2014a) 不起作用(请参阅下面的讨论)。 作为一种解决方法,MATLAB程序将函数集 返回到当前工作空间中,使用int()命令可以计算出Shapley值 。
为了让讨论更加具体,让我们先考虑一下这个小的程序 。
function [shv,F,dfm]=ShapleyValueML(v)
N=length(v);
[~, n]=log2(N);
S=1:N;
int=0:-1:1-n;
mat=(rem(floor(S(:)*pow2(int)),2)==1);
cmat=(rem(floor(S(:)*pow2(int)),2)==0);
x=sym('x',[1 n]);
mx=1-x;
y = sym('y');
vy=ones(1,n)*y;
F=0;
shv=zeros(1,n);
dfm=cell(1,n);
for ss=1:N
pd1=x(mat(ss,:));
pd2=mx(cmat(ss,:));
pd=prod(pd1)*prod(pd2)*v(ss);
F=pd+F;
end
F=expand(F);
for jj=1:n
dF=diff(F,x(jj));
dfy=subs(dF,x,vy);
%% Does not work!! MATLAB bug???
% mf=matlabFunction(dfy);
% shv(jj)=integral(mf,0,1);
%%
%% The best would be to use:
%%
% shv(jj)=int(dfy,0,1)
%% but it cannot be used inside a program.
dfm{jj}=dfy;
end
end
注释的部分是不里面 程序的工作部件,但需要计算与该程序,这是它的目的Shapley值 。我测试了这个程序 多达12名球员,并且我能够通过两步程序成功计算出Shapley值。因此,上述程序 正确指出了所考虑的问题。为了更好地了解上述程序的这两步程序和功能 ,让我们专注于三人游戏。 的联盟的值由下面的数据阵列
>> v = [0,0,90,0,100,120,220];
注意联盟进行排序根据其独特 整数表示给出。游戏定义后,我们现在可以用 来计算 的多线性扩展和偏导数的集合 上面的程序,但不是Shapley的值。
>> [shv,F,dfm]=ShapleyValueML(v);
所述一组偏导数的积分运行在单位立方体的对角线 ,但我们可以设置从[X1,X2,X3] 至[Y,Y,Y]中的变量,并且集成运行从0到1。
>> for k=1:3, shv(k)=int(dfm{k},0,1);end;
一体化的解决方案是Shapley值由下式给出:
>> shv
shv =
65 75 80
检查,这确实是Shapley值可以在
>> sh_v=ShapleyValue(v)
sh_v =
65 75 80
实现的潜在功能的方式来完成
附带我的MATLAB游戏理论工具箱MatTuGames
http://www.mathworks.com/matlabcentral/fileexchange/35933-mattugames
而是用INT整合()一个也可以使用积分(), 但随后的内容就像
>> dfm{1}
ans =
- 90*y^2 + 190*y
必须matlabFunction()被改写成函数句柄。正如我上面提到的 这不适用于Linux (MATLAB R2013a,R2013b,R2014a)。看到这让我们尝试重现 的例子
>> syms x y
>> r = sqrt(x^2 + y^2);
从文档的URL:
这应该给
ht =
@(x,y)tanh(sqrt(x.^2+y.^2))
,但我得到
>> ht = matlabFunction(tanh(r))
Cell contents reference from a non-cell array object.
Error in vectorize (line 15)
c = cells{i};
Error in sym/matlabFunction>mup2mat (line 319)
res = vectorize(res(2:end-1)); % remove quotes
Error in sym/matlabFunction>mup2matcell (line 304)
r = mup2mat(c{1});
Error in sym/matlabFunction (line 123)
body = mup2matcell(funs);
现在,这里是我的问题:存在有一个替代过程 从
>> dfm{1}
ans =
- 90*y^2 + 190*y
得到一个函数处理
>> [email protected](y) (- 90.*y.^2 + 190.*y)
df =
@(y)(-90.*y.^2+190.*y)
由
>> integral(df,0,1)
ans =
65
它集成或者换种方式。是否有另一种方法可用于 改变乘法运算*到元素乘法运算*和功率运算^到元素方式的功率。
当然,任何关于上述MATLAB程序 的改进建议都非常感谢。
@Amro非常感谢。你是对的!!我不明白这个失败。尽管如此,遗憾的是,当变量/函数被内建函数遮蔽时,MATLAB不会显示像Mathematica这样的警告。 – 2014-09-28 15:42:37
是的,那个错误信息有点神秘。我不得不通过调试器并检查调用堆栈来弄清楚发生了什么。 – Amro 2014-09-28 15:48:56