def _selector(name, data_in, data_out, setting): d = dsp.Dispatcher( name='%s selector' % name, description='Select the calibrated %s.' % name, ) errors, setting = [], setting or {} _sort_models = setting.pop('sort_models', sort_models) if 'weights' in setting: _weights = dsp_utl.map_list(setting['targets'], *setting.pop('weights')) else: _weights = None _get_best_model = functools.partial( setting.pop('get_best_model', get_best_model), models_wo_err=setting.pop('models_wo_err', None), selector_id=d.name ) d.add_data( data_id='selector_settings', default_value={}) node_ids = ['error_settings', 'best_model_settings'] d.add_function( function=functools.partial(define_selector_settings, node_ids=node_ids), inputs=['selector_settings'], outputs=node_ids ) for i in data_in: e = 'error/%s' % i errors.append(e) d.add_function( function=_errors(name, i, data_out, setting), inputs=['error_settings', i] + [k for k in data_out if k != i], outputs=[e] ) d.add_function( function_id='sort_models', function=functools.partial(_sort_models, weights=_weights), inputs=errors, outputs=['rank'] ) d.add_function( function_id='get_best_model', function=_get_best_model, inputs=['rank', 'best_model_settings'], outputs=['model', 'errors'] ) return dsp_utl.SubDispatch(d, outputs=['model', 'errors'], output_type='list')
def _comparison2df(comparison): res = {} it = co2_utl.stack_nested_keys(comparison, depth=3) keys = ['usage', 'cycle', 'param'] gen = [(dsp_utl.map_list(keys, *k), k, v) for k, v in it] for s, k, v in _yield_sorted_params(gen, keys=keys): l = co2_utl.get_nested_dicts(res, *k[:-1], default=list) l.append(dsp_utl.combine_dicts({'param_id': k[-1]}, v)) if res: return _dd2df(res, 'param_id', depth=2)
def selector(*data): """ Defines the models' selector model. .. dispatcher:: dsp >>> dsp = selector() :return: The models' selector model. :rtype: SubDispatchFunction """ data = data or ('wltp_h', 'wltp_l') dsp = Dispatcher( name='Models selector', description='Select the calibrated models.', ) dsp.add_function(function=partial(dsp_utl.map_list, data), inputs=data, outputs=['CO2MPAS_results']) dsp.add_data(data_id='models', function=combine_outputs, wait_inputs=True) dsp.add_data(data_id='scores', function=combine_scores, wait_inputs=True) setting = sub_models() dsp.add_data(data_id='error_settings', default_value={}) m = list(setting) dsp.add_function(function=partial(split_error_settings, m), inputs=['error_settings'], outputs=['error_settings/%s' % k for k in m]) for k, v in setting.items(): v['dsp'] = v.pop('define_sub_model', define_sub_model)(**v) v['metrics'] = dsp_utl.map_list(v['targets'], *v['metrics']) dsp.add_function(function=v.pop('model_selector', _selector)(k, data, data, v), function_id='%s selector' % k, inputs=['CO2MPAS_results', 'error_settings/%s' % k], outputs=['models', 'scores']) func = dsp_utl.SubDispatchFunction(dsp=dsp, function_id='models_selector', inputs=('error_settings', ) + data, outputs=['models', 'scores']) return func
def _format_scores(scores): res = {} for k, j in co2_utl.stack_nested_keys(scores, depth=3): if k[-1] in ('limits', 'errors'): model_id = k[0] extra_field = ('score',) if k[-1] == 'errors' else () for i, v in co2_utl.stack_nested_keys(j): i = (model_id, i[-1], k[1],) + i[:-1] + extra_field co2_utl.get_nested_dicts(res, *i, default=co2_utl.ret_v(v)) sco = {} for k, v in co2_utl.stack_nested_keys(res, depth=4): v.update(dsp_utl.map_list(['model_id', 'param_id'], *k[:2])) co2_utl.get_nested_dicts(sco, *k[2:], default=list).append(v) return sco
def _summary2df(data): res = [] summary = data.get('summary', {}) if 'results' in summary: r = {} index = ['cycle', 'stage', 'usage'] for k, v in dsp_utl.stack_nested_keys(summary['results'], depth=4): l = dsp_utl.get_nested_dicts(r, k[0], default=list) l.append(dsp_utl.combine_dicts(dsp_utl.map_list(index, *k[1:]), v)) if r: df = _dd2df(r, index=index, depth=2, col_key=functools.partial(_sort_key, p_keys=('param', ) * 2), row_key=functools.partial(_sort_key, p_keys=index)) df.columns = pd.MultiIndex.from_tuples(_add_units(df.columns)) setattr(df, 'name', 'results') res.append(df) if 'selection' in summary: df = _dd2df(summary['selection'], ['model_id'], depth=2, col_key=functools.partial(_sort_key, p_keys=('stage', 'cycle')), row_key=functools.partial(_sort_key, p_keys=())) setattr(df, 'name', 'selection') res.append(df) if 'comparison' in summary: r = {} for k, v in dsp_utl.stack_nested_keys(summary['comparison'], depth=3): v = dsp_utl.combine_dicts(v, base={'param_id': k[-1]}) dsp_utl.get_nested_dicts(r, *k[:-1], default=list).append(v) if r: df = _dd2df(r, ['param_id'], depth=2, col_key=functools.partial(_sort_key, p_keys=('stage', 'cycle')), row_key=functools.partial(_sort_key, p_keys=())) setattr(df, 'name', 'comparison') res.append(df) if res: return {'summary': res} return {}
def _error(name, data_id, data_out, setting): d = dsp.Dispatcher( name='%s-%s error vs %s' % (name, data_id, data_out), description='Calculates the error of calibrated model of a reference.', ) default_settings = { 'inputs_map': {}, 'targets': [], 'metrics_inputs': {}, 'up_limit': None, 'dn_limit': None } default_settings.update(setting) it = dsp_utl.selector(['up_limit', 'dn_limit'], default_settings).items() for k, v in it: if v is not None: default_settings[k] = dsp_utl.map_list(setting['targets'], *v) d.add_function( function_id='select_inputs', function=dsp_utl.map_dict, inputs=['inputs_map', 'data'], outputs=['inputs<0>'] ) d.add_function( function_id='select_inputs', function=functools.partial(dsp_utl.selector, allow_miss=True), inputs=['inputs', 'inputs<0>'], outputs=['inputs<1>'] ) d.add_function( function=dsp_utl.combine_dicts, inputs=['calibrated_models', 'inputs<1>'], outputs=['prediction_inputs'] ) d.add_function( function_id='select_targets', function=functools.partial(dsp_utl.selector, allow_miss=True), inputs=['targets', 'data'], outputs=['references'] ) d.add_function( function=functools.partial( default_settings.pop('dsp', lambda x: x), {} ), inputs=['prediction_inputs', 'calibrated_models'], outputs=['results'] ) d.add_function( function_id='select_outputs', function=select_outputs, inputs=['outputs', 'targets', 'results'], outputs=['predictions'] ) d.add_function( function_id='select_metrics_inputs', function=functools.partial(dsp_utl.selector, allow_miss=True), inputs=['metrics_inputs', 'data'], outputs=['metrics_args'] ) d.add_function( function=make_metrics, inputs=['metrics', 'references', 'predictions', 'metrics_args'], outputs=['errors'] ) d.add_function( function=check_limits, inputs=['errors', 'up_limit', 'dn_limit'], outputs=['status'] ) for k, v in default_settings.items(): d.add_data(k, v) func = dsp_utl.SubDispatch( dsp=d, outputs=['errors', 'status'], output_type='list' ) return func