From 84fb74f5c2be6817a461850788c27070b64fa836 Mon Sep 17 00:00:00 2001 From: Vesna Tanko Date: Mon, 3 Oct 2016 15:55:58 +0200 Subject: [PATCH] Manifold: Add methods to scripting part --- Orange/projection/manifold.py | 47 +++++++++++++++++++++++++--- Orange/tests/test_manifold.py | 58 ++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/Orange/projection/manifold.py b/Orange/projection/manifold.py index b5362c78433..250f6e8d668 100644 --- a/Orange/projection/manifold.py +++ b/Orange/projection/manifold.py @@ -3,12 +3,13 @@ from Orange.distance import SklDistance, SpearmanDistance, PearsonDistance from Orange.projection import SklProjector -__all__ = ["MDS", "Isomap", "LocallyLinearEmbedding"] +__all__ = ["MDS", "Isomap", "LocallyLinearEmbedding", "SpectralEmbedding", + "TSNE"] class MDS(SklProjector): __wraps__ = skl_manifold.MDS - name = 'mds' + name = 'MDS' def __init__(self, n_components=2, metric=True, n_init=4, max_iter=300, eps=0.001, n_jobs=1, random_state=None, @@ -46,7 +47,7 @@ class Isomap(SklProjector): name = 'isomap' def __init__(self, n_neighbors=5, n_components=2, eigen_solver='auto', - max_iter=None, path_method='auto', + tol=0, max_iter=None, path_method='auto', neighbors_algorithm='auto', preprocessors=None): super().__init__(preprocessors=preprocessors) self.params = vars() @@ -57,9 +58,47 @@ class LocallyLinearEmbedding(SklProjector): name = 'lle' def __init__(self, n_neighbors=5, n_components=2, reg=0.001, - eigen_solver='auto', tol=1e-06 , max_iter=100, + eigen_solver='auto', tol=1e-06, max_iter=100, method='standard', hessian_tol=0.0001, modified_tol=1e-12, neighbors_algorithm='auto', random_state=None, preprocessors=None): super().__init__(preprocessors=preprocessors) self.params = vars() + + +class SpectralEmbedding(SklProjector): + __wraps__ = skl_manifold.SpectralEmbedding + name = 'Spectral Embedding' + + def __init__(self, n_components=2, affinity='nearest_neighbors', gamma=None, + random_state=None, eigen_solver=None, n_neighbors=None, + preprocessors=None): + super().__init__(preprocessors=preprocessors) + self.params = vars() + + +class TSNE(SklProjector): + __wraps__ = skl_manifold.TSNE + name = 't-SNE' + + def __init__(self, n_components=2, perplexity=30.0, early_exaggeration=4.0, + learning_rate=1000.0, n_iter=1000, n_iter_without_progress=30, + min_grad_norm=1e-07, metric='euclidean', init='random', + random_state=None, method='barnes_hut', angle=0.5, + preprocessors=None): + super().__init__(preprocessors=preprocessors) + self.params = vars() + + def __call__(self, data): + if self.params['metric'] is 'precomputed': + X, Y, domain = data, None, None + else: + data = self.preprocess(data) + X, Y, domain = data.X, data.Y, data.domain + distances = SklDistance, SpearmanDistance, PearsonDistance + if isinstance(self.params['metric'], distances): + X = self.params['metric'](X) + self.params['metric'] = 'precomputed' + clf = self.fit(X, Y=Y) + clf.domain = domain + return clf diff --git a/Orange/tests/test_manifold.py b/Orange/tests/test_manifold.py index 6ebb0e610e3..cb41424bb7b 100644 --- a/Orange/tests/test_manifold.py +++ b/Orange/tests/test_manifold.py @@ -4,7 +4,8 @@ import unittest import numpy as np -from Orange.projection import MDS, Isomap +from Orange.projection import (MDS, Isomap, LocallyLinearEmbedding, + SpectralEmbedding, TSNE) from Orange.distance import Euclidean from Orange.data import Table @@ -45,3 +46,58 @@ def __isomap_test_helper(self, data, n_com): isomap_fit = isomap_fit(data) eshape = data.X.shape[0], n_com self.assertEqual(eshape, isomap_fit.embedding_.shape) + + def test_lle(self): + for i in range(1, 4): + self.__lle_test_helper(self.ionosphere, n_com=i) + + def __lle_test_helper(self, data, n_com): + lle = LocallyLinearEmbedding(n_neighbors=5, n_components=n_com) + lle = lle(data) + + ltsa = LocallyLinearEmbedding(n_neighbors=5, n_components=n_com, + method="ltsa") + ltsa = ltsa(data) + + hessian = LocallyLinearEmbedding(n_neighbors=15, n_components=n_com, + method="hessian", + eigen_solver="dense") + hessian = hessian(data) + + modified = LocallyLinearEmbedding(n_neighbors=5, n_components=n_com, + method="modified", + eigen_solver="dense") + modified = modified(data) + + self.assertEqual((data.X.shape[0], n_com), lle.embedding_.shape) + self.assertEqual((data.X.shape[0], n_com), ltsa.embedding_.shape) + self.assertEqual((data.X.shape[0], n_com), hessian.embedding_.shape) + self.assertEqual((data.X.shape[0], n_com), modified.embedding_.shape) + + def test_se(self): + for i in range(1, 4): + self.__se_test_helper(self.ionosphere, n_com=i) + + def __se_test_helper(self, data, n_com): + se = SpectralEmbedding(n_components=n_com, n_neighbors=5) + se = se(data) + self.assertEqual((data.X.shape[0], n_com), se.embedding_.shape) + + def test_tsne(self): + data = self.ionosphere[:50] + for i in range(1, 4): + self.__tsne_test_helper(data, n_com=i) + + def __tsne_test_helper(self, data, n_com): + tsne_def = TSNE(n_components=n_com, metric='euclidean') + tsne_def = tsne_def(data) + + tsne_euc = TSNE(n_components=n_com, metric=Euclidean) + tsne_euc = tsne_euc(data) + + tsne_pre = TSNE(n_components=n_com, metric='precomputed') + tsne_pre = tsne_pre(Euclidean(data)) + + self.assertEqual((data.X.shape[0], n_com), tsne_def.embedding_.shape) + self.assertEqual((data.X.shape[0], n_com), tsne_euc.embedding_.shape) + self.assertEqual((data.X.shape[0], n_com), tsne_pre.embedding_.shape)