예제 #1
0
def test_Morris_with_NAN():
    '''
    Test if morris.analyze raise a ValueError when nan are passed in the Y 
    values
    '''
    problem, model_results, param_values = setup_samples()

    #  Should raise a ValueError type of error
    with pytest.raises(ValueError):
        morris.analyze(problem, param_values, model_results)
예제 #2
0
파일: test_to_df.py 프로젝트: SALib/SALib
def test_morris_to_df():
    params = ['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8']

    problem = {
        'num_vars': 8,
        'names': params,
        'groups': None,
        'bounds': [[0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0]]
    }

    param_values = morris_sample.sample(problem, N=1000, num_levels=4,
                                        optimal_trajectories=None)
    Y = Sobol_G.evaluate(param_values)
    Si = morris.analyze(problem, param_values, Y)
    Si_df = Si.to_df()

    assert isinstance(Si_df, pd.DataFrame), \
        "Morris Si: Expected DataFrame, got {}".format(type(Si_df))

    expected_index = set(params)
    assert set(Si_df.index) == expected_index, "Incorrect index in DataFrame"

    col_names = ['mu', 'mu_star', 'sigma', 'mu_star_conf']
    assert set(Si_df.columns) == set(col_names), \
        "Unexpected column names in DataFrame. Expected {}, got {}".format(
            col_names, Si_df.columns)
예제 #3
0
    def test_regression_morris_optimal(self, set_seed):
        '''
        Tests the use of optimal trajectories with Morris.

        Uses brute force approach

        Note that the relative tolerance is set to a very high value
        (default is 1e-05) due to the coarse nature of the num_levels.
        '''
        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami.txt'
        problem = read_param_file(param_file)
        param_values = sample(problem=problem, N=20,
                              num_levels=4,
                              optimal_trajectories=9,
                              local_optimization=True)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem, param_values, Y,
                            conf_level=0.95, print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu_star'],
                        [9.786986e+00, 7.875000e+00, 1.388621],
                        atol=0,
                        rtol=1e-5)
예제 #4
0
    def test_regression_morris_groups_brute_optim(self, set_seed):

        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami_groups.txt'
        problem = read_param_file(param_file)

        param_values = sample(problem=problem, N=50,
                              num_levels=4,
                              optimal_trajectories=6,
                              local_optimization=False)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem, param_values, Y,
                            conf_level=0.95, print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu'], [9.786986, np.NaN],
                        atol=0, rtol=1e-5)

        assert_allclose(Si['sigma'], [6.453729, np.NaN],
                        atol=0, rtol=1e-5)

        assert_allclose(Si['mu_star'], [9.786986, 7.875],
                        atol=0, rtol=1e-5)
예제 #5
0
    def test_regression_morris_optimal(self, set_seed):
        '''
        Tests the use of optimal trajectories with Morris.

        Uses brute force approach

        Note that the relative tolerance is set to a very high value
        (default is 1e-05) due to the coarse nature of the num_levels.
        '''
        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami.txt'
        problem = read_param_file(param_file)
        param_values = sample(problem=problem,
                              N=20,
                              num_levels=4,
                              optimal_trajectories=9,
                              local_optimization=True)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem,
                            param_values,
                            Y,
                            conf_level=0.95,
                            print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu_star'], [9.786986e+00, 7.875000e+00, 1.388621],
                        atol=0,
                        rtol=1e-5)
예제 #6
0
def plot_morris_by_leaf_by_boot(df_out, variable='normalized_audpc',
                                parameter_range_file='param_range_SA.txt',
                                input_file='morris_input.txt',
                                nboots=5, ylims=None):
    problem = read_param_file(parameter_range_file)
    fig, axs = plt.subplots(6, 2, figsize=(15, 30))
    colors = iter(['b', 'g', 'r', 'k', 'm', 'c', 'y'])
    colors = {b: next(colors) for b in range(nboots)}
    for i, ax in enumerate(axs.flat):
        lf = i + 1
        for boot in np.unique(df_out['i_boot']):
            param_values = np.loadtxt(input_file[:-4] + '_boot' + str(boot) + input_file[-4:])
            df = df_out[(df_out['i_boot'] == boot) & (df_out['num_leaf_top'] == lf)]
            Y = df[variable]
            Si_bt = morris.analyze(problem, param_values, Y, grid_jump=5,
                                   num_levels=10, conf_level=0.95,
                                   print_to_console=False)
            for ip, param in enumerate(Si_bt['names']):
                ax.plot(Si_bt['mu_star'][ip], Si_bt['sigma'][ip],
                        color=colors[boot], marker='*')
                ax.annotate(param, (Si_bt['mu_star'][ip], Si_bt['sigma'][ip]))
        if ylims is not None:
            ax.set_ylim(ylims)
            ax.set_xlim(ylims)
        ax.annotate('Leaf %d' % lf, xy=(0.05, 0.85),
                    xycoords='axes fraction', fontsize=18)
예제 #7
0
 def gsa_analyse(self):
     return [
         ma.analyze(self.morris_problem,
                    self.samples,
                    np.array(score),
                    num_levels=4) for score in self.scores
     ]
예제 #8
0
    def test_regression_morris_groups_brute_optim(self, set_seed):

        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami_groups.txt'
        problem = read_param_file(param_file)

        param_values = sample(problem=problem,
                              N=50,
                              num_levels=4,
                              optimal_trajectories=6,
                              local_optimization=False)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem,
                            param_values,
                            Y,
                            conf_level=0.95,
                            print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu'], [9.786986, np.NaN], atol=0, rtol=1e-5)

        assert_allclose(Si['sigma'], [6.453729, np.NaN], atol=0, rtol=1e-5)

        assert_allclose(Si['mu_star'], [9.786986, 7.875], atol=0, rtol=1e-5)
예제 #9
0
def test_morris_to_df():
    params = ['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8']

    problem = {
        'num_vars':
        8,
        'names':
        params,
        'groups':
        None,
        'bounds': [[0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0],
                   [0.0, 1.0], [0.0, 1.0], [0.0, 1.0]]
    }

    param_values = morris_sample.sample(problem,
                                        N=1000,
                                        num_levels=4,
                                        optimal_trajectories=None)
    Y = Sobol_G.evaluate(param_values)
    Si = morris.analyze(problem, param_values, Y)
    Si_df = Si.to_df()

    assert isinstance(Si_df, pd.DataFrame), \
        "Morris Si: Expected DataFrame, got {}".format(type(Si_df))

    expected_index = set(params)
    assert set(Si_df.index) == expected_index, "Incorrect index in DataFrame"

    col_names = ['mu', 'mu_star', 'sigma', 'mu_star_conf']
    assert set(Si_df.columns) == set(col_names), \
        "Unexpected column names in DataFrame. Expected {}, got {}".format(
            col_names, Si_df.columns)
예제 #10
0
 def analyze_morris(self):
     # Method of Morris
     return morris.analyze(
         self.sa_problem,
         self.samples_x,
         self.samples_y,
         conf_level=0.95,
         num_levels=4,
         print_to_console=self.options["print_to_console"])
