<s> """<STR_LIT>""" <EOL> __authors__ = "<STR_LIT>" <EOL> __license__ = "<STR_LIT>" <EOL> __contact__ = "<STR_LIT>" <EOL> import logging <EOL> import numpy as np <EOL> from pyll . stochastic import ( <EOL> categorical , <EOL> normal , <EOL> lognormal , <EOL> qnormal , <EOL> qlognormal , <EOL> uniform , <EOL> loguniform , <EOL> quniform , <EOL> qloguniform , <EOL> ) <EOL> from . base import miscs_to_idxs_vals <EOL> from . algobase import ( <EOL> SuggestAlgo , <EOL> ExprEvaluator , <EOL> ) <EOL> logger = logging . getLogger ( __name__ ) <EOL> class AnnealingAlgo ( SuggestAlgo ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , domain , trials , seed , <EOL> avg_best_idx = <NUM_LIT> , <EOL> shrink_coef = <NUM_LIT:0.1> ) : <EOL> """<STR_LIT>""" <EOL> SuggestAlgo . __init__ ( self , domain , trials , seed = seed ) <EOL> self . avg_best_idx = avg_best_idx <EOL> self . shrink_coef = shrink_coef <EOL> doc_by_tid = { } <EOL> for doc in trials . trials : <EOL> tid = doc [ '<STR_LIT>' ] <EOL> loss = domain . loss ( doc [ '<STR_LIT:result>' ] , doc [ '<STR_LIT>' ] ) <EOL> if loss is None : <EOL> loss = float ( '<STR_LIT>' ) <EOL> else : <EOL> loss = float ( loss ) <EOL> doc_by_tid [ tid ] = ( doc , loss ) <EOL> self . tid_docs_losses = sorted ( doc_by_tid . items ( ) ) <EOL> self . tids = np . asarray ( [ t for ( t , ( d , l ) ) in self . tid_docs_losses ] ) <EOL> self . losses = np . asarray ( [ l for ( t , ( d , l ) ) in self . tid_docs_losses ] ) <EOL> self . tid_losses_dct = dict ( zip ( self . tids , self . losses ) ) <EOL> self . node_tids , self . node_vals = miscs_to_idxs_vals ( <EOL> [ d [ '<STR_LIT>' ] for ( tid , ( d , l ) ) in self . tid_docs_losses ] , <EOL> keys = domain . params . keys ( ) ) <EOL> self . best_tids = [ ] <EOL> def shrinking ( self , label ) : <EOL> """<STR_LIT>""" <EOL> T = len ( self . node_vals [ label ] ) <EOL> return <NUM_LIT:1.0> / ( <NUM_LIT:1.0> + T * self . shrink_coef ) <EOL> def choose_ltv ( self , label , size ) : <EOL> """<STR_LIT>""" <EOL> tids = self . node_tids [ label ] <EOL> vals = self . node_vals [ label ] <EOL> losses = [ self . tid_losses_dct [ tid ] for tid in tids ] <EOL> if size == <NUM_LIT:1> : <EOL> tid_set = set ( tids ) <EOL> for tid in self . best_tids : <EOL> if tid in tid_set : <EOL> idx = tids . index ( tid ) <EOL> rval = losses [ idx ] , tid , vals [ idx ] <EOL> return rval <EOL> good_idx = self . rng . geometric ( <NUM_LIT:1.0> / self . avg_best_idx , size = size ) - <NUM_LIT:1> <EOL> good_idx = np . clip ( good_idx , <NUM_LIT:0> , len ( tids ) - <NUM_LIT:1> ) . astype ( '<STR_LIT>' ) <EOL> picks = np . argsort ( losses ) [ good_idx ] <EOL> picks_loss = np . asarray ( losses ) [ picks ] <EOL> picks_tids = np . asarray ( tids ) [ picks ] <EOL> picks_vals = np . asarray ( vals ) [ picks ] <EOL> if size == <NUM_LIT:1> : <EOL> self . best_tids . append ( int ( picks_tids ) ) <EOL> return picks_loss , picks_tids , picks_vals <EOL> def on_node_hyperparameter ( self , memo , node , label ) : <EOL> """<STR_LIT>""" <EOL> n_observations = len ( self . node_vals [ label ] ) <EOL> if n_observations > <NUM_LIT:0> : <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] <EOL> loss , tid , val = self . choose_ltv ( label , size = size ) <EOL> try : <EOL> handler = getattr ( self , '<STR_LIT>' % node . name ) <EOL> except AttributeError : <EOL> raise NotImplementedError ( '<STR_LIT>' , node . name ) <EOL> return handler ( memo , node , label , tid , val ) <EOL> else : <EOL> return ExprEvaluator . on_node ( self , memo , node ) <EOL> def hp_uniform ( self , memo , node , label , tid , val , <EOL> log_scale = False , <EOL> pass_q = False , <EOL> uniform_like = uniform ) : <EOL> """<STR_LIT>""" <EOL> if log_scale : <EOL> midpt = np . log ( val ) <EOL> else : <EOL> midpt = val <EOL> high = memo [ node . arg [ '<STR_LIT>' ] ] <EOL> low = memo [ node . arg [ '<STR_LIT>' ] ] <EOL> width = ( high - low ) * self . shrinking ( label ) <EOL> half = <NUM_LIT> * width <EOL> min_midpt = low + half <EOL> max_midpt = high - half <EOL> clipped_midpt = np . clip ( midpt , min_midpt , max_midpt ) <EOL> if pass_q : <EOL> return uniform_like ( <EOL> low = clipped_midpt - half , <EOL> high = clipped_midpt + half , <EOL> rng = self . rng , <EOL> q = memo [ node . arg [ '<STR_LIT:q>' ] ] , <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] ) <EOL> else : <EOL> return uniform_like ( <EOL> low = clipped_midpt - half , <EOL> high = clipped_midpt + half , <EOL> rng = self . rng , <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] ) <EOL> def hp_quniform ( self , * args , ** kwargs ) : <EOL> return self . hp_uniform ( <EOL> pass_q = True , <EOL> uniform_like = quniform , <EOL> * args , <EOL> ** kwargs ) <EOL> def hp_loguniform ( self , * args , ** kwargs ) : <EOL> return self . hp_uniform ( <EOL> log_scale = True , <EOL> pass_q = False , <EOL> uniform_like = loguniform , <EOL> * args , <EOL> ** kwargs ) <EOL> def hp_qloguniform ( self , * args , ** kwargs ) : <EOL> return self . hp_uniform ( <EOL> log_scale = True , <EOL> pass_q = True , <EOL> uniform_like = qloguniform , <EOL> * args , <EOL> ** kwargs ) <EOL> def hp_randint ( self , memo , node , label , tid , val ) : <EOL> """<STR_LIT>""" <EOL> upper = memo [ node . arg [ '<STR_LIT>' ] ] <EOL> val1 = np . atleast_1d ( val ) <EOL> if val1 . size : <EOL> counts = np . bincount ( val1 , minlength = upper ) / float ( val1 . size ) <EOL> else : <EOL> counts = np . zeros ( upper ) <EOL> prior = <NUM_LIT:1.0> <EOL> prior = self . shrinking ( label ) <EOL> p = ( <NUM_LIT:1> - prior ) * counts + prior * ( <NUM_LIT:1.0> / upper ) <EOL> rval = categorical ( p = p , upper = upper , rng = self . rng , <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] ) <EOL> return rval <EOL> def hp_categorical ( self , memo , node , label , tid , val ) : <EOL> """<STR_LIT>""" <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] <EOL> if size == <NUM_LIT:0> : <EOL> return [ ] <EOL> val1 = np . atleast_1d ( val ) <EOL> p = p_orig = np . asarray ( memo [ node . arg [ '<STR_LIT:p>' ] ] ) <EOL> if p . ndim == <NUM_LIT:2> : <EOL> if len ( p ) not in ( <NUM_LIT:1> , len ( val1 ) ) : <EOL> print node <EOL> print p <EOL> print np . asarray ( p ) . shape <EOL> assert len ( p ) in ( <NUM_LIT:1> , len ( val1 ) ) <EOL> else : <EOL> assert p . ndim == <NUM_LIT:1> <EOL> p = p [ np . newaxis , : ] <EOL> upper = memo [ node . arg [ '<STR_LIT>' ] ] <EOL> if val1 . size : <EOL> counts = np . bincount ( val1 , minlength = upper ) / float ( val1 . size ) <EOL> prior = self . shrinking ( label ) <EOL> else : <EOL> counts = np . zeros ( upper ) <EOL> prior = <NUM_LIT:1.0> <EOL> new_p = ( <NUM_LIT:1> - prior ) * counts + prior * p <EOL> assert new_p . ndim == <NUM_LIT:2> <EOL> rval = categorical ( p = new_p , rng = self . rng , size = size ) <EOL> if p_orig . ndim == <NUM_LIT:1> : <EOL> assert len ( rval ) == <NUM_LIT:1> <EOL> return rval [ <NUM_LIT:0> ] <EOL> else : <EOL> return rval <EOL> def hp_normal ( self , memo , node , label , tid , val ) : <EOL> """<STR_LIT>""" <EOL> return normal ( <EOL> mu = val , <EOL> sigma = memo [ node . arg [ '<STR_LIT>' ] ] * self . shrinking ( label ) , <EOL> rng = self . rng , <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] ) <EOL> def hp_lognormal ( self , memo , node , label , tid , val ) : <EOL> """<STR_LIT>""" <EOL> return lognormal ( <EOL> mu = np . log ( val ) , <EOL> sigma = memo [ node . arg [ '<STR_LIT>' ] ] * self . shrinking ( label ) , <EOL> rng = self . rng , <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] ) <EOL> def hp_qlognormal ( self , memo , node , label , tid , val ) : <EOL> """<STR_LIT>""" <EOL> return qlognormal ( <EOL> mu = np . log ( <NUM_LIT> + val ) , <EOL> sigma = memo [ node . arg [ '<STR_LIT>' ] ] * self . shrinking ( label ) , <EOL> q = memo [ node . arg [ '<STR_LIT:q>' ] ] , <EOL> rng = self . rng , <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] ) <EOL> def hp_qnormal ( self , memo , node , label , tid , val ) : <EOL> """<STR_LIT>""" <EOL> return qnormal ( <EOL> mu = val , <EOL> sigma = memo [ node . arg [ '<STR_LIT>' ] ] * self . shrinking ( label ) , <EOL> q = memo [ node . arg [ '<STR_LIT:q>' ] ] , <EOL> rng = self . rng , <EOL> size = memo [ node . arg [ '<STR_LIT:size>' ] ] ) <EOL> def suggest ( new_ids , domain , trials , seed , * args , ** kwargs ) : <EOL> new_id , = new_ids <EOL> return AnnealingAlgo ( domain , trials , seed , * args , ** kwargs ) ( new_id ) <EOL> def suggest_batch ( new_ids , domain , trials , seed , * args , ** kwargs ) : <EOL> return AnnealingAlgo ( domain , trials , seed , * args , ** kwargs ) . batch ( new_ids ) </s>
