예제 #1
0
    def compare_models(self):
        new_AICc = AICc(self.model)

        AICc_test = new_AICc < (self._AICc_fraction * self.best_AICc)
        AICc_absolute_test = np.abs(new_AICc - self.best_AICc) <= \
            np.abs(self._AICc_fraction * self.best_AICc)
        dof_test = len(self.model.p0) < self.best_dof

        if AICc_test or AICc_absolute_test and dof_test:

            self.best_values = self._collect_values()
            self.best_AICc = new_AICc
            self.best_dof = len(self.model.p0)
            self.best_chisq = self.model.chisq.data[0]
예제 #2
0
    def compare_models(self):
        new_AICc = AICc(self.model)

        AICc_test = new_AICc < (self._AICc_fraction * self.best_AICc)
        AICc_absolute_test = abs(new_AICc - self.best_AICc) <= \
            abs(self._AICc_fraction * self.best_AICc)
        dof_test = len(self.model.p0) < self.best_dof

        if AICc_test or AICc_absolute_test and dof_test:

            self.best_values = self._collect_values()
            self.best_AICc = new_AICc
            self.best_dof = len(self.model.p0)
            for k in self.parameters.keys():
                self.parameters[k] = getattr(self.model, k).data[0]
 def test_AICc(self):
     _aicc1 = AICc(self.m1)
     _aicc2 = AICc(self.m2)
     np.testing.assert_allclose(_aicc1, 82.477061729373233)
     np.testing.assert_allclose(_aicc2, 80.749265802224159)
예제 #4
0
def single_kernel(model, ind, values, optional_components, _args, test):
    from itertools import combinations, product
    import numpy as np
    from hyperspy.utils.model_selection import AICc

    def generate_values_iterator(compnames, vals, turned_on_component_inds):
        turned_on_names = [compnames[i] for i in turned_on_component_inds]
        tmp = []
        name_list = []
        # TODO: put changing _position parameter of each component at the
        # beginning
        for _comp_n, _comp in vals.items():
            if _comp_n in turned_on_names:
                for par_n, par in _comp.items():
                    if not isinstance(par, list):
                        par = [par]
                    tmp.append(par)
                    name_list.append((_comp_n, par_n))
        return name_list, product(*tmp)

    comb = []
    AICc_fraction = 0.99
    model.axes_manager.indices = ind[::-1]
    for comp in optional_components:
        model[comp].active = False

    for num in range(len(optional_components) + 1):
        for c in combinations(optional_components, num):
            comb.append(c)

    best_AICc, best_dof = np.inf, np.inf
    best_comb, best_values, best_names = None, None, None

    component_names = [c.name for c in model]

    for combination in comb:
        # iterate all component combinations
        for component in combination:
            model[component].active = True

        on_comps = [i for i, _c in enumerate(model) if _c.active]
        name_list, iterator = generate_values_iterator(component_names, values,
                                                       on_comps)

        ifgood = False
        for it in iterator:
            # iterate all parameter value combinations
            for (comp_n, par_n), val in zip(name_list, it):
                try:
                    getattr(model[comp_n], par_n).value = val
                except:
                    pass
            model.fit(**_args)
            # only perform iterations until we find a solution that we think is
            # good enough
            ifgood = test.test(model, ind)
            if ifgood:
                break
        if ifgood:
            # shortcut when no optional components:
            if len(comb) == 1:
                return True

            # get model with best chisq here, and test model validation
            new_AICc = AICc(model.inav[ind[::-1]])

            if new_AICc < AICc_fraction * best_AICc or \
                    (np.abs(new_AICc - best_AICc) <= np.abs(AICc_fraction * best_AICc)
                     and len(model.p0) < best_dof):
                best_values = [
                    getattr(model[comp_n], par_n).value
                    for comp_n, par_n in name_list
                ]
                best_names = name_list
                best_comb = combination
                best_AICc = new_AICc
                best_dof = len(model.p0)
        for component in combination:
            model[component].active = False

    # take the best overall combination of components and parameters:
    if best_comb is None:
        model.chisq.data[ind] = np.nan
        return False
    else:
        for component in best_comb:
            model[component].active = True
        for (comp_n, par_n), val in zip(best_names, best_values):
            try:
                getattr(model[comp_n], par_n).value = val
            except:
                pass
        model.fit(**_args)
        return True
