自己組織化マップにおけるカラーバーの作成方法

2 views (last 30 days)
Naro
Naro on 14 Feb 2022
Commented: Atsushi Ueno on 14 Feb 2022
現在、ドキュメンテーションの「アヤメのクラスタリング」を基に自己組織化マップの作成を試みており、plotsomplanes関数から各項目における重み分布の可視化を実施しています。
しかし、挿入→カラーバーによって出力されるカラー分布はマップ上のカラー分布と対応していないようです。
重み配列は確認できるので、関数内部で色分けが為されている思われますが、マップ上のカラー分布に対応したカラーバーの取得方法がわかりません。
ご存じの方がいればご回答いただけますと嬉しいです。
以下は使用している関数コ―ドです。
-----------------------------------------------------------------
function y = norm_som(x)
x = normalize(x,'range')
x = table2array(x);
x = x.';
net = selforgmap([27 27],1000,3,'hextop','dist');
net = train(net,x);
view(net);
y = net(x);
classes = vec2ind(y);
end
-----------------------------------------------------------------

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 14 Feb 2022
【結論】多分これで表示できると思います。動作確認できないplotsomplanes関数の代わりにsurf関数を表示しています
x = iris_dataset;
net = selforgmap([5 5]);
net = train(net,x);
plotData = plotsomplanes(net); % 代わりにsurf(peaks);を表示
R = [0:0.1:1 ones(1,9)]'; % 数値はRGB各20個でカラーマップを作成しています
G = [zeros(1,9) 0:0.1:1]'; % 数値の数を増やせばより滑らかなカラーマップになります
B = zeros(1,20)';
colormap(plotData.axis,[R G B]); % 代わりにcolormap([R G B]);を表示
colorbar(plotData.axis); % 代わりにcolorbar();を表示
【plotsomplanes関数で用いられるカラーマップの調査】
% 最も負の接続は黒、ゼロ接続は赤、最も強い正の接続は黄色で示される。
これを裏付ける為、色の設定に着目してplotsomplanes関数(一番下参照)の一部を抽出すると、上記の様にカラーマップを使わずカスタム色でパッチの色を設定しています。黒⇒赤⇒黄はカラーマップの'hot'に近いですが白色を含みません。これを真似てカラーマップを作成すると一番上の結論の様になります。
% z = fill(a,pos(1,ii)+shapex,pos(2,ii)+shapey,[1 1 1]); % パッチを作成
% set(z,'EdgeColor','none'); % パッチのエッジ色は無し
% plotData.Patches{k}(ii) = z;
% red = min(1,level*2);
% green = max(0,level*2-1);
% blue = 0; % level=0,R0G0B0:黒、level=0.5,R1G0B0:赤、level=1,R1G1B0:黄
% set(plotData.pathces{i}(j),'FaceColor',[red green blue]);% パッチの色設定
type plotsomplanes
function plotData = plotsomplanes(param,graphicsAdapter,plotData,net) %#ok<*INUSL> % plotsomplanes Internal function for plotsomplanes % % This function allows creation of the plot created by the user-facing % function plotsomplanes(), but specifying a figure handle as the parent. % % Arguments to the internal function are handled differently to the % user-facing function. % % The arguments provided to this function are: % - param: unused % - graphicsAdapter: an nnet.internal.plot.GraphicsAdapter wrapping the % figure. % - plotData: a struct whose fields are various graphics handles (e.g. line % objects). Those handles will be updated with the new data. If no % plotData struct is provided, one will be created. % - net: a Self-Organizing Map network. % Copyright 2021 The MathWorks, Inc. if isempty(plotData) plotData = setup_plot(graphicsAdapter); end numInputs = net.inputs{1}.processedSize; numNeurons = net.layers{1}.size; topologyFcn = net.layers{1}.topologyFcn; if strcmp(topologyFcn,'gridtop') shapex = [-1 1 1 -1]*0.5; shapey = [1 1 -1 -1]*0.5; dx = 1; dy = 1; elseif strcmp(topologyFcn,'hextop') z = sqrt(0.75); shapex = [-1 0 1 1 0 -1]*0.5; shapey = [1 2 1 -1 -2 -1]*(z/3); dx = 1; dy = sqrt(0.75); end if (plotData.numInputs ~= numInputs) || (plotData.numNeurons ~= numNeurons) ... || ~strcmp(plotData.topologyFcn,topologyFcn) graphicsAdapter.setNextPlotReplace(); plotData.numInputs = numInputs; plotData.numNeurons = numNeurons; plotData.topologyFcn = topologyFcn; pos = net.layers{1}.positions; dim = net.layers{1}.dimensions; numDimensions = length(dim); if (numDimensions == 1) dim1 = dim(1); dim2 = 1; pos = [pos; zeros(1,size(pos,2))]; elseif (numDimensions > 2) pos = pos(1:2,:); dim1 = dim(1); dim2 = dim(2); else dim1 = dim(1); dim2 = dim(2); end plotcols = ceil(sqrt(numInputs)); plotrows = ceil(numInputs/plotcols); plotData.patches = cell(numInputs); for i=1:plotrows for j=1:plotcols k = (i-1)*plotcols+j; if (k<=numInputs) a = graphicsAdapter.subplot(plotrows,plotcols,k); cla(a); set(a,... 'DataAspectRatio',[1 1 1], ... 'Box','on',... 'Color',[1 1 1]*0.5) graphicsAdapter.holdOn(a); plotData.patches{k} = zeros(1,numNeurons); for ii=1:numNeurons z = fill(a,pos(1,ii)+shapex,pos(2,ii)+shapey,[1 1 1]); set(z,'EdgeColor','none'); plotData.patches{k}(ii) = z; end set(a,'XLim',[-1 (dim1-0.5)*dx + 1]); set(a,'YLim',[-1 (dim2-0.5)*dy + 0.5]); title(a,getString(message('nnet:nnplots:PlotsomplanesWeightsTitle', num2str(k)))); end end end screenSize = get(0,'ScreenSize'); screenSize = screenSize(3:4); windowSize = 700 * [1 (plotrows/plotcols)]; pos = [(screenSize-windowSize)/2 windowSize]; graphicsAdapter.setWindowPosition(pos); end iw = net.IW{1,1}; %min_neg = min(0,min(iw,[],1)); %max_pos = max(0,max(iw,[],1)); mn = min(iw,[],1); mx = max(iw,[],1); rng = mx-mn; for i=1:numInputs for j=1:numNeurons level = net.IW{1,1}(j,i); %if level<0, level = -level/min_neg(i); end %if level>0, level = level/max_pos(i); end %red = min(1,max(0,level)*2); % positive %blue = -max(-1,min(0,level)*2); % negative %green = max(0,abs(level)*2-1); % very positive/negative level = (level-mn(i))/rng(i); red = min(1,level*2); green = max(0,level*2-1); blue = 0; c = [red green blue]; set(plotData.patches{i}(j),'FaceColor',c); end end end function plotData = setup_plot(graphicsAdapter) plotData.axis = graphicsAdapter.subplot(1,1,1); plotData.numInputs = 0; plotData.numNeurons = 0; plotData.topologyFcn = ''; end
  1 Comment
Atsushi Ueno
Atsushi Ueno on 14 Feb 2022
最新のplotsomplanes関数内部を良く見ると以前は異なる配色(red,green,blue要素を全て使う)でしたが、コメントアウトされて今はblue要素がずっと0のままになっています。理由は良くわかりません(コメント読んでない:p)

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!