예제 #11
0
    def fit(self, X, y):
        """
        Fits the regressor to the data `(X, y)` and performs a sensitivity analysis on the result of the regression.

        :param X: Training data
        :param y: Target values
        :return: `self`
        """
        from numpy import argpartition
        N = len(X[0])
        if (self.domain is None) or (self.probs is None):
            self._avg_fucn(X, y)
        if self.regressor is None:
            from sklearn.svm import SVR
            self.regressor = SVR()
        self.regressor.fit(self.domain, self.probs)
        bounds = [[
            min(self.domain[:, idx]) - self.margin,
            max(self.domain[:, idx]) + self.margin
        ] for idx in range(N)]
        problem = dict(num_vars=N,
                       names=['x%d' % idx for idx in range(N)],
                       bounds=bounds)
        res = []
        if self.method == 'sobol':
            from SALib.sample import saltelli
            from SALib.analyze import sobol
            param_values = saltelli.sample(problem, self.num_smpl)
            y_ = self.regressor.predict(param_values)
            res = sobol.analyze(problem, y_)['ST']
            self.weights_ = res
        elif self.method == 'morris':
            from SALib.sample import morris as mrs
            from SALib.analyze import morris
            param_values = mrs.sample(problem,
                                      self.num_smpl,
                                      num_levels=self.num_levels)
            y_ = self.regressor.predict(param_values)
            res = morris.analyze(problem,
                                 param_values,
                                 y_,
                                 num_levels=self.num_levels)['mu_star']
            self.weights_ = res
        elif self.method == 'delta-mmnt':
            from SALib.sample import latin
            from SALib.analyze import delta
            param_values = latin.sample(problem, self.num_smpl)
            y_ = self.regressor.predict(param_values)
            res = delta.analyze(problem,
                                param_values,
                                y_,
                                num_resamples=self.num_resmpl)['delta']
            self.weights_ = res
        self.top_features_ = argpartition(
            res, -self.n_features_to_select)[-self.n_features_to_select:]
        return self
예제 #12
0
    def explain_global(self, name=None):
        from SALib.analyze import morris

        if name is None:
            name = gen_name_from_class(self)

        samples = self.sampler.sample()
        problem = self.sampler.gen_problem_from_data(self.data,
                                                     self.feature_names)
        analysis = morris.analyze(problem, samples,
                                  self.predict_fn(samples).astype(float))

        mu = analysis["mu"]
        mu_star = analysis["mu_star"]
        sigma = analysis["sigma"]
        mu_star_conf = analysis["mu_star_conf"]

        mask = mu_star > 0
        convergence_index = np.max(
            np.array(mu_star_conf)[mask] / np.array(mu_star)[mask])

        overall_data_dict = {
            "names": self.feature_names,
            "scores": mu_star,
            "convergence_index": convergence_index,
        }

        specific_data_dicts = []
        for feat_idx, feature_name in enumerate(self.feature_names):
            specific_data_dict = {
                "type": "morris",
                "mu": mu[feat_idx],
                "mu_star": mu_star[feat_idx],
                "sigma": sigma[feat_idx],
                "mu_star_conf": mu_star_conf[feat_idx],
            }
            specific_data_dicts.append(specific_data_dict)

        internal_obj = {
            "overall": overall_data_dict,
            "specific": specific_data_dicts
        }

        global_selector = gen_global_selector(self.data, self.feature_names,
                                              self.feature_types, mu_star)

        return MorrisExplanation(
            "global",
            internal_obj,
            feature_names=self.feature_names,
            feature_types=self.feature_types,
            name=name,
            selector=global_selector,
        )
예제 #13
0
    def _analyze(*args, **kwargs):
        self = args[0]

        num_levels       = self.getKwarg('num_levels', kwargs)
        grid_jump        = self.getKwarg('grid_jump', kwargs)
        num_resamples    = kwargs.get('num_resamples', 1000)
        conf_level       = kwargs.get('conf_level', 0.95)
        print_to_console = kwargs.get('print_to_console', False)

        return morris.analyze(self.problem, self.inputs, self.results, num_resamples=num_resamples,
                              conf_level=conf_level, print_to_console=print_to_console,
                              grid_jump=grid_jump, num_levels=num_levels)
예제 #14
0
def _anlzr_salib(método, problema, mstr, simul, ops_método):
    '''
    Parameters
    ----------
    método: ['morris', 'fast']
    líms_paráms, mapa_paráms se usan para generar el problema.
    mstr: sampled data
    simul: simulated model output
    ops_método: dict
    #{'num_levels': 8, 'grid_jump': 4}

    Returns
    -------

    '''

    if isinstance(mstr, list):
        mstr = np.asarray(mstr)

    if método == 'morris':
        if isinstance(simul, list):
            simul = np.asarray(simul)
        ops = {'X': mstr, 'Y': simul, 'num_levels': 16}
        ops.update(ops_método)

        mor = {}
        Si = morris.analyze(problema, **ops)

        mor.update(
            {'mu_star': {j: Si['mu_star'][i] for i, j in enumerate(problema['names'])},
             'sigma': {j: Si['sigma'][i] for i, j in enumerate(problema['names'])},
             # 'sum_sigma': np.sum(Si['sigma'])
             })
        return mor

    elif método == 'fast':
        ops = {'Y': simul}

        fa = {}
        Si = fast.analyze(problema, **ops)

        fa.update({'Si': {j: Si['S1'][i] for i, j in enumerate(problema['names'])},
                   'ST': {j: Si['ST'][i] for i, j in enumerate(problema['names'])},
                   'St-Si': {j: Si['ST'][i] - Si['S1'][i] for i, j in enumerate(problema['names'])},
                   # 'sum_s1': np.sum(Si['S1']),
                   # 'sum_st': np.sum(Si['ST']),
                   # 'sum_st-s1': np.absolute(np.sum(Si['ST']) - np.sum(Si['S1']))
                   })
        return fa

    else:
        raise ValueError(_('Algoritmo "{}" no reconocido.').format(método))
예제 #15
0
def test_analysis_of_morris_results():
    '''
    Tests a one-dimensional vector of results

    Taken from the solution to Exercise 4 (p.138) in Saltelli (2008).
    '''
    model_input = np.array(
        [[0, 1. / 3], [0, 1], [2. / 3, 1], [0, 1. / 3], [2. / 3, 1. / 3],
         [2. / 3, 1], [2. / 3, 0], [2. / 3, 2. / 3], [0, 2. / 3], [1. / 3, 1],
         [1, 1], [1, 1. / 3], [1. / 3, 1], [1. / 3, 1. / 3], [1, 1. / 3],
         [1. / 3, 2. / 3], [1. / 3, 0], [1, 0]],
        dtype=float)

    model_output = np.array([
        0.97, 0.71, 2.39, 0.97, 2.30, 2.39, 1.87, 2.40, 0.87, 2.15, 1.71, 1.54,
        2.15, 2.17, 1.54, 2.20, 1.87, 1.0
    ],
                            dtype=float)

    problem = {
        'num_vars': 2,
        'names': ['Test 1', 'Test 2'],
        'groups': None,
        'bounds': [[0.0, 1.0], [0.0, 1.0]]
    }

    Si = analyze(problem,
                 model_input,
                 model_output,
                 num_resamples=1000,
                 conf_level=0.95,
                 print_to_console=False)

    desired_mu = np.array([0.66, 0.21])
    assert_allclose(Si['mu'],
                    desired_mu,
                    rtol=1e-1,
                    err_msg="The values for mu are incorrect")
    desired_mu_star = np.array([1.62, 0.35])
    assert_allclose(Si['mu_star'],
                    desired_mu_star,
                    rtol=1e-2,
                    err_msg="The values for mu star are incorrect")
    desired_sigma = np.array([1.79, 0.41])
    assert_allclose(Si['sigma'],
                    desired_sigma,
                    rtol=1e-2,
                    err_msg="The values for sigma are incorrect")
    desired_names = ['Test 1', 'Test 2']
    assert_equal(Si['names'],
                 desired_names,
                 err_msg="The values for names are incorrect")
