88from scipy .sparse .linalg import eigsh as arpack_eigh
99import sklearn .manifold as skl_manifold
1010
11- import openTSNE
12- import openTSNE .affinity
13- import openTSNE .initialization
14-
1511import Orange
1612from Orange .data import Table , Domain , ContinuousVariable
1713from Orange .distance import Distance , DistanceModel , Euclidean
2117__all__ = ["MDS" , "Isomap" , "LocallyLinearEmbedding" , "SpectralEmbedding" ,
2218 "TSNE" ]
2319
24- # Disable t-SNE user warnings
25- openTSNE .tsne .log .setLevel (logging .ERROR )
26- openTSNE .affinity .log .setLevel (logging .ERROR )
27-
2820
2921def torgerson (distances , n_components = 2 , eigen_solver = "auto" ):
3022 """
@@ -190,6 +182,23 @@ def __init__(self, n_components=2, affinity='nearest_neighbors', gamma=None,
190182 self .params = vars ()
191183
192184
185+ class lazy_openTSNE :
186+ """openTSNE uses numba, which is slow to load, so load it lazily."""
187+ def __getattr__ (self , item ):
188+ import sys
189+ import openTSNE
190+ import openTSNE .affinity
191+ import openTSNE .initialization
192+ if "openTSNE" in sys .modules :
193+ # Disable t-SNE user warnings
194+ openTSNE .tsne .log .setLevel (logging .ERROR )
195+ openTSNE .affinity .log .setLevel (logging .ERROR )
196+ return getattr (openTSNE , item )
197+
198+
199+ openTSNE = lazy_openTSNE ()
200+
201+
193202class TSNEModel (Projection ):
194203 """A t-SNE embedding object. Supports further optimization as well as
195204 adding new data into the existing embedding.
@@ -204,8 +213,8 @@ class TSNEModel(Projection):
204213 pre_domain : Domain
205214 Original data domain
206215 """
207- def __init__ (self , embedding : openTSNE . TSNEEmbedding , table : Table ,
208- pre_domain : Domain ):
216+ def __init__ (self , embedding , table , pre_domain ):
217+ # type: (openTSNE.TSNEEmbedding, Table, Domain) -> None
209218 transformer = TransformDomain (self )
210219
211220 def proj_variable (i ):
@@ -221,7 +230,8 @@ def proj_variable(i):
221230 class_vars = table .domain .class_vars ,
222231 metas = table .domain .metas )
223232
224- def transform (self , X : np .ndarray , learning_rate = 1 , ** kwargs ) -> openTSNE .PartialTSNEEmbedding :
233+ def transform (self , X , learning_rate = 1 , ** kwargs ):
234+ # type: (np.ndarray, int, ...) -> openTSNE.PartialTSNEEmbedding
225235 if sp .issparse (X ):
226236 raise TypeError (
227237 "A sparse matrix was passed, but dense data is required. Use "
@@ -481,7 +491,8 @@ def prepare_embedding(self, affinities, initialization):
481491 callbacks_every_iters = self .callbacks_every_iters ,
482492 )
483493
484- def fit (self , X : np .ndarray , Y : np .ndarray = None ) -> openTSNE .TSNEEmbedding :
494+ def fit (self , X , Y = None ):
495+ # type: (np.ndarray, Optional[np.ndarray]) -> openTSNE.TSNEEmbedding
485496 # Compute affinities and initial positions and prepare the embedding object
486497 affinities = self .compute_affinities (X )
487498 initialization = self .compute_initialization (X )
0 commit comments