예제 #5
0
def multi_kernel(ind, m_dic, values, optional_components, _args, result_q,
                 test_dict):
    import hyperspy.api as hs
    from hyperspy.signal import Signal
    from multiprocessing import current_process
    from itertools import combinations, product
    # from collections import Iterable
    import numpy as np
    import copy
    from hyperspy.utils.model_selection import AICc
    import dill

    def generate_values_iterator(compnames, vals, turned_on_component_inds):
        turned_on_names = [compnames[i] for i in turned_on_component_inds]
        tmp = []
        name_list = []
        # TODO: put changing _position parameter of each component at the
        # beginning
        for _comp_n, _comp in vals.items():
            if _comp_n in turned_on_names:
                for par_n, par in _comp.items():
                    if not isinstance(par, list):
                        par = [
                            par,
                        ]
                    tmp.append(par)
                    name_list.append((_comp_n, par_n))
        return name_list, product(*tmp)

    def send_good_results(model, previous_switching, cur_p, result_q, ind):
        result = copy.deepcopy(model.as_dictionary())
        for num, a_i_m in enumerate(previous_switching):
            result['components'][num]['active_is_multidimensional'] = a_i_m
        result['current'] = cur_p._identity
        result_q.put((ind, result, True))

    test = dill.loads(test_dict)
    cur_p = current_process()
    previous_switching = []
    comb = []
    AICc_fraction = 0.99

    comp_dict = m_dic['models']['z']['_dict']['components']
    for num, comp in enumerate(comp_dict):
        previous_switching.append(comp['active_is_multidimensional'])
        comp['active_is_multidimensional'] = False
    for comp in optional_components:
        comp_dict[comp]['active'] = False

    for num in range(len(optional_components) + 1):
        for comp in combinations(optional_components, num):
            comb.append(comp)

    best_AICc, best_dof = np.inf, np.inf
    best_comb, best_values, best_names = None, None, None

    component_names = [c['name'] for c in comp_dict]

    sig = Signal(**m_dic)
    sig._assign_subclass()
    model = sig.models.z.restore()
    for combination in comb:
        # iterate all component combinations
        for component in combination:
            model[component].active = True

        on_comps = [i for i, _c in enumerate(model) if _c.active]
        name_list, iterator = generate_values_iterator(component_names, values,
                                                       on_comps)

        ifgood = False
        for it in iterator:
            # iterate all parameter value combinations
            for (comp_n, par_n), val in zip(name_list, it):
                try:
                    getattr(model[comp_n], par_n).value = val
                except:
                    pass
            model.fit(**_args)
            # only perform iterations until we find a solution that we think is
            # good enough
            ifgood = test.test(model, (0, ))
            if ifgood:
                break
        if ifgood:
            # get model with best chisq here, and test model validation
            if len(comb) == 1:
                send_good_results(model, previous_switching, cur_p, result_q,
                                  ind)
            new_AICc = AICc(model)

            if new_AICc < AICc_fraction * best_AICc or \
                    (np.abs(new_AICc - best_AICc) <= np.abs(AICc_fraction * best_AICc)
                     and len(model.p0) < best_dof):
                best_values = [
                    getattr(model[comp_n], par_n).value
                    for comp_n, par_n in name_list
                ]
                best_names = name_list
                best_comb = combination
                best_AICc = new_AICc
                best_dof = len(model.p0)
        for component in combination:
            model[component].active = False

    # take the best overall combination of components and parameters:
    if best_comb is None:
        result_q.put((ind, None, False))
    else:
        for component in best_comb:
            model[component].active = True
        for (comp_n, par_n), val in zip(best_names, best_values):
            try:
                getattr(model[comp_n], par_n).value = val
            except:
                pass
        model.fit(**_args)
        send_good_results(model, previous_switching, cur_p, result_q, ind)
예제 #6
0
 def test_AICc(self):
     _aicc1 = AICc(self.m1)
     _aicc2 = AICc(self.m2)
     nt.assert_almost_equal(_aicc1, 82.477061729373233)
     nt.assert_almost_equal(_aicc2, 80.749265802224159)
예제 #7
0
 def test(self, model, ind):
     m = model.inav[ind[::-1]]
     m.fetch_stored_values()
     _aicc = AICc(m)
     return np.abs(notexp(_aicc) - self.expected) < notexp(self.tolerance)