예제 #16
0
def morris():
    from SALib.analyze import morris
    from SALib.sample.morris import sample

    problem = {
        'num_vars': 5,
        'names': ['HEME', 'K1', 'MPY', 'MPYgu', 'QCC'],
        'groups': None,
        'bounds': [[.4, .5], [10., 30.], [30., 40.], [15., 25.], [10., 15.]]
    }

    parameter_values = sample(problem,
                              N=10,
                              num_levels=4,
                              grid_jump=2,
                              optimal_trajectories=None)

    parameters = assign_parameters()
    schedule = get_default_schedule()

    y_index = np.argmax(o["Curine"])

    ys = []

    for inputs in parameter_values:
        for i in range(len(problem["names"])):
            setattr(parameters, problem["names"][i], inputs[i])

        _, __, ___, output = pbpk(parameters, schedule)

        ys.append(output["Curine"][y_index])

    sis = morris.analyze(problem,
                         parameter_values,
                         np.array(ys),
                         conf_level=0.95,
                         print_to_console=True,
                         num_levels=4,
                         grid_jump=2,
                         num_resamples=100)

    import matplotlib.pyplot as plt
    from SALib.plotting.morris import horizontal_bar_plot, covariance_plot, sample_histograms

    fig, (ax1, ax2) = plt.subplots(1, 2)
    horizontal_bar_plot(ax1, sis, {}, sortby='mu_star', unit=r"mg/g")
    covariance_plot(ax2, sis, {}, unit=r"mg/g")

    fig2 = plt.figure()
    sample_histograms(fig2, parameter_values, problem, {'color': 'y'})
    plt.show()
예제 #17
0
def test_doesnot_raise_error_if_floats():

    inputs = np.array([[0, 1. / 3], [0, 1], [2. / 3, 1],
                       [0, 1. / 3], [2. / 3, 1. / 3], [2. / 3, 1],
                       [2. / 3, 0], [2. / 3, 2. / 3], [0, 2. / 3],
                       [1. / 3, 1], [1, 1], [1, 1. / 3],
                       [1. / 3, 1], [1. / 3, 1. / 3], [1, 1. / 3],
                       [1. / 3, 2. / 3], [1. / 3, 0], [1, 0]],
                      dtype=np.float32)

    outputs = np.array([0.97, 0.71, 2.39, 0.97, 2.30, 2.39,
                        1.87, 2.40, 0.87, 2.15, 1.71, 1.54,
                        2.15, 2.17, 1.54, 2.20, 1.87, 1.0],
                       dtype=np.float32)

    problem = {
        'num_vars': 2,
        'names': ['Test 1', 'Test 2'],
        'groups': None,
        'bounds': [[0.0, 1.0], [0.0, 1.0]]
    }

    analyze(problem, inputs, outputs)
예제 #18
0
def test_doesnot_raise_error_if_floats():

    inputs = np.array(
        [[0, 1. / 3], [0, 1], [2. / 3, 1], [0, 1. / 3], [2. / 3, 1. / 3],
         [2. / 3, 1], [2. / 3, 0], [2. / 3, 2. / 3], [0, 2. / 3], [1. / 3, 1],
         [1, 1], [1, 1. / 3], [1. / 3, 1], [1. / 3, 1. / 3], [1, 1. / 3],
         [1. / 3, 2. / 3], [1. / 3, 0], [1, 0]],
        dtype=np.float32)

    outputs = np.array([
        0.97, 0.71, 2.39, 0.97, 2.30, 2.39, 1.87, 2.40, 0.87, 2.15, 1.71, 1.54,
        2.15, 2.17, 1.54, 2.20, 1.87, 1.0
    ],
                       dtype=np.float32)

    problem = {
        'num_vars': 2,
        'names': ['Test 1', 'Test 2'],
        'groups': None,
        'bounds': [[0.0, 1.0], [0.0, 1.0]]
    }

    analyze(problem, inputs, outputs)
예제 #19
0
    def explain_global(self, name=None):
        if name is None:
            name = gen_name_from_class(self)

        samples = self.sampler.sample()
        problem = self.sampler.gen_problem_from_data(self.data, self.feature_names)
        analysis = morris.analyze(problem, samples, self.predict_fn(samples))

        mu = analysis["mu"]
        mu_star = analysis["mu_star"]
        sigma = analysis["sigma"]
        mu_star_conf = analysis["mu_star_conf"]

        mask = mu_star > 0
        convergence_index = np.max(
            np.array(mu_star_conf)[mask] / np.array(mu_star)[mask]
        )

        overall_data_dict = {
            "names": self.feature_names,
            "scores": mu_star,
            "convergence_index": convergence_index,
        }

        specific_data_dicts = []
        for feat_idx, feature_name in enumerate(self.feature_names):
            specific_data_dict = {
                "type": "morris",
                "mu": mu[feat_idx],
                "mu_star": mu_star[feat_idx],
                "sigma": sigma[feat_idx],
                "mu_star_conf": mu_star_conf[feat_idx],
            }
            specific_data_dicts.append(specific_data_dict)

        internal_obj = {"overall": overall_data_dict, "specific": specific_data_dicts}

        global_selector = gen_global_selector(
            self.data, self.feature_names, self.feature_types, mu_star
        )

        return MorrisExplanation(
            "global",
            internal_obj,
            feature_names=self.feature_names,
            feature_types=self.feature_types,
            name=name,
            selector=global_selector,
        )
예제 #20
0
    def explain_global(self, name=None):
        if name is None:
            name = gen_name_from_class(self)

        samples = self.sampler.sample()
        problem = self.sampler.gen_problem_from_data(self.data,
                                                     self.feature_names)
        analysis = morris.analyze(problem, samples, self.predict_fn(samples))

        mu = analysis['mu']
        mu_star = analysis['mu_star']
        sigma = analysis['sigma']
        mu_star_conf = analysis['mu_star_conf']

        mask = mu_star > 0
        convergence_index = np.max(
            np.array(mu_star_conf)[mask] / np.array(mu_star)[mask])

        overall_data_dict = {
            'names': self.feature_names,
            'scores': mu_star,
            'convergence_index': convergence_index,
        }

        specific_data_dicts = []
        for feat_idx, feature_name in enumerate(self.feature_names):
            specific_data_dict = {
                'type': 'morris',
                'mu': mu[feat_idx],
                'mu_star': mu_star[feat_idx],
                'sigma': sigma[feat_idx],
                'mu_star_conf': mu_star_conf[feat_idx],
            }
            specific_data_dicts.append(specific_data_dict)

        internal_obj = {
            'overall': overall_data_dict,
            'specific': specific_data_dicts,
        }

        global_selector = gen_global_selector(self.data, self.feature_names,
                                              self.feature_types, mu_star)

        return MorrisExplanation('global',
                                 internal_obj,
                                 feature_names=self.feature_names,
                                 feature_types=self.feature_types,
                                 name=name,
                                 selector=global_selector)
예제 #21
0
def test_regression_morris_vanilla():

    param_file = 'SALib/test_functions/params/Ishigami.txt'
    problem = read_param_file(param_file)
    param_values = sample(problem=problem, N=5000, \
                          num_levels=10, grid_jump=5, \
                          optimal_trajectories=None)

    Y = Ishigami.evaluate(param_values)

    Si = morris.analyze(problem, param_values, Y,
                        conf_level=0.95, print_to_console=False,
                        num_levels=10, grid_jump=5)

    assert_allclose(Si['mu_star'], [8.1, 2.2, 5.4], atol=0, rtol=5e-1)
예제 #22
0
def morris_analyze_function(problem, X, Y):
    """
    Use the SALib.analyze.morris method to analyze the simulation results.

    :param problem: The definition of the problem statement as defined for the sampling method.
    :param X: the `X` parameter of the morris method (The NumPy matrix containing the model inputs)
    :param Y: The NumPy array containing the model outputs
    :param parameters: dictionary containing the key 'num_levels' that is passed on to the
                       SALib.analyze.morris method parameter of the same name.
    :return: returns the result of the SALib.analyze.sobol method (from the documentation: a dictionary with keys 
             `mu`, `mu_star`, `sigma`, and `mu_star_conf`, where each entry is a list of size D (the number of eters) 
             containing the indices in the same order as the parameter file.)
    """
    assert 'num_levels' in problem, 'morris method requires the `num_levels` parameter to be set (int)'
    return morris.analyze(problem, X, Y, num_levels=problem['num_levels'])
