我在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