No science, No life.

もっと科学を身近に

非線形次元削減法 Isomap でスイスロールを開いてみた

多様体学習 (manifold learning) による非線形次元削減法 Isomap を使って、スイスロール風の 3 次元データを開いて 2 次元にしてみました。MATLB で書いています。

自分で適当にスイスロールを作り、

% swiss roll data
npt= 1000;
t = linspace(0,2*pi*1.5,npt);
r = linspace(1,10,npt);
x = r .* cos(t);
y = r .* sin(t);
z = rand(1,npt)*6;
c = linspace(0,1,npt);

% plot swiss roll
figure(1); clf
subplot(121)
scatter3(x,y,z,10,c,'filled')
axis equal; view([50,50])

距離行列 (distance matrix) を計算し、

% distance matrix
X = [x' y' z'];
D = pdist2(X,X);

いざ、Isomap に放り込みます。

% Isomap
n_fcn = 'k';
n_size = 20;
options.dims = 1:5;
options.display = 0;
[Iso,R,E] = Isomap(D, n_fcn, n_size, options); 

% plot
x2 = Iso.coords{2}(1,:);
y2 = Iso.coords{2}(2,:);
subplot(122)
scatter(x2,y2,10,c,'filled')

良さそうな感じに開くことができました ↓ 左が元のスイスロール、右が Isomap で開いた図です。n_size は近傍点の数を指定するハイパーパラメータです。これを変えると、見た目やそもそも上手く開けるかが変わります。

f:id:neocortex:20210418165721p:plain

非線形次元削減法には、他にも t-SNE や UMAP などいくつもあるので、試してみたいですね。

線形な次元削減法である主成分分析 (PCA) では、ロールを開けません。

[~,score] = pca(X);
x3 = score(:,1);
y3 = score(:,2);
figure(2); clf
scatter(x3,y3,10,c,'filled')

f:id:neocortex:20210418171118p:plain

Isomap 関数は、こちらのものを使いました ↓

jp.mathworks.com

Isomap 関数のなかの L2_distance には、こちらを拝借しました ↓

https://www.mathworks.com/matlabcentral/mlc-downloads/downloads/submissions/48196/versions/1/previews/approximate%20LE/L2_distance.m/index.html