예제 #23
0
def run_salib_morris(target_parameters,
                     target_output_name,
                     n_trajectories,
                     num_levels,
                     grid_jump,
                     n_processors=cpu_count() - 1):

    num_vars = len(target_parameters)
    parameter_names = list(target_parameters.keys())
    groups = None
    bounds = [target_parameters[name] for name in parameter_names]

    problem = {
        'num_vars': num_vars,
        'names': parameter_names,
        'groups': groups,
        'bounds': bounds
    }

    parameter_values = sample(problem,
                              N=n_trajectories,
                              num_levels=num_levels,
                              grid_jump=grid_jump,
                              optimal_trajectories=None)

    ys = None

    if n_processors > 1:
        chunks = np.array_split(parameter_values, n_processors)
        chunks = [(parameter_names, chunk, target_output_name)
                  for chunk in chunks]
        pool = Pool(n_processors)
        results = pool.map(hdmpp.generate_outputs, chunks)
        ys = np.concatenate(results)
    else:
        ys = hdmpp.generate_outputs(
            (parameter_names, parameter_values, target_output_name))

    sis = morris.analyze(problem,
                         parameter_values,
                         np.array(ys),
                         conf_level=0.95,
                         print_to_console=False,
                         num_levels=num_levels,
                         grid_jump=grid_jump,
                         num_resamples=100)

    return problem, parameter_values, sis
예제 #24
0
def sensiAnal(model_results, Problem):
    weather = []
    X = []
    Y = []
    for row in model_results:
        weather.append(row[0])
        X.append(row[1:len(row) - 2])
        Y.append(row[len(row) - 1])

    climate = [
        '1A', '2A', '2B', '3A', '3B', '3C', '4A', '4B', '4C', '5A', '5B', '6A',
        '6B', '7A', '8A'
    ]

    Mu = []
    Sigma = []
    Name = []
    Clim = []

    for x in climate:
        X_clim = []
        Y_clim = []
        for ind, val in enumerate(weather):
            if val == x:
                X_clim.append(X[ind])
                Y_clim.append(Y[ind])
        for row in Problem:
            if row[0] == x:
                problem = row[1]
        if len(X_clim) > 0:
            Si = morris.analyze(problem,
                                np.array(X_clim),
                                np.array(Y_clim),
                                conf_level=0.95,
                                print_to_console=True,
                                num_levels=4,
                                grid_jump=2)

            mu_clim = Si['mu_star']
            sigma_clim = Si['sigma']
            name_clim = Si['names']

            Mu.append(mu_clim)
            Sigma.append(sigma_clim)
            Name.append(name_clim)
            Clim.append(x)

    return Clim, Name, Mu, Sigma
예제 #25
0
    def _analizar(símismo, vec_res, muestra, ops):

        if símismo.método == 'sobol':
            return sobol.analyze(problem=símismo.problema, Y=vec_res, **ops)
        elif símismo.método == 'fast':
            return fast.analyze(problem=símismo.problema, Y=vec_res, **ops)
        elif símismo.método == 'morris':
            return morris_anlz.analyze(problem=símismo.problema, X=muestra, Y=vec_res, **ops)
        elif símismo.método == 'dmim':
            return delta.analyze(problem=símismo.problema, X=muestra, Y=vec_res, **ops)
        elif símismo.método == 'dgsm':
            return dgsm.analyze(problem=símismo.problema, X=muestra, Y=vec_res, **ops)
        elif símismo.método == 'ff':
            return ff_anlz.analyze(problem=símismo.problema, X=muestra, Y=vec_res, **ops)
        else:
            raise ValueError('Método de análisis de sensibilidad "{}" no reconocido.'.format(símismo.método))
예제 #26
0
    def morris(self):
        """Morris Method sensitivity of the objective function.
        This function estimates the sensitivity with the Morris Method of the
        objective function with changes in the parameters using SALib:
        https://salib.readthedocs.io/en/latest/api.html#method-of-morris

        Returns:
            dict: sensitivity values of parameters; dict has keys 'mu',
                'mu_star', 'sigma', and 'mu_star_conf'
        """
        X, y, problem = self._sensitivity_prep()
        n_sample = 2000
        param_values = morris.sample(problem, n_sample)
        X_s, y_s = self._closest_points(problem, X, y, param_values)
        Si = morris.analyze(problem, X_s, y_s)
        return Si
예제 #27
0
    def test_regression_morris_groups(self, set_seed):
        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami_groups.txt'
        problem = read_param_file(param_file)

        param_values = sample(problem=problem, N=10000,
                              num_levels=4,
                              optimal_trajectories=None)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem, param_values, Y,
                            conf_level=0.95, print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu_star'], [7.610322, 10.197014],
                        atol=0, rtol=1e-5)
예제 #28
0
    def test_regression_morris_groups(self, set_seed):
        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami_groups.txt'
        problem = read_param_file(param_file)

        param_values = sample(problem=problem, N=10000,
                              num_levels=4,
                              optimal_trajectories=None)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem, param_values, Y,
                            conf_level=0.95, print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu_star'], [7.610322, 10.197014],
                        atol=0, rtol=1e-5)
예제 #29
0
    def test_regression_morris_vanilla(self, set_seed):
        """Note that this is a poor estimate of the Ishigami
        function.
        """
        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami.txt'
        problem = read_param_file(param_file)
        param_values = sample(problem, 10000, 4,
                              optimal_trajectories=None)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem, param_values, Y,
                            conf_level=0.95, print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu_star'], [7.536586, 7.875, 6.308785],
                        atol=0, rtol=1e-5)
예제 #30
0
    def test_regression_morris_vanilla(self, set_seed):
        """Note that this is a poor estimate of the Ishigami
        function.
        """
        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami.txt'
        problem = read_param_file(param_file)
        param_values = sample(problem, 10000, 4,
                              optimal_trajectories=None)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem, param_values, Y,
                            conf_level=0.95, print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu_star'], [7.536586, 7.875, 6.308785],
                        atol=0, rtol=1e-5)
예제 #31
0
    def evaluate(self):
        """

        :param y: A Numpy array containing the model outputs of dtype=float
        :return: A dictionary of sensitivity indices containing the following entries.
            - `mu` - the mean elementary effect
            - `mu_star` - the absolute of the mean elementary effect
            - `sigma` - the standard deviation of the elementary effect
            - `mu_star_conf` - the bootstrapped confidence interval
            - `names` - the names of the parameters
        """
        if self.y is None:
            raise NameError('y is not defined. run e+ models first')
        self.si = analyze(self.problem,
                          self.X,
                          self.y,
                          num_levels=self.num_levels)
        return self.si
예제 #32
0
def main():
    #print param
    param = np.array([
        ["T",0,.75],
        ["rho",0,1],
        ["R",10,50],
        ["D",0,5],
        ["s",0,.6],
    ])
    np.savetxt('parameters.txt',param,fmt='%s',delimiter=' ')
    # Generate samples
    param_values = morris_oat.sample(100, "parameters.txt", num_levels=10, grid_jump=5)
    # Save the parameter values in a file (they are needed in the analysis)
    np.savetxt('model_input.txt', param_values, delimiter=' ')

    
    Y = np.array(POOL.map(measure_tau,param_values))
    np.savetxt("model_output.txt", Y, delimiter=' ')

    # Perform the sensitivity analysis using the model output
    Si = morris.analyze('parameters.txt', 'model_input.txt', 'model_output.txt',
                        column=0, conf_level=0.95, print_to_console=False)

    with open("data.pkle","w") as f:
        pkle.dump({"X": param_values, "Y":Y, "Morris":Si},f)
    metadata("data.pkle")

    
    plt.scatter(Si["mu_star"],Si["sigma"])

    for x,y,s in zip(Si["mu_star"],Si["sigma"],param[:,0]):
        
        plt.annotate(s,(x,y), xytext=(5, 5),textcoords='offset points')
            
    plt.xlabel(r"$\mu^*$")
    plt.ylabel(r"$\sigma$")
        
    plt.savefig("sensitivity_with_morris.png")
    metadata("sensitivity_with_morris.png")

    plt.savefig("sensitivity_with_morris.eps")
    metadata("sensitivity_with_morris.eps")
        
    return Si
