|
|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
TITLE:: FluidUMAP
|
|
|
|
|
summary:: Dimensionality Reduction with Uniform Manifold Approximation and Projection
|
|
|
|
|
categories:: Dimensionality Reduction, Data Processing
|
|
|
|
|
related:: Classes/FluidMDS, Classes/FluidDataSet
|
|
|
|
|
related:: Classes/FluidMDS, Classes/FluidPCA, Classes/FluidDataSet
|
|
|
|
|
|
|
|
|
|
DESCRIPTION::
|
|
|
|
|
|
|
|
|
|
@ -53,7 +53,7 @@ code::
|
|
|
|
|
~normalized = FluidDataSet(s);
|
|
|
|
|
~standardizer = FluidStandardize(s);
|
|
|
|
|
~normalizer = FluidNormalize(s);
|
|
|
|
|
~umap = FluidUMAP(s).numDimensions_(2).numNeighbours_(5).minDist_(0.2).iterations_(50). learnRate_(0.2).batchSize_(50);
|
|
|
|
|
~umap = FluidUMAP(s).numDimensions_(2).numNeighbours_(5).minDist_(0.2).iterations_(50).learnRate_(0.2);
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -78,15 +78,15 @@ code::
|
|
|
|
|
|
|
|
|
|
//Visualise the 2D projection of our original 4D data
|
|
|
|
|
(
|
|
|
|
|
w = Window("scatter", Rect(128, 64, 200, 200));
|
|
|
|
|
w = Window("a perspective", Rect(128, 64, 200, 200));
|
|
|
|
|
w.drawFunc = {
|
|
|
|
|
Pen.use {
|
|
|
|
|
~normalizedDict.keysValuesDo{|key, val|
|
|
|
|
|
Pen.use {
|
|
|
|
|
~normalizedDict.keysValuesDo{|key, val|
|
|
|
|
|
Pen.fillColor = Color.new(~colours[key.asSymbol][0], ~colours[key.asSymbol][1],~colours[key.asSymbol][2]);
|
|
|
|
|
Pen.fillOval(Rect((val[0] * 200), (val[1] * 200), 5, 5));
|
|
|
|
|
~colours[key.asSymbol].flat.postln;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
~colours[key.asSymbol].flat;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
w.refresh;
|
|
|
|
|
w.front;
|
|
|
|
|
@ -95,5 +95,75 @@ w.front;
|
|
|
|
|
//play with parameters
|
|
|
|
|
~umap.numNeighbours = 10;
|
|
|
|
|
~umap.minDist =5;
|
|
|
|
|
~umap.batchSize = 10;
|
|
|
|
|
|
|
|
|
|
//rerun the UMAP
|
|
|
|
|
~umap.fitTransform(~standardized,~reduced,action:{"Finished UMAP".postln});
|
|
|
|
|
|
|
|
|
|
//draw to compare
|
|
|
|
|
(
|
|
|
|
|
~normalizer.fitTransform(~reduced,~normalized,action:{
|
|
|
|
|
"Normalized Output".postln;
|
|
|
|
|
~normalized.dump{|x|
|
|
|
|
|
~normalizedDict = x["data"];
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
w = Window("another perspective", Rect(328, 64, 200, 200));
|
|
|
|
|
w.drawFunc = {
|
|
|
|
|
Pen.use {
|
|
|
|
|
~normalizedDict.keysValuesDo{|key, val|
|
|
|
|
|
Pen.fillColor = Color.new(~colours[key.asSymbol][0], ~colours[key.asSymbol][1],~colours[key.asSymbol][2]);
|
|
|
|
|
Pen.fillOval(Rect((val[0] * 200), (val[1] * 200), 5, 5));
|
|
|
|
|
~colours[key.asSymbol].flat;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
w.refresh;
|
|
|
|
|
w.front;
|
|
|
|
|
|
|
|
|
|
}.defer;
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// now run new random points on the same training material. Colours should be scattered around the same space (BUT THEY DON'T RIGHT NOW)
|
|
|
|
|
|
|
|
|
|
~newDS = FluidDataSet(s);
|
|
|
|
|
~colours2 = Dictionary.newFrom(400.collect{|i|[("entry"++i).asSymbol, 3.collect{1.0.rand}]}.flatten(1));
|
|
|
|
|
~newDS.load(Dictionary.newFrom([\cols, 3, \data, ~colours2]));
|
|
|
|
|
|
|
|
|
|
//we need to standardize to the same space
|
|
|
|
|
~newDSstan = FluidDataSet(s);
|
|
|
|
|
~standardizer.transform(~newDS, ~newDSstan);
|
|
|
|
|
|
|
|
|
|
//then we can run the umap
|
|
|
|
|
~newDSmap = FluidDataSet(s);
|
|
|
|
|
~umap.transform(~newDSstan, ~newDSmap);
|
|
|
|
|
|
|
|
|
|
//then we can draw and look
|
|
|
|
|
(
|
|
|
|
|
~normalizer.transform(~newDSmap,~normalized,action:{
|
|
|
|
|
"Normalized Output".postln;
|
|
|
|
|
~normalized.dump{|x|
|
|
|
|
|
~normalizedDict = x["data"];
|
|
|
|
|
{
|
|
|
|
|
w = Window("new material", Rect(528, 64, 200, 200));
|
|
|
|
|
w.drawFunc = {
|
|
|
|
|
Pen.use {
|
|
|
|
|
~normalizedDict.keysValuesDo{|key, val|
|
|
|
|
|
Pen.fillColor = Color.new(~colours2[key.asSymbol][0], ~colours2[key.asSymbol][1],~colours2[key.asSymbol][2]);
|
|
|
|
|
Pen.fillOval(Rect((val[0] * 200), (val[1] * 200), 5, 5));
|
|
|
|
|
~colours2[key.asSymbol].flat;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
w.refresh;
|
|
|
|
|
w.front;
|
|
|
|
|
}.defer;
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
//same process as above in 2 passes maybe?
|
|
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|