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)
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)
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)
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)
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)
def gsa_analyse(self): return [ ma.analyze(self.morris_problem, self.samples, np.array(score), num_levels=4) for score in self.scores ]
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"])
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
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, )
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)
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))
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")
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()
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)
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)
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, )
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)
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)
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'])
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
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
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))
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
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)
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)
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
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
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)
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")
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)
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)
# } # 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()
# 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()
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
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
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
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
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)