예제 #33
0
    def test_regression_morris_groups_local_optim(self, set_seed):
        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami_groups.txt'
        problem = read_param_file(param_file)

        param_values = sample(problem=problem, N=500,
                              num_levels=4,
                              optimal_trajectories=20,
                              local_optimization=True)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem, param_values, Y,
                            conf_level=0.95, print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu_star'],
                        [13.95285, 7.875],
                        rtol=1e-5)
예제 #34
0
def test_analysis_of_morris_results():
    '''
    Tests a one-dimensional vector of results
    
    Taken from the solution to Exercise 4 (p.138) in Saltelli (2008).
    '''
    model_input = np.array([[0, 1. / 3], [0, 1], [2. / 3, 1],
                             [0, 1. / 3], [2. / 3, 1. / 3], [2. / 3, 1],
                             [2. / 3, 0], [2. / 3, 2. / 3], [0, 2. / 3],
                             [1. / 3, 1], [1, 1], [1, 1. / 3],
                             [1. / 3, 1], [1. / 3, 1. / 3], [1, 1. / 3],
                             [1. / 3, 2. / 3], [1. / 3, 0], [1, 0]],
                            dtype=np.float)

    model_output = np.array([0.97, 0.71, 2.39, 0.97, 2.30, 2.39, 
                             1.87, 2.40, 0.87, 2.15, 1.71, 1.54, 
                             2.15, 2.17, 1.54, 2.20, 1.87, 1.0],
                       dtype=np.float)

    problem = {
     'num_vars': 2,
     'names': ['Test 1', 'Test 2'],
     'groups': None,
     'bounds': [[0.0, 1.0], [0.0, 1.0]]
    }

    Si = analyze(problem, model_input, model_output,
                 num_resamples=1000,
                 conf_level=0.95,
                 print_to_console=False)

    desired_mu = np.array([0.66, 0.21])
    assert_allclose(Si['mu'], desired_mu, rtol=1e-1, 
                    err_msg="The values for mu are incorrect")
    desired_mu_star = np.array([1.62, 0.35])
    assert_allclose(Si['mu_star'], desired_mu_star, rtol=1e-2, 
                    err_msg="The values for mu star are incorrect")
    desired_sigma = np.array([1.79, 0.41])
    assert_allclose(Si['sigma'], desired_sigma, rtol=1e-2, 
                    err_msg="The values for sigma are incorrect")
    desired_names = ['Test 1', 'Test 2']
    assert_equal(Si['names'], desired_names, 
                 err_msg="The values for names are incorrect")
예제 #35
0
    def test_regression_morris_groups_local_optim(self, set_seed):
        set_seed
        param_file = 'src/SALib/test_functions/params/Ishigami_groups.txt'
        problem = read_param_file(param_file)

        param_values = sample(problem=problem, N=500,
                              num_levels=4,
                              optimal_trajectories=20,
                              local_optimization=True)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem, param_values, Y,
                            conf_level=0.95, print_to_console=False,
                            num_levels=4)

        assert_allclose(Si['mu_star'],
                        [13.95285, 7.875],
                        rtol=1e-5)
예제 #36
0
def test_regression_morris_optimal():
    '''
    Tests the use of optimal trajectories with Morris.

    Note that the relative tolerance is set to a very high value (default is 1e-05)
    due to the coarse nature of the num_levels and grid_jump.
    '''
    param_file = 'SALib/test_functions/params/Ishigami.txt'
    problem = read_param_file(param_file)
    param_values = sample(problem=problem, N=20, \
                          num_levels=4, grid_jump=2, \
                          optimal_trajectories=9)

    Y = Ishigami.evaluate(param_values)

    Si = morris.analyze(problem, param_values, Y,
                        conf_level=0.95, print_to_console=False,
                        num_levels=4, grid_jump=2)

    assert_allclose(Si['mu_star'], [8.1, 2.2, 5.4], rtol=10)
예제 #37
0
def plot_morris_by_leaf_by_boot(df_out,
                                variable='normalized_audpc',
                                parameter_range_file='param_range_SA.txt',
                                input_file='morris_input.txt',
                                nboots=5,
                                ylims=None):
    problem = read_param_file(parameter_range_file)
    fig, axs = plt.subplots(6, 2, figsize=(15, 30))
    colors = iter(['b', 'g', 'r', 'k', 'm', 'c', 'y'])
    colors = {b: next(colors) for b in range(nboots)}
    for i, ax in enumerate(axs.flat):
        lf = i + 1
        for boot in np.unique(df_out['i_boot']):
            param_values = np.loadtxt(input_file[:-4] + '_boot' + str(boot) +
                                      input_file[-4:])
            df = df_out[(df_out['i_boot'] == boot)
                        & (df_out['num_leaf_top'] == lf)]
            Y = df[variable]
            Si_bt = morris.analyze(problem,
                                   param_values,
                                   Y,
                                   grid_jump=5,
                                   num_levels=10,
                                   conf_level=0.95,
                                   print_to_console=False)
            for ip, param in enumerate(Si_bt['names']):
                ax.plot(Si_bt['mu_star'][ip],
                        Si_bt['sigma'][ip],
                        color=colors[boot],
                        marker='*')
                ax.annotate(param, (Si_bt['mu_star'][ip], Si_bt['sigma'][ip]))
        if ylims is not None:
            ax.set_ylim(ylims)
            ax.set_xlim(ylims)
        ax.annotate('Leaf %d' % lf,
                    xy=(0.05, 0.85),
                    xycoords='axes fraction',
                    fontsize=18)
예제 #38
0
    def test_regression_morris_vanilla(self, set_seed):
        set_seed
        param_file = 'SALib/test_functions/params/Ishigami.txt'
        problem = read_param_file(param_file)
        param_values = sample(problem=problem,
                              N=10000,
                              num_levels=4,
                              grid_jump=2,
                              optimal_trajectories=None)

        Y = Ishigami.evaluate(param_values)

        Si = morris.analyze(problem,
                            param_values,
                            Y,
                            conf_level=0.95,
                            print_to_console=False,
                            num_levels=4,
                            grid_jump=2)

        assert_allclose(Si['mu_star'], [7.701555, 7.875, 6.288788],
                        atol=0,
                        rtol=1e-5)
예제 #39
0
# }

# Files with a 4th column for "group name" will be detected automatically, e.g.:
# param_file = '../../SALib/test_functions/params/Ishigami_groups.txt'

# Generate samples
param_values = sample(problem, N=1000, num_levels=4, grid_jump=2, \
                      optimal_trajectories=None)

# To use optimized trajectories (brute force method), give an integer value for optimal_trajectories

# Run the "model" -- this will happen offline for external models
Y = Sobol_G.evaluate(param_values)

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
Si = morris.analyze(problem, param_values, Y, conf_level=0.95, 
                    print_to_console=True,
                    num_levels=4, grid_jump=2, num_resamples=100)
# Returns a dictionary with keys 'mu', 'mu_star', 'sigma', and 'mu_star_conf'
# e.g. Si['mu_star'] contains the mu* value for each parameter, in the
# same order as the parameter file

