99from scipy import sparse
1010import warnings
1111import numbers
12+ import tasklogger
13+
1214try :
1315 import pandas as pd
1416except ImportError :
2426from .utils import (elementwise_minimum ,
2527 elementwise_maximum ,
2628 set_diagonal )
27- from .logging import (set_logging ,
28- log_start ,
29- log_complete ,
30- log_debug )
3129
3230
3331class Base (object ):
@@ -67,6 +65,9 @@ def _get_param_names(cls):
6765
6866 return parameters
6967
68+ def set_params (self , ** kwargs ):
69+ return self
70+
7071
7172class Data (Base ):
7273 """Parent class that handles the import and dimensionality reduction of data
@@ -152,7 +153,7 @@ def _reduce_data(self):
152153 Reduced data matrix
153154 """
154155 if self .n_pca is not None and self .n_pca < self .data .shape [1 ]:
155- log_start ("PCA" )
156+ tasklogger . log_start ("PCA" )
156157 if sparse .issparse (self .data ):
157158 if isinstance (self .data , sparse .coo_matrix ) or \
158159 isinstance (self .data , sparse .lil_matrix ) or \
@@ -166,7 +167,7 @@ def _reduce_data(self):
166167 random_state = self .random_state )
167168 self .data_pca .fit (self .data )
168169 data_nu = self .data_pca .transform (self .data )
169- log_complete ("PCA" )
170+ tasklogger . log_complete ("PCA" )
170171 return data_nu
171172 else :
172173 data_nu = self .data
@@ -204,6 +205,7 @@ def set_params(self, **params):
204205 raise ValueError ("Cannot update n_pca. Please create a new graph" )
205206 if 'random_state' in params :
206207 self .random_state = params ['random_state' ]
208+ super ().set_params (** params )
207209 return self
208210
209211 def transform (self , Y ):
@@ -342,10 +344,10 @@ def __init__(self, kernel_symm='+',
342344 self ._check_symmetrization (kernel_symm , gamma )
343345
344346 if initialize :
345- log_debug ("Initializing kernel..." )
347+ tasklogger . log_debug ("Initializing kernel..." )
346348 self .K
347349 else :
348- log_debug ("Not initializing kernel." )
350+ tasklogger . log_debug ("Not initializing kernel." )
349351 super ().__init__ (** kwargs )
350352
351353 def _check_symmetrization (self , kernel_symm , gamma ):
@@ -363,7 +365,8 @@ def _check_symmetrization(self, kernel_symm, gamma):
363365 warnings .warn ("kernel_symm='gamma' but gamma not given. "
364366 "Defaulting to gamma=0.5." )
365367 self .gamma = gamma = 0.5
366- elif not isinstance (gamma , numbers .Number ) or gamma < 0 or gamma > 1 :
368+ elif not isinstance (gamma , numbers .Number ) or \
369+ gamma < 0 or gamma > 1 :
367370 raise ValueError ("gamma {} not recognized. Expected "
368371 "a float between 0 and 1" .format (gamma ))
369372
@@ -392,18 +395,18 @@ def _build_kernel(self):
392395 def symmetrize_kernel (self , K ):
393396 # symmetrize
394397 if self .kernel_symm == "+" :
395- log_debug ("Using addition symmetrization." )
398+ tasklogger . log_debug ("Using addition symmetrization." )
396399 K = (K + K .T ) / 2
397400 elif self .kernel_symm == "*" :
398- log_debug ("Using multiplication symmetrization." )
401+ tasklogger . log_debug ("Using multiplication symmetrization." )
399402 K = K .multiply (K .T )
400403 elif self .kernel_symm == 'gamma' :
401- log_debug (
404+ tasklogger . log_debug (
402405 "Using gamma symmetrization (gamma = {})." .format (self .gamma ))
403406 K = self .gamma * elementwise_minimum (K , K .T ) + \
404407 (1 - self .gamma ) * elementwise_maximum (K , K .T )
405408 elif self .kernel_symm is None :
406- log_debug ("Using no symmetrization." )
409+ tasklogger . log_debug ("Using no symmetrization." )
407410 pass
408411 else :
409412 # this should never happen
@@ -438,9 +441,11 @@ def set_params(self, **params):
438441 """
439442 if 'gamma' in params and params ['gamma' ] != self .gamma :
440443 raise ValueError ("Cannot update gamma. Please create a new graph" )
441- if 'kernel_symm' in params and params ['kernel_symm' ] != self .kernel_symm :
444+ if 'kernel_symm' in params and \
445+ params ['kernel_symm' ] != self .kernel_symm :
442446 raise ValueError (
443447 "Cannot update kernel_symm. Please create a new graph" )
448+ super ().set_params (** params )
444449 return self
445450
446451 @property
@@ -462,6 +467,31 @@ def P(self):
462467 self ._diff_op = normalize (self .kernel , 'l1' , axis = 1 )
463468 return self ._diff_op
464469
470+ @property
471+ def diff_aff (self ):
472+ """Symmetric diffusion affinity matrix
473+
474+ Return or calculate the symmetric diffusion affinity matrix
475+
476+ .. math:: A(x,y) = K(x,y) (d(x) d(y))^{-1/2}
477+
478+ where :math:`d` is the degrees (row sums of the kernel.)
479+
480+ Returns
481+ -------
482+
483+ diff_aff : array-like, shape=[n_samples, n_samples]
484+ symmetric diffusion affinity matrix defined as a
485+ doubly-stochastic form of the kernel matrix
486+ """
487+ row_degrees = np .array (self .kernel .sum (axis = 1 )).reshape (- 1 , 1 )
488+ col_degrees = np .array (self .kernel .sum (axis = 0 )).reshape (1 , - 1 )
489+ if sparse .issparse (self .kernel ):
490+ return self .kernel .multiply (1 / np .sqrt (row_degrees )).multiply (
491+ 1 / np .sqrt (col_degrees ))
492+ else :
493+ return (self .kernel / np .sqrt (row_degrees )) / np .sqrt (col_degrees )
494+
465495 @property
466496 def diff_op (self ):
467497 """Synonym for P
@@ -597,7 +627,7 @@ def __init__(self, data,
597627 # kwargs are ignored
598628 self .n_jobs = n_jobs
599629 self .verbose = verbose
600- set_logging (verbose )
630+ tasklogger . set_level (verbose )
601631 super ().__init__ (data , ** kwargs )
602632
603633 def get_params (self ):
0 commit comments