fig, (ax1, ax2) = plt.subplots(1, 2)
horizontal_bar_plot(ax1, Si,{}, sortby='mu_star', unit=r"tCO$_2$/year")
covariance_plot(ax2, Si, {}, unit=r"tCO$_2$/year")

fig2 = plt.figure()
sample_histograms(fig2, param_values, problem, {'color':'y'})
plt.show()
예제 #40
0
파일: morris.py 프로젝트: Runnnning/SALib
# Files with a 4th column for "group name" will be detected automatically, e.g.
# param_file = '../../SALib/test_functions/params/Ishigami_groups.txt'

# Generate samples
param_values = sample(problem, N=1000, num_levels=4,
                      optimal_trajectories=None)

# To use optimized trajectories (brute force method),
# give an integer value for optimal_trajectories

# Run the "model" -- this will happen offline for external models
Y = Sobol_G.evaluate(param_values)

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
Si = morris.analyze(problem, param_values, Y, conf_level=0.95,
                    print_to_console=True,
                    num_levels=4, num_resamples=100)
# Returns a dictionary with keys 'mu', 'mu_star', 'sigma', and 'mu_star_conf'
# e.g. Si['mu_star'] contains the mu* value for each parameter, in the
# same order as the parameter file

fig, (ax1, ax2) = plt.subplots(1, 2)
horizontal_bar_plot(ax1, Si, {}, sortby='mu_star', unit=r"tCO$_2$/year")
covariance_plot(ax2, Si, {}, unit=r"tCO$_2$/year")

fig2 = plt.figure()
sample_histograms(fig2, param_values, problem, {'color': 'y'})
plt.show()
예제 #41
0
    partial_order = {}
    mu_st, sigma_dt = {}, {}
    rank_low_dt, rank_up_dt = {}, {}
    n_start, n_end, n_step = 20, 120, 10
    x_large_size = sample_morris.sample(problem, n_end, num_levels=4)
    for i in range(n_start, n_end, n_step):
        # partial ordering
        x_morris = x_large_size[:i * (len_params + 1)]
        if i == n_start:
            y_morris = evaluate(x_morris, a)
        else:
            y_eval = evaluate(x_morris[-(len_params + 1) * n_step:], a)
            y_morris = np.append(y_morris, y_eval)
        sa_dict = analyze_morris.analyze(problem,
                                         x_morris,
                                         y_morris,
                                         num_resamples=1000,
                                         conf_level=0.95,
                                         seed=123)
        mu_star_rank_dict = sa_dict['mu_star'].argsort().argsort()
        # use toposort to find parameter sa block
        conf_low = sa_dict['mu_star_rank_conf'][0]
        conf_up = sa_dict['mu_star_rank_conf'][1]

        abs_sort = partial_rank(len_params, conf_low, conf_up)
        rank_list = list(toposort(abs_sort))
        key = 'result_' + str(i)
        partial_order[key] = {
            j: list(rank_list[j])
            for j in range(len(rank_list))
        }
        #save results returned from Morris if needed
예제 #42
0
def sa(model, response, policy={}, method="sobol", nsamples=1000, **kwargs):
    if len(model.uncertainties) == 0:
        raise ValueError("no uncertainties defined in model")

    problem = {
        'num_vars': len(model.uncertainties),
        'names': model.uncertainties.keys(),
        'bounds': [[0.0, 1.0] for u in model.uncertainties],
        'groups': kwargs.get("groups", None)
    }

    # estimate the argument N passed to the sampler that produces the requested
    # number of samples
    N = _predict_N(method, nsamples, problem["num_vars"], kwargs)

    # generate the samples
    if method == "sobol":
        samples = saltelli.sample(problem, N,
                                  **_cleanup_kwargs(saltelli.sample, kwargs))
    elif method == "morris":
        samples = morris_sampler.sample(
            problem, N, **_cleanup_kwargs(morris_sampler.sample, kwargs))
    elif method == "fast":
        samples = fast_sampler.sample(
            problem, N, **_cleanup_kwargs(fast_sampler.sample, kwargs))
    elif method == "ff":
        samples = ff_sampler.sample(
            problem, **_cleanup_kwargs(ff_sampler.sample, kwargs))
    elif method == "dgsm":
        samples = finite_diff.sample(
            problem, N, **_cleanup_kwargs(finite_diff.sample, kwargs))
    elif method == "delta":
        if "samples" in kwargs:
            samples = kwargs["samples"]
        else:
            samples = latin.sample(problem, N,
                                   **_cleanup_kwargs(latin.sample, kwargs))

    # convert from samples in [0, 1] to uncertainty domain
    for i, u in enumerate(model.uncertainties):
        samples[:, i] = u.ppf(samples[:, i])

    # run the model and collect the responses
    responses = np.empty(samples.shape[0])

    for i in range(samples.shape[0]):
        sample = {k: v for k, v in zip(model.uncertainties.keys(), samples[i])}
        responses[i] = evaluate(model, overwrite(sample, policy))[response]

    # run the sensitivity analysis method
    if method == "sobol":
        result = sobol.analyze(problem, responses,
                               **_cleanup_kwargs(sobol.analyze, kwargs))
    elif method == "morris":
        result = morris_analyzer.analyze(
            problem, samples, responses,
            **_cleanup_kwargs(morris_analyzer.analyze, kwargs))
    elif method == "fast":
        result = fast.analyze(problem, responses,
                              **_cleanup_kwargs(fast.analyze, kwargs))
    elif method == "ff":
        result = ff_analyzer.analyze(
            problem, samples, responses,
            **_cleanup_kwargs(ff_analyzer.analyze, kwargs))
    elif method == "dgsm":
        result = dgsm.analyze(problem, samples, responses,
                              **_cleanup_kwargs(dgsm.analyze, kwargs))
    elif method == "delta":
        result = delta.analyze(problem, samples, responses,
                               **_cleanup_kwargs(delta.analyze, kwargs))

    # convert the SALib results into a form allowing pretty printing and
    # lookups using the parameter name
    pretty_result = SAResult(
        list(result["names"] if "names" in result else problem["names"]))

    if "S1" in result:
        pretty_result["S1"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["S1"])
        }
    if "S1_conf" in result:
        pretty_result["S1_conf"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["S1_conf"])
        }
    if "ST" in result:
        pretty_result["ST"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["ST"])
        }
    if "ST_conf" in result:
        pretty_result["ST_conf"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["ST_conf"])
        }
    if "S2" in result:
        pretty_result["S2"] = _S2_to_dict(result["S2"], problem)
    if "S2_conf" in result:
        pretty_result["S2_conf"] = _S2_to_dict(result["S2_conf"], problem)
    if "delta" in result:
        pretty_result["delta"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["delta"])
        }
    if "delta_conf" in result:
        pretty_result["delta_conf"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["delta_conf"])
        }
    if "vi" in result:
        pretty_result["vi"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["vi"])
        }
    if "vi_std" in result:
        pretty_result["vi_std"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["vi_std"])
        }
    if "dgsm" in result:
        pretty_result["dgsm"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["dgsm"])
        }
    if "dgsm_conf" in result:
        pretty_result["dgsm_conf"] = {
            k: float(v)
            for k, v in zip(problem["names"], result["dgsm_conf"])
        }
    if "mu" in result:
        pretty_result["mu"] = {
            k: float(v)
            for k, v in zip(result["names"], result["mu"])
        }
    if "mu_star" in result:
        pretty_result["mu_star"] = {
            k: float(v)
            for k, v in zip(result["names"], result["mu_star"])
        }
    if "mu_star_conf" in result:
        pretty_result["mu_star_conf"] = {
            k: float(v)
            for k, v in zip(result["names"], result["mu_star_conf"])
        }
    if "sigma" in result:
        pretty_result["sigma"] = {
            k: float(v)
            for k, v in zip(result["names"], result["sigma"])
        }

    return pretty_result
예제 #43
0
def plot_morris_one_leaf(df_out, problem, leaf=1, ax=None,
                         variable='normalized_audpc',
                         input_file='morris_input.txt',
                         folder='septoria',
                         nboots=5, ylims=None, force_rename={},
                         markers_SA={}, add_legend=True, colored=False,
                         annotation_suffix='', markersize=8, return_legend=False):
    if ax is None:
        fig, ax = plt.subplots()
    df_mu_lf = pd.DataFrame()
    df_sigma_lf = pd.DataFrame()
    for boot in np.unique(df_out['i_boot']):
        param_values = np.loadtxt('./' + folder + '/' + input_file[:-4] + '_boot' + str(boot) + input_file[-4:])
        df = df_out[(df_out['i_boot'] == boot) & (df_out['num_leaf_top'] == leaf)]
        Y = df[variable]
        Si_bt = morris.analyze(problem, param_values, Y, grid_jump=5,
                               num_levels=10, conf_level=0.95,
                               print_to_console=False)
        for ip, param in enumerate(Si_bt['names']):
            if param != 'proba_main_nff':
                df_mu_lf.loc[boot, param] = Si_bt['mu_star'][ip]
                df_sigma_lf.loc[boot, param] = Si_bt['sigma'][ip]
    mu_star = df_mu_lf.mean().values
    mu_star_conf = df_mu_lf.apply(conf_int).values
    sigma = df_sigma_lf.mean().values
    sigma_conf = df_sigma_lf.apply(conf_int).values
    # ax.errorbar(mu_star, sigma, yerr=sigma_conf, xerr=mu_star_conf,
    # color='b', marker='*', linestyle='')
    tags = iter(df_mu_lf.columns)
    markers = itertools.cycle(['o', '^', 'v', 's', 'p', '*', 'd', 'D', '<', '>'])
    colors = itertools.cycle(['b', 'g', 'r', 'k', 'm', 'c'])
    labels = []
    proxys = []
    for x, y in zip(mu_star, sigma):
        tag = tags.next()
        if tag in markers_SA:
            marker = markers_SA[tag]
        else:
            marker = markers.next()
        if tag in force_rename:
            tag = force_rename[tag]
        if colored == True:
            color = next(colors)
        else:
            color = 'k'
        ax.plot(x, y, color=color, marker=marker, markersize=markersize)
        # ax.annotate(tag, (x,y))
        labels += [tag]
        proxys += [plt.Line2D((0, 1), (0, 0), color=color,
                              marker=marker, markersize=markersize, linestyle='None')]
    if ylims is not None:
        ax.set_ylim(ylims)
        ax.set_xlim(ylims)
    else:
        ylims = [min([ax.get_xlim()[0], ax.get_xlim()[0]]),
                 max([max(mu_star), max(sigma)]) * 1.05]
        ax.set_ylim(ylims)
        ax.set_xlim(ylims)
    ax.annotate('Leaf %d ' % leaf + annotation_suffix, xy=(0.05, 0.85),
                xycoords='axes fraction', fontsize=24)
    ax.set_ylabel(r"$\sigma$", fontsize=36)
    ax.set_xlabel(r"$\mu^\ast$", fontsize=36)
    ax.tick_params(axis='both', labelsize=24)
    if add_legend:
        lgd = ax.legend(proxys, labels, numpoints=1,
                        bbox_to_anchor=(1.01, 1.), loc=2, borderaxespad=0., fontsize=28)
    plt.rcParams['text.usetex'] = False
    if return_legend:
        return lgd
예제 #44
0
파일: morris.py 프로젝트: r2rahul/SALib
import sys
sys.path.append('../..')

from SALib.sample import morris_oat
from SALib.analyze import morris
from SALib.test_functions import Ishigami
import numpy as np

# Read the parameter range file and generate samples
param_file = '../../SALib/test_functions/params/Ishigami.txt'

# Generate samples
param_values = morris_oat.sample(1000, param_file, num_levels=10, grid_jump=5)

# Save the parameter values in a file (they are needed in the analysis)
np.savetxt('model_input.txt', param_values, delimiter=' ')

# Run the "model" and save the output in a text file
# This will happen offline for external models
Y = Ishigami.evaluate(param_values)
np.savetxt("model_output.txt", Y, delimiter=' ')

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
Si = morris.analyze(param_file, 'model_input.txt', 'model_output.txt',
                    column=0, conf_level=0.95, print_to_console=False)
# Returns a dictionary with keys 'mu', 'mu_star', 'sigma', and 'mu_star_conf'
# e.g. Si['mu_star'] contains the mu* value for each parameter, in the
# same order as the parameter file
예제 #45
0
파일: sa.py 프로젝트: arita37/Rhodium
def sa(model, response, policy={}, method="sobol", nsamples=1000, **kwargs):
    if len(model.uncertainties) == 0:
        raise ValueError("no uncertainties defined in model")
    
    problem = { 'num_vars' : len(model.uncertainties),
                'names' : model.uncertainties.keys(),
                'bounds' : [[0.0, 1.0] for u in model.uncertainties],
                'groups' : kwargs.get("groups", None) }

    # estimate the argument N passed to the sampler that produces the requested
    # number of samples
    N = _predict_N(method, nsamples, problem["num_vars"], kwargs)
    
    # generate the samples
    if method == "sobol":
        samples = saltelli.sample(problem, N, **_cleanup_kwargs(saltelli.sample, kwargs))
    elif method == "morris":
        samples = morris_sampler.sample(problem, N, **_cleanup_kwargs(morris_sampler.sample, kwargs))
    elif method == "fast":
        samples = fast_sampler.sample(problem, N, **_cleanup_kwargs(fast_sampler.sample, kwargs))
    elif method == "ff":
        samples = ff_sampler.sample(problem, **_cleanup_kwargs(ff_sampler.sample, kwargs))
    elif method == "dgsm":
        samples = finite_diff.sample(problem, N, **_cleanup_kwargs(finite_diff.sample, kwargs))
    elif method == "delta":
        if "samples" in kwargs:
            samples = kwargs["samples"]
        else:
            samples = latin.sample(problem, N, **_cleanup_kwargs(latin.sample, kwargs))
            
    # convert from samples in [0, 1] to uncertainty domain
    for i, u in enumerate(model.uncertainties):
        samples[:,i] = u.ppf(samples[:,i])
        
    # run the model and collect the responses
    responses = np.empty(samples.shape[0])
    
    for i in range(samples.shape[0]):
        sample = {k : v for k, v in zip(model.uncertainties.keys(), samples[i])}
        responses[i] = evaluate(model, overwrite(sample, policy))[response]
    
    # run the sensitivity analysis method
    if method == "sobol":
        result = sobol.analyze(problem, responses, **_cleanup_kwargs(sobol.analyze, kwargs))
    elif method == "morris":
        result = morris_analyzer.analyze(problem, samples, responses, **_cleanup_kwargs(morris_analyzer.analyze, kwargs))
    elif method == "fast":
        result = fast.analyze(problem, responses, **_cleanup_kwargs(fast.analyze, kwargs))
    elif method == "ff":
        result = ff_analyzer.analyze(problem, samples, responses, **_cleanup_kwargs(ff_analyzer.analyze, kwargs))
    elif method == "dgsm":
        result = dgsm.analyze(problem, samples, responses, **_cleanup_kwargs(dgsm.analyze, kwargs))
    elif method == "delta":
        result = delta.analyze(problem, samples, responses, **_cleanup_kwargs(delta.analyze, kwargs))
         
    # convert the SALib results into a form allowing pretty printing and
    # lookups using the parameter name
    pretty_result = SAResult(result["names"] if "names" in result else problem["names"])
    
    if "S1" in result:
        pretty_result["S1"] = {k : float(v) for k, v in zip(problem["names"], result["S1"])}
    if "S1_conf" in result:
        pretty_result["S1_conf"] = {k : float(v) for k, v in zip(problem["names"], result["S1_conf"])}
    if "ST" in result:
        pretty_result["ST"] = {k : float(v) for k, v in zip(problem["names"], result["ST"])}
    if "ST_conf" in result:
        pretty_result["ST_conf"] = {k : float(v) for k, v in zip(problem["names"], result["ST_conf"])}
    if "S2" in result:
        pretty_result["S2"] = _S2_to_dict(result["S2"], problem)
    if "S2_conf" in result:
        pretty_result["S2_conf"] = _S2_to_dict(result["S2_conf"], problem)
    if "delta" in result:
        pretty_result["delta"] = {k : float(v) for k, v in zip(problem["names"], result["delta"])}
    if "delta_conf" in result:
        pretty_result["delta_conf"] = {k : float(v) for k, v in zip(problem["names"], result["delta_conf"])}
    if "vi" in result:
        pretty_result["vi"] = {k : float(v) for k, v in zip(problem["names"], result["vi"])}
    if "vi_std" in result:
        pretty_result["vi_std"] = {k : float(v) for k, v in zip(problem["names"], result["vi_std"])}
    if "dgsm" in result:
        pretty_result["dgsm"] = {k : float(v) for k, v in zip(problem["names"], result["dgsm"])}
    if "dgsm_conf" in result:
        pretty_result["dgsm_conf"] = {k : float(v) for k, v in zip(problem["names"], result["dgsm_conf"])}
    if "mu" in result:
        pretty_result["mu"] = {k : float(v) for k, v in zip(result["names"], result["mu"])}
    if "mu_star" in result:
        pretty_result["mu_star"] = {k : float(v) for k, v in zip(result["names"], result["mu_star"])}
    if "mu_star_conf" in result:
        pretty_result["mu_star_conf"] = {k : float(v) for k, v in zip(result["names"], result["mu_star_conf"])}
    if "sigma" in result:
        pretty_result["sigma"] = {k : float(v) for k, v in zip(result["names"], result["sigma"])}

    return pretty_result
sample


# ### Factor Prioritisation
# 
# We'll run a sensitivity analysis to see which is the most influential parameter.
# 
# The results parameters are called **mu**, **sigma** and **mu_star**.
# 
# * **Mu** is the mean effect caused by the input parameter being moved over its range.
# * **Sigma** is the standard deviation of the mean effect.
# * **Mu_star** is the mean absolute effect.

# In[21]:

Si = ma.analyze(morris_problem, sample, output, print_to_console=False)
print("{:20s} {:>7s} {:>7s} {:>7s}".format("Name", "mu", "mu_star", "sigma"))
for name, s1, st, mean in zip(morris_problem['names'], Si['mu'], Si['mu_star'], Si['sigma']):
    print("{:20s} {:=7.2f} {:=7.2f} {:=7.2f}".format(name, s1, st, mean))


# We can plot the results

# In[22]:

fig, (ax1, ax2) = plt.subplots(1,2)
mp.horizontal_bar_plot(ax1, Si, param_dict={})
mp.covariance_plot(ax2, Si, {})


# ## Sanity check
def sensitivity_main(locator, weather_path, gv, output_parameters, groups_var, num_samples, method):
    """
    This function creates the sensitivity analysis problem for either sobol or morris methods.
    It calculates the number of samples for the analysis and calls the CEA to run every sample.

    :param locator: locator class
    :param weather_path: path to weather file
    :param gv: global variables class
    :param output_parameters: list of output parameters to analyse
    :param groups_var: list of names of groups of variables to analyse. Possible  values are:
    'THERMAL', 'ARCHITECTURE', 'INDOOR_COMFORT', 'INTERNAL_LOADS'. This list links to the probability density functions
    of the variables contained in locator.get_uncertainty_db().
    :param num_samples: number of samples to calculate
    :param method: 'morris' or 'sobol' method
    :return: .xls file stored in locator.get_sensitivity_output(). every spreadsheet of the workbook
    stores a matrix whose content is the output of one sensitivity parameter and one output_parameter:

    - columns: groups of variables to anlyse.
    - rows: number of buildings of the case study under analysis.
    - content: sensitivity parameter per output parameter

    every sensitivity parameter depends on the method:

    - sobol: S1, ST and ST_conf >>for more information refereto SaBil documentation
    - morris: mu_star, sigma and mu_star_conf >> for more information refereto SaBil documentation

    """
    t0 = time.clock()

    # Model constants
    gv.multiprocessing = False  # false to deactivate the multiprocessing in the demand algorithm

    # write only monthly instead of hourly values
    gv.demand_writer = cea.demand.demand_writers.MonthlyDemandWriter(gv)

    # Define the model inputs
    pdf = pd.concat([pd.read_excel(locator.get_uncertainty_db(), group, axis=1) for group in groups_var])

    num_vars = pdf.name.count()  # integer with number of variables
    names = pdf.name.values  # [,,] with names of each variable
    bounds = []
    for var in range(num_vars):
        limits = [pdf.loc[var, 'min'], pdf.loc[var, 'max']]
        bounds.append(limits)

    # define the problem
    problem = {'num_vars': num_vars, 'names': names, 'bounds': bounds, 'groups': None}

    # create samples (combinations of variables)
    if method is 'sobol':
        second_order = False
        samples = sampler_sobol(problem, N=num_samples, calc_second_order=second_order)
    else:
        grid = 2
        levels = 4
        optimal_trajects = int(0.04 * num_samples)
        samples = sampler_morris(problem, N=num_samples, grid_jump=grid, num_levels=levels)
                                 #optimal_trajectories=optimal_trajects, local_optimization=True)
    gv.log('Sampling done, time elapsed: %(time_elapsed).2f seconds', time_elapsed=time.clock() - t0)
    gv.log('Running %i samples' %len(samples))

    #call the CEA for building demand and store the results of every sample in a vector
    simulations = screening_cea_multiprocessing(samples, names, output_parameters, locator, weather_path, gv)

    gv.log('Simulations done - time elapsed: %(time_elapsed).2f seconds', time_elapsed=time.clock() - t0)
    #do morris analysis and output to excel

    buildings_num = simulations[0].shape[0]
    writer = pd.ExcelWriter(locator.get_sensitivity_output(method, num_samples))
    for parameter in output_parameters:
        results_1 = []
        results_2 = []
        results_3 = []
        for building in range(buildings_num):
            simulations_parameter = np.array([x.loc[building, parameter] for x in simulations])
            if method is 'sobol':
                VAR1, VAR2, VAR3 = 'S1', 'ST', 'ST_conf'
                sobol_result = sobol.analyze(problem, simulations_parameter, calc_second_order=second_order)
                results_1.append(sobol_result['S1'])
                results_2.append(sobol_result['ST'])
                results_3.append(sobol_result['ST_conf'])
            else:
                VAR1, VAR2, VAR3 = 'mu_star', 'sigma', 'mu_star_conf'
                morris_result = morris.analyze(problem, samples, simulations_parameter, grid_jump=grid, num_levels=levels)
                results_1.append(morris_result['mu_star'])
                results_2.append(morris_result['sigma'])
                results_3.append(morris_result['mu_star_conf'])
        pd.DataFrame(results_1, columns=problem['names']).to_excel(writer, parameter + VAR1)
        pd.DataFrame(results_2, columns=problem['names']).to_excel(writer, parameter + VAR2)
        pd.DataFrame(results_3, columns=problem['names']).to_excel(writer, parameter + VAR3)

    writer.save()
    gv.log('Sensitivity analysis done - time elapsed: %(time_elapsed).2f seconds', time_elapsed=time.clock() - t0)