Exemple #1
0
def test_Delta_with_NAN():
    '''
    Test if delta.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):
        delta.analyze(problem, param_values, model_results)
def calcSindices(param_bounds, policy):
    x1 = np.linspace(param_bounds[0, 0], param_bounds[0, 1], 100)
    y1 = np.linspace(param_bounds[1, 0], param_bounds[1, 1], 100)
    xv, yv = np.meshgrid(x1, y1)
    x = xv.flatten()
    y = yv.flatten()
    if policy == 1:
        z = (x + 1) + -4 * y + (x + 1) * y + 1
    else:
        z = (x + 1) + -3 * y + (x + 1) * y

    param_names = ['x', 'y']
    params_no = len(param_names)
    problem = {
        'num_vars': params_no,
        'names': param_names,
        'bounds': param_bounds.tolist()
    }
    samples = np.transpose(np.array([x, y]))

    result = delta.analyze(problem,
                           samples,
                           z,
                           print_to_console=False,
                           num_resamples=2)

    return result, x1, y1, z
Exemple #3
0
def x_near__SA(ensemble_dir,
               these_varnames,
               thresh=1.05,
               varname='p_infect',
               last_scenario='none'):
    X, problem, labs = get_X(ensemble_dir,
                             these_varnames,
                             last_scenario='none')
    default_case_options = {'acr_enhancement': 1.}
    dxs, vardat_default = get_ensemble_dat(varname,
                                           ensemble_dir,
                                           default_case_options,
                                           dispersion_type='both',
                                           dxval='all',
                                           last_scenario=last_scenario)
    dxs, vardat_reflections = get_ensemble_dat(varname,
                                               ensemble_dir,
                                               default_case_options,
                                               dispersion_type='reflections',
                                               dxval='all')
    x_near = np.zeros(vardat_default.shape[0])
    for ii in range(vardat_default.shape[0]):
        x_near[ii] = interp1d((vardat_default / vardat_reflections)[ii, :],
                              dxs,
                              fill_value='extrapolate')(thresh)

    idx, = np.where(~np.isnan(x_near))
    output_delta = delta.analyze(problem, X[idx, :], x_near[idx])
    return output_delta
def sensitivity_analysis_per_structure(ID):
    '''
    Perform analysis for shortage magnitude
    '''
    DELTA = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
    DELTA_conf = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
    S1 = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
    S1_conf = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
    R2_scores = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
    DELTA.index=DELTA_conf.index=S1.index=S1_conf.index = R2_scores.index = param_names
    SYN_short = np.zeros([len(HIS_short), samples * realizations])
    for j in range(samples):
        data= np.loadtxt('../../../'+design+'/Infofiles/' +  ID + '/' + ID + '_info_' + str(rows_to_keep[j]+1) + '.txt')
        # replace failed runs with np.nan (currently -999.9)
        data[data < 0] = np.nan
        try:
            SYN_short[:,j*realizations:j*realizations+realizations]=data[:,idx]
        except IndexError:
            print(ID + '_info_' + str(j+1))
    # Reshape into water years
    # Create matrix of [no. years x no. months x no. experiments]
    f_SYN_short = np.zeros([int(np.size(HIS_short)/n),n, samples*realizations])
    for i in range(samples*realizations):
        f_SYN_short[:,:,i]= np.reshape(SYN_short[:,i], (int(np.size(SYN_short[:,i])/n), n))

    # Shortage per water year
    f_SYN_short_WY = np.sum(f_SYN_short,axis=1)

    # Identify droughts at percentiles
    syn_magnitude = np.zeros([len(percentiles),samples*realizations])
    for j in range(samples*realizations):
        syn_magnitude[:,j]=[np.percentile(f_SYN_short_WY[:,j], i) for i in percentiles]
    
    # Delta Method analysis
    for i in range(len(percentiles)):
        if syn_magnitude[i,:].any():
            try:
                result= delta.analyze(problem, np.repeat(LHsamples, realizations, axis = 0), syn_magnitude[i,:], print_to_console=False, num_resamples=2)
                DELTA[percentiles[i]]= result['delta']
                DELTA_conf[percentiles[i]] = result['delta_conf']
                S1[percentiles[i]]=result['S1']
                S1_conf[percentiles[i]]=result['S1_conf']
            except:
                pass

    S1.to_csv('../../../'+design+'/Magnitude_Sensitivity_analysis/'+ ID + '_S1.csv')
    S1_conf.to_csv('../../../'+design+'/Magnitude_Sensitivity_analysis/'+ ID + '_S1_conf.csv')
    DELTA.to_csv('../../../'+design+'/Magnitude_Sensitivity_analysis/'+ ID + '_DELTA.csv')
    DELTA_conf.to_csv('../../../'+design+'/Magnitude_Sensitivity_analysis/'+ ID + '_DELTA_conf.csv')

    # OLS regression analysis
    dta = pd.DataFrame(data = np.repeat(LHsamples, realizations, axis = 0), columns=param_names)
    for i in range(len(percentiles)):
        dta['Shortage']=syn_magnitude[i,:]
        for m in range(params_no):
            predictors = dta.columns.tolist()[m:(m+1)]
            result = fitOLS(dta, predictors)
            R2_scores.at[param_names[m],percentiles[i]]=result.rsquared
    R2_scores.to_csv('../../../'+design+'/Magnitude_Sensitivity_analysis/'+ ID + '_R2.csv')
Exemple #5
0
def calculate_sensitivities(trace, spec):
    """Calculates delta moment-independent sensitivities for specified inputs and outputs."""
    ins_list = list(spec.ins)
    ins = np.stack([trace[i] for i in ins_list], axis=1)
    problem = {"num_vars": len(spec.ins), "names": ins_list}
    return [
        sort_sensitivities(delta.analyze(problem, ins, trace[out])) for out in spec.outs
    ]
Exemple #6
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
Exemple #7
0
def Sobol_per_structure(design, ID):
    # get problem parameters (parameters, ranges, samples)
    param_bounds, param_names, params_no, problem = setupProblem(design)
    samples, rows_to_keep = getSamples(design, params_no, param_bounds)
    
    # constants
    percentiles = np.arange(0,100)
    nsamples = len(rows_to_keep)
    nrealizations = 10
    idx = np.arange(2,22,2)
    nyears = 105
    nmonths = 12
    
    # initiate dataframes to store sensitivity results
    S1 = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
    S1_conf = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
    R2_scores = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
    S1.index=S1_conf.index = R2_scores.index = param_names
    
    # load shortage data for this experimental design
    SYN_short = np.load('../Simulation_outputs/' + design + '/' + ID + '_info.npy')
    # remove columns for year (0) and demand (odd columns) and convert to m^3
    SYN_short = SYN_short[:,idx,:]*1233.48
    SYN_short = SYN_short[:,:,rows_to_keep]
    # replace failed runs with np.nan (currently -999.9)
    SYN_short[SYN_short < 0] = np.nan
    # Identify droughts at percentiles
    syn_magnitude = calc_syn_magnitude(nyears, nmonths, nrealizations, nsamples, percentiles, SYN_short)
    
    # Delta Method analysis
    for i in range(len(percentiles)):
        if syn_magnitude[i,:].any():
            try:
                result = delta.analyze(problem, np.repeat(samples, nrealizations, axis = 0), syn_magnitude[i,:], print_to_console=False, num_resamples=2)
                S1[percentiles[i]] = result['S1']
                S1_conf[percentiles[i]] = result['S1_conf']
            except:
                pass

    S1.to_csv('../Simulation_outputs/' + design + '/'+ ID + '_S1.csv')
    S1_conf.to_csv('../Simulation_outputs/' + design + '/'+ ID + '_S1_conf.csv')
    
    # OLS regression analysis
    dta = pd.DataFrame(data = np.repeat(samples, nrealizations, axis = 0), columns=param_names)
    for i in range(len(percentiles)):
        dta['Shortage'] = syn_magnitude[i,:]
        for m in range(params_no):
            predictors = dta.columns.tolist()[m:(m+1)]
            result = fitOLS(dta, predictors)
            R2_scores.at[param_names[m],percentiles[i]]=result.rsquared
            
    R2_scores.to_csv('../Simulation_outputs/' + design + '/' + ID + '_R2.csv')
    
    return None
def sensitivity_analysis_per_structure(ID):
    #    if not path.exists('../'+design+'/Max_Duration_Sensitivity_analysis/'+ ID + '_DELTA_conf.csv'):
    '''
    Perform analysis for max shortage duration at each magnitude
    '''
    durations = np.load('../' + design + '/Max_Duration_Curves/' + ID + '.npy')
    dta = pd.DataFrame(data=LHsamples, columns=param_names)
    DELTA = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                         columns=percentiles)
    DELTA_conf = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                              columns=percentiles)
    S1 = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                      columns=percentiles)
    S1_conf = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                           columns=percentiles)
    R2_scores = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                             columns=percentiles)
    DELTA.index = DELTA_conf.index = S1.index = S1_conf.index = R2_scores.index = param_names
    for i in range(len(percentiles)):
        if durations[i].any():
            output = np.mean(durations[i].reshape(-1, 10), axis=1)
            output = output[rows_to_keep]
            # Delta Method analysis
            try:
                result = delta.analyze(problem,
                                       LHsamples,
                                       output,
                                       print_to_console=False)
                DELTA[percentiles[i]] = result['delta']
                DELTA_conf[percentiles[i]] = result['delta_conf']
                S1[percentiles[i]] = result['S1']
                S1_conf[percentiles[i]] = result['S1_conf']
            except:
                pass
            # OLS regression analysis
            dta['Shortage'] = output
            try:
                for m in range(params_no):
                    predictors = dta.columns.tolist()[m:(m + 1)]
                    result = fitOLS(dta, predictors)
                    R2_scores.at[param_names[m],
                                 percentiles[i]] = result.rsquared
            except:
                pass
    R2_scores.to_csv('../' + design + '/Max_Duration_Sensitivity_analysis/' +
                     ID + '_R2.csv')
    S1.to_csv('../' + design + '/Max_Duration_Sensitivity_analysis/' + ID +
              '_S1.csv')
    S1_conf.to_csv('../' + design + '/Max_Duration_Sensitivity_analysis/' +
                   ID + '_S1_conf.csv')
    DELTA.to_csv('../' + design + '/Max_Duration_Sensitivity_analysis/' + ID +
                 '_DELTA.csv')
    DELTA_conf.to_csv('../' + design + '/Max_Duration_Sensitivity_analysis/' +
                      ID + '_DELTA_conf.csv')
Exemple #9
0
def test_regression_delta():
    param_file = 'src/SALib/test_functions/params/Ishigami.txt'
    problem = read_param_file(param_file)
    param_values = latin.sample(problem, 10000)

    Y = Ishigami.evaluate(param_values)

    Si = delta.analyze(problem, param_values, Y, num_resamples=10,
                       conf_level=0.95, print_to_console=True)

    assert_allclose(Si['delta'], [0.210, 0.358, 0.155], atol=5e-2, rtol=1e-1)
    assert_allclose(Si['S1'], [0.31, 0.44, 0.00], atol=5e-2, rtol=1e-1)
    def analyze(self):
        """Initiate the analysis, and stores the result at data directory.

        Generates:
            Analysis result at 'acbm/data/output/delta.txt'.

        """

        X = latin.sample(self.problem, self.n_samples, seed=self.seed_sample)
        Y = ACBM.evaluate(X)
        si = delta.analyze(self.problem, X, Y, seed=self.seed_analyze)
        pickle.dump(si, open(self.path_output + 'delta.txt', 'wb'))
Exemple #11
0
def test_regression_delta():
    param_file = 'src/SALib/test_functions/params/Ishigami.txt'
    problem = read_param_file(param_file)
    param_values = latin.sample(problem, 10000)

    Y = Ishigami.evaluate(param_values)

    Si = delta.analyze(problem, param_values, Y, num_resamples=10,
                       conf_level=0.95, print_to_console=True)

    assert_allclose(Si['delta'], [0.210, 0.358, 0.155], atol=5e-2, rtol=1e-1)
    assert_allclose(Si['S1'], [0.31, 0.44, 0.00], atol=5e-2, rtol=1e-1)
Exemple #12
0
def _parallel_analyze(index, method, problem, samples, data, seed):
    if method == 'sobol':
        result = sobol.analyze(problem,
                               data,
                               calc_second_order=True,
                               print_to_console=False,
                               seed=seed)
    elif method == 'fast':
        result = fast.analyze(problem, data, print_to_console=False, seed=seed)
    elif method == 'rbd-fast':
        result = rbd_fast.analyze(problem,
                                  samples,
                                  data,
                                  print_to_console=False,
                                  seed=seed)
    elif method == 'morris':
        result = morris_analyze(problem,
                                samples,
                                data,
                                print_to_console=False,
                                seed=seed)
    elif method == 'delta':
        result = delta.analyze(problem,
                               samples,
                               data,
                               print_to_console=False,
                               seed=seed)
    elif method == 'dgsm':
        result = dgsm.analyze(problem,
                              samples,
                              data,
                              print_to_console=False,
                              seed=seed)
    elif method == 'frac':
        result = ff_analyze(problem,
                            samples,
                            data,
                            second_order=True,
                            print_to_console=False,
                            seed=seed)
    else:
        return 0

    for key in result.keys():
        result[key] = result[key].tolist()

    with open('{:s}.json'.format(index), 'w') as outfile:
        json.dump(result, outfile)

    return 0
Exemple #13
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))
Exemple #14
0
    def delta(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#delta-moment-independent-measure

        Returns:
            dict: sensitivity values of parameters; dict has keys 'delta',
                'delta_conf', 'S1', and 'S1_conf'
        """
        X, y, problem = self._sensitivity_prep()
        n_sample = 2000
        param_values = latin.sample(problem, n_sample)
        X_s, y_s = self._closest_points(problem, X, y, param_values)
        Si = delta.analyze(problem, X_s, y_s)
        return Si
Exemple #15
0
def _parallel_analyze(data):
    seed = int(opts['seed'])
    samples = population['problem', 'samples']
    problem = population['problem', 'definition']

    if opts['method'] == 'sobol':
        return sobol.analyze(problem,
                             data,
                             calc_second_order=True,
                             print_to_console=False)
    elif opts['method'] == 'fast':
        return fast.analyze(problem, data, print_to_console=False, seed=seed)
    elif opts['method'] == 'rbd-fast':
        return rbd_fast.analyze(problem,
                                samples,
                                data,
                                print_to_console=False,
                                seed=seed)
    elif opts['method'] == 'morris':
        return morris_analyze(problem,
                              samples,
                              data,
                              print_to_console=False,
                              seed=seed)
    elif opts['method'] == 'delta':
        return delta.analyze(problem,
                             samples,
                             data,
                             print_to_console=False,
                             seed=seed)
    elif opts['method'] == 'dgsm':
        return dgsm.analyze(problem,
                            samples,
                            data,
                            print_to_console=False,
                            seed=seed)
    elif opts['method'] == 'frac':
        return ff_analyze(problem,
                          samples,
                          data,
                          second_order=True,
                          print_to_console=False,
                          seed=seed)
    else:
        return 0
Exemple #16
0
def salib_wrapper(problem, y_val, x, analysis_type='sobol', **kwargs):
    '''
    Backend wrapper for sobol, fast and delta analysis.
    
    :meta private:
    '''
    if analysis_type == 'sobol':
        return sobol.analyze(problem, y_val, **kwargs)
    elif analysis_type == 'fast':
        return fast.analyze(problem, y_val, **kwargs)
    elif analysis_type == 'delta':
        return delta.analyze(problem, x, y_val, **kwargs)
    elif analysis_type == 'rbd-fast':
        return rbd_fast.analyze(problem, x, y_val, **kwargs)
    else:
        raise Exception(
            'Could not find analyzer. analysis_type must be sobol, fast, rbd-fast or delta.'
        )
def analyze(filename):
    print("Processing {}".format(filename))
    # Load the response file
    response = pandas.read_table(filename,
                                 delimiter=",",
                                 index_col=0,
                                 squeeze=True)
    print(response)
    try:
        id = [True for k in response.values if k < 800 and k is not str]
    except:
        print(filename)
        pass

    # Convert data frame into numpy array
    response_matrix = response.as_matrix()[id].astype(float).ravel()

    # Convert parameter values into numpy array
    params_matrix = params.as_matrix()[response.index[id]].astype(float)

    # Define a salib "problem"
    problem = {
        "num_vars": params.shape[1],  # Number of parameters
        "names": params.columns.values,  # Parameter names
        "bounds": zip(params.min(), params.max()),  # Parameter bounds
    }

    # Compute S1 sobol indices using the method of Plischke (2013, doi: https://doi.org/10.1016/j.ejor.2012.11.047)
    # as implemented in SALib
    Si = delta.analyze(problem,
                       params_matrix,
                       response_matrix,
                       num_resamples=100,
                       print_to_console=False)

    # Save responses as text files
    outfile = join(output_dir, os.path.split(filename)[-1][:-4] + "_sobel.txt")
    np.savetxt(
        outfile,
        np.c_[params.columns.values, Si["S1"], Si["S1_conf"]],
        delimiter=" ",
        header="Parameter S1 S1_conf",
        fmt=["%s", "%.03f", "%.03f"],
    )
def delta_mim(parameters, candidates_dict_log):
    samples = []
    losses = []
    for candidate, loss in candidates_dict_log:
        sample = parameters.from_dict(candidate)
        if parameters.defaults:
            sample.drop(parameters.defaults, inplace=True)
        sample = sample.to_numpy()
        samples.append(sample)
        losses.append(loss)
    samples = np.asarray(samples)
    losses = np.asarray(losses)

    bounds = {key: value for key, value in parameters.bounds.items()
              if key not in parameters.defaults}
    problem = {'num_vars': len(bounds),
               'names': list(bounds),
               'bounds': bounds}

    return delta.analyze(problem, samples, losses).to_df()
def analyzeSampleSensitivity(args):
	"""
	Analysis map function
	"""

	index = args[0]
	problem = args[1]
	X = args[2]
	Y = np.array(args[3])
	queue = args[4]

	# Find sensitive parameters
	try:
		S = delta.analyze(problem, X, Y, print_to_console=False)
	except Exception as e:
		print "Error: %s" % str(e)
		queue.put( (index,None) )
		return

	# Return the 'most correlated' parameters
	queue.put( (index, S['S1']) )
def objective_function_delta(problem, pars, OF):

    from SALib.analyze import delta
    import numpy as np
    import csv

    # convert pandas dataframe to numpy matrix
    params = pars.to_numpy()

    # initialize an empty list to save Sobol Indices
    results = []

    # loop through each OF and calculate the Delta Indices and Sobol first-order index for each parameter
    for j in np.arange(len(OF.columns)):

        # subset the OF of interest
        Y = np.array(OF.iloc[:, j])

        # calculate Sobol indices
        DI = delta.analyze(problem, params, Y)

        # hard code any negative indices to 0
        DI['delta'][DI['delta'] < 0] = 0
        DI['S1'][DI['S1'] < 0] = 0

        # save output to text file
        keys = DI.keys()

        with open('output/raw/delta_' + OF.columns[j] + '.csv',
                  'w') as csvfile:
            fieldnames = keys
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerow(DI)

        # save in results list
        results.append([DI])

    return results
Exemple #21
0
from SALib.sample import latin
from SALib.analyze import delta, sobol
from SALib.test_functions import Ishigami
import numpy as np
import random

# Define the model inputs
problem = {
    'num_vars': 4,
    'names': ['apprecition', 'cost', 'returns', 'interest'],
}
with open("data.csv") as f:
    data = f.read().splitlines()
data = list(map(lambda x: list(map(float, x.split(","))), data))
print(data[:10])
X = np.array(data)
Y = X[:, 4]
X = X[:, 0:4]
print(X)

# Perform analysis
Si = delta.analyze(problem, X, Y, print_to_console=True)

# Print the first-order sensitivity indices
print(Si['S1'])

s = sobol.analyze(problem, X, Y, print_to_console=True)
print(s)
Exemple #22
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(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
Exemple #23
0
    Si = sobol.analyze(problem, Y, print_to_console=False)
    figure_keys = {
        'ax1_title': 'S1',
        'ax2_title': 'S1_conf',
        'ax2_lable': 'Parameter index',
        'ax3_title': 'ST',
        'ax4_title': 'ST_conf',
        'ax4_lable': 'Parameter index',
        'ax5_parm': 'S2',
        'ax5_title': 'Second order sensitivity',
        'ax5_lable': 'Parameter index',
    }
elif method_flag == 2:
    Si = delta.analyze(problem,
                       param_values,
                       Y,
                       num_resamples=10,
                       conf_level=0.95,
                       print_to_console=False)
    figure_keys = {
        'ax1_title': 'S1',
        'ax2_title': 'S1_conf',
        'ax2_lable': 'Parameter index',
        'ax3_title': 'delta',
        'ax4_title': 'delta_conf',
        'ax4_lable': 'Parameter index',
    }
    Si_con = delta.analyze(problem,
                           param_values,
                           Y_con,
                           num_resamples=10,
                           conf_level=0.95,
Exemple #24
0
import sys
sys.path.append('../..')

from SALib.analyze import delta

# Read the parameter range file and generate samples
# Since this is "given data", the bounds in the parameter file will not be used
# but the columns are still expected
param_file = '../../SALib/test_functions/params/Ishigami.txt'

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
Si = delta.analyze(param_file,
                   'model_input.txt',
                   'model_output.txt',
                   column=0,
                   num_resamples=10,
                   conf_level=0.95,
                   print_to_console=False)
# Returns a dictionary with keys 'delta', 'delta_conf', 'S1', 'S1_conf'
print(str(Si['delta']))
Exemple #25
0
import sys

from SALib.analyze import delta
from SALib.util import read_param_file
import numpy as np

sys.path.append('../..')

# Read the parameter range file and generate samples
# Since this is "given data", the bounds in the parameter file will not be used
# but the columns are still expected
problem = read_param_file('../../src/SALib/test_functions/params/Ishigami.txt')
X = np.loadtxt('../data/model_input.txt')
Y = np.loadtxt('../data/model_output.txt')

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
Si = delta.analyze(problem,
                   X,
                   Y,
                   num_resamples=10,
                   conf_level=0.95,
                   print_to_console=False)
# Returns a dictionary with keys 'delta', 'delta_conf', 'S1', 'S1_conf'
print(str(Si['delta']))
Exemple #26
0
def read_outcomes_sens_analysis():
    """ Function to write the output of the sensitivity analysis to figures.
    """
    # load some basics
    data_path = load_config()['paths']['data']

    # specify country
    countries = [
        'LU', 'CZ', 'CH', 'EE', 'LV', 'LT', 'PT', 'ES', 'AT', 'BE', 'DK', 'IE',
        'NL', 'NO', 'SE'
    ]

    # done: LU
    country_full_names = {
        'CZ': 'Czech Republic',
        'CH': 'Switzerland',
        'EE': 'Estonia',
        'LV': 'Latvia',
        'LT': 'Lithuania',
        'PT': 'Portugal',
        'ES': 'Spain',
        'AT': 'Austria',
        'BE': 'Belgium',
        'DK': 'Denmark',
        'LU': 'Luxembourg',
        'NL': 'Netherlands',
        'IE': 'Ireland',
        'UK': 'United Kingdom',
        'NO': 'Norway',
        'SE': 'Sweden'
    }

    storms = {
        '19991203': 'Anatol',
        '19900125': 'Daria',
        '20090124': 'Klaus',
        '20070118': 'Kyrill',
        '19991226': 'Lothar'
    }

    # set parameters for sensitivity analysis
    problem = {
        'num_vars': 5,
        'names': ['c2', 'c3', 'c4', 'lu1', 'lu2'],
        'bounds': [[0, 100], [0, 100], [0, 100], [0, 50], [0, 50]]
    }

    # select storms to assess
    storm_name_list = [
        '19991203', '19900125', '20090124', '20070118', '19991226'
    ]
    storm_list = []
    for root, dirs, files in os.walk(os.path.join(data_path, 'STORMS')):
        for file in files:
            for storm in storm_name_list:
                if storm in file:
                    storm_list.append(os.path.join(data_path, 'STORMS', file))

    for country in countries:
        dirlist = os.listdir(os.path.join(data_path, 'output_sens'))
        country_list = [x for x in dirlist if country in x]
        k = 0

        for i in range(int(len(country_list) / 2)):
            if i < 1:
                out = pd.read_csv(
                    os.path.join(data_path,
                                 'output_sens',
                                 country_list[k],
                                 index_col=0))
            else:
                out2 = (os.path.join(data_path,
                                     'output_sens',
                                     country_list[k],
                                     index_col=0)).fillna(0)
                out += out2
            k += 2
        param_values = pd.read_csv(os.path.join(data_path, 'output_sens',
                                                country_list[1]),
                                   delim_whitespace=True,
                                   header=None)

        #Estimate outcome of sensitvity analysis
        param_values = np.asarray(param_values)
        for l in range(5):
            try:
                storm = np.asarray(out.ix[:, l])
                Si = delta.analyze(problem,
                                   param_values,
                                   storm,
                                   print_to_console=True)

                # create histogram
                plt.hist(storm, bins='auto', ec="k", lw=0.1)
                plt.autoscale(tight=True)
                plt.title(country_full_names[country] + ', ' +
                          storms[out.ix[:, l].name])
                plt.ylabel('Frequency')
                plt.xlabel('Total damage in Million Euro')
                plt.savefig(os.path.join(
                    data_path, 'Figures',
                    country + '_' + storms[out.ix[:, l].name] + '.png'),
                            dpi=300)
                plt.clf()

                # create pie chart
                delta_ = (Si['delta']) / sum(Si['delta']) * 100
                colors = [
                    'yellowgreen', 'gold', 'lightskyblue', 'lightcoral', 'peru'
                ]
                labels = ['c2', 'c3', 'c4', 'lu1', 'lu2']
                patches, texts = plt.pie(delta_,
                                         colors=colors,
                                         startangle=90,
                                         radius=0.4,
                                         center=(0.5, 0.5))
                plt.axis('equal')
                plt.legend(patches,
                           loc="best",
                           labels=[
                               '%s : %1.1f%%' % (l, s)
                               for l, s in zip(labels, delta_)
                           ])
                plt.title(country_full_names[country] + ', ' +
                          storms[out.ix[:, l].name])
                plt.savefig(os.path.join(
                    data_path, 'Figures',
                    country + '_' + storms[out.ix[:, l].name] + '_SA.png'),
                            dpi=300)
                plt.clf()
            except Exception:
                continue
Exemple #27
0
import sys
sys.path.append('../..')

from SALib.analyze import delta

# Read the parameter range file and generate samples
# Since this is "given data", the bounds in the parameter file will not be used
# but the columns are still expected
param_file = '../../SALib/test_functions/params/Ishigami.txt'

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
Si = delta.analyze(param_file, 'model_input.txt', 'model_output.txt', column = 0, num_resamples=10, conf_level = 0.95, print_to_console=False)
# Returns a dictionary with keys 'delta', 'delta_conf', 'S1', 'S1_conf'
print Si['delta']
Exemple #28
0
def sensitivity_analysis_per_structure(ID):
    '''
    Perform analysis for shortage frequency
    '''
    HIS_short = np.loadtxt('../' + design + '/Infofiles/' + ID + '/' + ID +
                           '_info_0.txt')[:, 2]

    DELTA = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                         columns=percentiles)
    DELTA_conf = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                              columns=percentiles)
    S1 = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                      columns=percentiles)
    S1_conf = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                           columns=percentiles)
    R2_scores = pd.DataFrame(np.zeros((params_no, len(percentiles))),
                             columns=percentiles)
    DELTA.index = DELTA_conf.index = S1.index = S1_conf.index = R2_scores.index = param_names

    SYN_short = np.zeros([len(HIS_short), samples * realizations])

    for j in range(samples):
        data = np.loadtxt('../' + design + '/Infofiles/' + ID + '/' + ID +
                          '_info_' + str(j + 1) + '.txt')
        try:
            SYN_short[:, j * realizations:j * realizations +
                      realizations] = data[:, idx]
        except IndexError:
            print(ID + '_info_' + str(j + 1))
    # Reshape into water years
    # Create matrix of [no. years x no. months x no. experiments]
    f_HIS_short = np.reshape(HIS_short, (int(np.size(HIS_short) / n), n))
    f_SYN_short = np.zeros(
        [int(np.size(HIS_short) / n), n, samples * realizations])
    for i in range(samples * realizations):
        f_SYN_short[:, :,
                    i] = np.reshape(SYN_short[:, i],
                                    (int(np.size(SYN_short[:, i]) / n), n))

    # Shortage per water year
    f_HIS_short_WY = np.sum(f_HIS_short, axis=1)
    f_SYN_short_WY = np.sum(f_SYN_short, axis=1)

    # Identify historic shortages at percentiles
    HIS_magnitude = [np.percentile(f_HIS_short_WY, i) for i in percentiles]

    # Identify synthetic frequencies of historic shortages
    syn_magnitude = np.zeros([len(percentiles), samples * realizations])
    for p in percentiles:
        if HIS_magnitude[p] > 0:
            for j in range(samples * realizations):
                syn_magnitude[p, j] = scipy.stats.percentileofscore(
                    f_SYN_short_WY[:, j], HIS_magnitude[p], kind='strict')
        else:
            syn_magnitude[p, :] = 0

    # Delta Method analysis
    for p in percentiles:
        if HIS_magnitude[p] > 0:
            try:
                output = np.mean(syn_magnitude[p, :].reshape(-1, 10), axis=1)
                output = output[rows_to_keep]
                result = delta.analyze(problem,
                                       LHsamples,
                                       output,
                                       print_to_console=False,
                                       num_resamples=10)
                DELTA[p] = result['delta']
                DELTA_conf[p] = result['delta_conf']
                S1[p] = result['S1']
                S1_conf[p] = result['S1_conf']
            except:
                pass

    S1.to_csv('../' + design + '/Frequency_Sensitivity_analysis/' + ID +
              '_S1.csv')
    S1_conf.to_csv('../' + design + '/Frequency_Sensitivity_analysis/' + ID +
                   '_S1_conf.csv')
    DELTA.to_csv('../' + design + '/Frequency_Sensitivity_analysis/' + ID +
                 '_DELTA.csv')
    DELTA_conf.to_csv('../' + design + '/Frequency_Sensitivity_analysis/' +
                      ID + '_DELTA_conf.csv')

    # OLS regression analysis
    dta = pd.DataFrame(data=LHsamples, columns=param_names)
    for p in percentiles:
        if HIS_magnitude[p] > 0:
            output = np.mean(syn_magnitude[p, :].reshape(-1, 10), axis=1)
            dta['Shortage'] = output[rows_to_keep]
            for m in range(params_no):
                predictors = dta.columns.tolist()[m:(m + 1)]
                result = fitOLS(dta, predictors)
                R2_scores.at[param_names[m], p] = result.rsquared
    R2_scores.to_csv('../' + design + '/Frequency_Sensitivity_analysis/' + ID +
                     '_R2.csv')
Exemple #29
0
import sys

from SALib.analyze import delta
from SALib.util import read_param_file
import numpy as np


sys.path.append('../..')


# Read the parameter range file and generate samples
# Since this is "given data", the bounds in the parameter file will not be used
# but the columns are still expected
problem = read_param_file('../../SALib/test_functions/params/Ishigami.txt')
X = np.loadtxt('model_input.txt')
Y = np.loadtxt('model_output.txt')

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
Si = delta.analyze(problem, X, Y, num_resamples=10, conf_level=0.95, print_to_console=False)
# Returns a dictionary with keys 'delta', 'delta_conf', 'S1', 'S1_conf'
print(str(Si['delta']))
Exemple #30
0
    def perform_GSA(self, act_number=0, method_number=0,
                    cutoff_technosphere=0.01, cutoff_biosphere=0.01):
        """Perform GSA for specific reference flow and impact category."""
        start = time()

        # set FU and method
        try:
            self.act_number = act_number
            self.method_number = method_number
            self.cutoff_technosphere = cutoff_technosphere
            self.cutoff_biosphere = cutoff_biosphere

            self.fu = self.mc.cs['inv'][act_number]
            self.activity = bw.get_activity(self.mc.rev_activity_index[act_number])
            self.method = self.mc.cs['ia'][method_number]

        except Exception as e:
            traceback.print_exc()
            # todo: QMessageBox.warning(self, 'Could not perform Delta analysis', str(e))
            print('Initializing the GSA failed.')
            return None

        print('-- GSA --\n Project:', bw.projects.current, 'CS:', self.mc.cs_name,
              'Activity:', self.activity, 'Method:', self.method)

        # get non-stochastic LCA object with reverse dictionaries
        self.lca = get_lca(self.fu, self.method)

        # =============================================================================
        #   Filter exchanges and get metadata DataFrames
        # =============================================================================
        dfs = []
        # technosphere
        if self.mc.include_technosphere:
            self.t_indices = filter_technosphere_exchanges(self.fu, self.method,
                                                           cutoff=cutoff_technosphere,
                                                           max_calc=1e4)
            self.t_exchanges, self.t_indices = get_exchanges(self.lca, self.t_indices)
            self.dft = get_exchanges_dataframe(self.t_exchanges, self.t_indices)
            if not self.dft.empty:
                dfs.append(self.dft)

        # biosphere
        if self.mc.include_biosphere:
            self.b_indices = filter_biosphere_exchanges(self.lca, cutoff=cutoff_biosphere)
            self.b_exchanges, self.b_indices = get_exchanges(self.lca, self.b_indices, biosphere=True)
            self.dfb = get_exchanges_dataframe(self.b_exchanges, self.b_indices, biosphere=True)
            if not self.dfb.empty:
                dfs.append(self.dfb)

        # characterization factors
        if self.mc.include_cfs:
            self.dfcf = get_CF_dataframe(self.lca, only_uncertain_CFs=True)  # None if no stochastic CFs
            if not self.dfcf.empty:
                dfs.append(self.dfcf)

        # parameters
        # todo: if parameters, include df, but remove exchanges from T and B (skipped for now)
        self.dfp = get_parameters_DF(self.mc)  # Empty df if no parameters
        if not self.dfp.empty:
            dfs.append(self.dfp)

        # Join dataframes to get metadata
        self.metadata = pd.concat(dfs, axis=0, ignore_index=True, sort=False)
        self.metadata.set_index('GSA name', inplace=True)

        # =============================================================================
        #     GSA
        # =============================================================================

        # Get X (Technosphere, Biosphere and CF values)
        X_list = list()
        if self.mc.include_technosphere and self.t_indices:
            self.Xa = get_X(self.mc.A_matrices, self.t_indices)
            X_list.append(self.Xa)
        if self.mc.include_biosphere and self.b_indices:
            self.Xb = get_X(self.mc.B_matrices, self.b_indices)
            X_list.append(self.Xb)
        if self.mc.include_cfs and not self.dfcf.empty:
            self.Xc = get_X_CF(self.mc, self.dfcf, self.method)
            X_list.append(self.Xc)
        if self.mc.include_parameters and not self.dfp.empty:
            self.Xp = get_X_P(self.dfp)
            X_list.append(self.Xp)

        self.X = np.concatenate(X_list, axis=1)
        # print('X', self.X.shape)

        # Get Y (LCA scores)
        self.Y = self.mc.get_results_dataframe(act_key=self.activity.key)[self.method].to_numpy()

        # log-transformation. This makes it more robust for very uneven distributions of LCA results (e.g. toxicity related impacts).
        # Can only be applied if all Monte-Carlo LCA scores are either positive or negative.
        # Should not be used when LCA scores overlap zero (sometimes positive and sometimes negative)
        # if np.all(self.Y > 0) if self.Y[0] > 0 else np.all(self.Y < 0):  # check if all LCA scores are of the same sign
        #     self.Y = np.log(np.abs(self.Y))  # this makes it more robust for very uneven distributions of LCA results
        if np.all(self.Y > 0):  # all positive numbers
            self.Y = np.log(np.abs(self.Y))
            print('All positive LCA scores. Log-transformation performed.')
        elif np.all(self.Y < 0):  # all negative numbers
            self.Y = -np.log(np.abs(self.Y))
            print('All negative LCA scores. Log-transformation performed.')
        else:  # mixed positive and negative numbers
            print('Log-transformation cannot be applied as LCA scores overlap zero.')

        # print('Filtering took {} seconds'.format(np.round(time() - start, 2)))

        # define problem
        self.names = self.metadata.index  # ['GSA name']
        # print('Names:', len(self.names))
        self.problem = get_problem(self.X, self.names)

        # perform delta analysis
        time_delta = time()
        self.Si = delta.analyze(self.problem, self.X, self.Y, print_to_console=False)
        print('Delta analysis took {} seconds'.format(np.round(time() - time_delta, 2), ))

        # put GSA results in to dataframe
        self.dfgsa = pd.DataFrame(self.Si, index=self.names).sort_values(by='delta', ascending=False)
        self.dfgsa.index.names = ['GSA name']

        # join with metadata
        self.df_final = self.dfgsa.join(self.metadata, on='GSA name')
        self.df_final.reset_index(inplace=True)
        self.df_final['pedigree'] = [str(x) for x in self.df_final['pedigree']]

        print('GSA took {} seconds'.format(np.round(time() - start, 2)))
Exemple #31
0
    def run(self,
            input_ids=None,
            output_ids=None,
            method=None,
            calc_second_order=None,
            conf_level=None,
            **kwargs):

        self._update_parameters(method, calc_second_order, conf_level)

        self.other_parameters = kwargs

        if input_ids is None:
            input_ids = range(self.n_inputs)

        self.problem = {
            "num_vars": len(input_ids),
            "names": np.array(self.input_names)[input_ids].tolist(),
            "bounds": np.array(self.input_bounds)[input_ids].tolist()
        }

        if output_ids is None:
            output_ids = range(self.n_outputs)

        n_outputs = len(output_ids)

        if self.method.lower() == "sobol":
            self.logger.warning(
                "'sobol' method requires 'saltelli' sampling scheme!")
            # Additional keyword parameters and their defaults:
            # calc_second_order (bool): Calculate second-order sensitivities (default True)
            # num_resamples (int): The number of resamples used to compute the confidence intervals (default 1000)
            # conf_level (float): The confidence interval level (default 0.95)
            # print_to_console (bool): Print results directly to console (default False)
            # parallel: False,
            # n_processors: None
            self.analyzer = lambda output: sobol.analyze(
                self.problem,
                output,
                calc_second_order=self.calc_second_order,
                conf_level=self.conf_level,
                num_resamples=self.other_parameters.get("num_resamples", 1000),
                parallel=self.other_parameters.get("parallel", False),
                n_processors=self.other_parameters.get("n_processors", None),
                print_to_console=self.other_parameters.get(
                    "print_to_console", False))

        elif np.in1d(self.method.lower(), ["latin", "delta"]):
            self.logger.warning(
                "'latin' sampling scheme is recommended for 'delta' method!")
            # Additional keyword parameters and their defaults:
            # num_resamples (int): The number of resamples used to compute the confidence intervals (default 1000)
            # conf_level (float): The confidence interval level (default 0.95)
            # print_to_console (bool): Print results directly to console (default False)
            self.analyzer = lambda output: delta.analyze(
                self.problem,
                self.input_samples[:, input_ids],
                output,
                conf_level=self.conf_level,
                num_resamples=self.other_parameters.get("num_resamples", 1000),
                print_to_console=self.other_parameters.get(
                    "print_to_console", False))

        elif np.in1d(self.method.lower(), ["fast", "fast_sampler"]):
            self.logger.warning(
                "'fast' method requires 'fast_sampler' sampling scheme!")
            # Additional keyword parameters and their defaults:
            # M (int): The interference parameter,
            #           i.e., the number of harmonics to sum in the Fourier series decomposition (default 4)
            # print_to_console (bool): Print results directly to console (default False)
            self.analyzer = lambda output: fast.analyze(
                self.problem,
                output,
                M=self.other_parameters.get("M", 4),
                print_to_console=self.other_parameters.get(
                    "print_to_console", False))

        elif np.in1d(self.method.lower(), ["ff", "fractional_factorial"]):
            # Additional keyword parameters and their defaults:
            # second_order (bool, default=False): Include interaction effects
            # print_to_console (bool, default=False): Print results directly to console
            self.logger.warning(
                "'fractional_factorial' method requires 'fractional_factorial' sampling scheme!"
            )
            self.analyzer = lambda output: ff.analyze(
                self.problem,
                self.input_samples[:, input_ids],
                output,
                calc_second_order=self.calc_second_order,
                conf_level=self.conf_level,
                num_resamples=self.other_parameters.get("num_resamples", 1000),
                print_to_console=self.other_parameters.get(
                    "print_to_console", False))

        elif self.method.lower().lower() == "morris":
            self.logger.warning(
                "'morris' method requires 'morris' sampling scheme!")
            # Additional keyword parameters and their defaults:
            # num_resamples (int): The number of resamples used to compute the confidence intervals (default 1000)
            # conf_level (float): The confidence interval level (default 0.95)
            # print_to_console (bool): Print results directly to console (default False)
            # grid_jump (int): The grid jump size, must be identical to the value passed to
            #                   SALib.sample.morris.sample() (default 2)
            # num_levels (int): The number of grid levels, must be identical to the value passed to
            #                   SALib.sample.morris (default 4)
            self.analyzer = lambda output: morris.analyze(
                self.problem,
                self.input_samples[:, input_ids],
                output,
                conf_level=self.conf_level,
                grid_jump=self.other_parameters.get("grid_jump", 2),
                num_levels=self.other_parameters.get("num_levels", 4),
                num_resamples=self.other_parameters.get("num_resamples", 1000),
                print_to_console=self.other_parameters.get(
                    "print_to_console", False))

        elif self.method.lower() == "dgsm":
            # num_resamples (int): The number of resamples used to compute the confidence intervals (default 1000)
            # conf_level (float): The confidence interval level (default 0.95)
            # print_to_console (bool): Print results directly to console (default False)
            self.analyzer = lambda output: dgsm.analyze(
                self.problem,
                self.input_samples[:, input_ids],
                output,
                conf_level=self.conf_level,
                num_resamples=self.other_parameters.get("num_resamples", 1000),
                print_to_console=self.other_parameters.get(
                    "print_to_console", False))

        else:
            raise_value_error("Method " + str(self.method) +
                              " is not one of the available methods " +
                              str(METHODS) + " !")

        output_names = []
        results = []
        for io in output_ids:
            output_names.append(self.output_names[io])
            results.append(self.analyzer(self.output_values[:, io]))

        # TODO: Adjust list_of_dicts_to_dicts_of_ndarrays to handle ndarray concatenation
        results = list_of_dicts_to_dicts_of_ndarrays(results)

        results.update({"output_names": output_names})

        return results
Exemple #32
0
R2_scores = pd.DataFrame(np.zeros((params_no, len(percentiles))), columns = percentiles)
DELTA.index=DELTA_conf.index=S1.index=S1_conf.index = R2_scores.index = param_names

# Read in experiment data
expData = np.loadtxt('./experiment_data.txt')

# Identify magnitude at each percentiles
syn_magnitude = np.zeros([len(percentiles),len(LHsamples[:,0])])
for j in range(len(LHsamples[:,0])):
    syn_magnitude[:,j]=[np.percentile(expData[:,j], i) for i in percentiles]

# Delta Method analysis
for i in range(len(percentiles)):
    if syn_magnitude[i,:].any():
        try:
            result= delta.analyze(problem, LHsamples, syn_magnitude[i,:], print_to_console=False, num_resamples=2)
            DELTA[percentiles[i]]= result['delta']
            DELTA_conf[percentiles[i]] = result['delta_conf']
            S1[percentiles[i]]=result['S1']
            S1_conf[percentiles[i]]=result['S1_conf']
        except:
            pass

S1.to_csv('./S1_scores.csv')
S1_conf.to_csv('./S1_conf_scores.csv')
DELTA.to_csv('./DELTA_scores.csv')
DELTA_conf.to_csv('./DELTA_conf_scores.csv')

# OLS regression analysis
dta = pd.DataFrame(data = LHsamples, columns=param_names)
#    fig = plt.figure()
Exemple #33
0
    def perform_GSA(self, act_number=0, method_number=0,
                    cutoff_technosphere=0.01, cutoff_biosphere=0.01):
        """Perform GSA for specific functional unit and LCIA method."""
        start = time()

        # set FU and method
        try:
            self.act_number = act_number
            self.method_number = method_number
            self.cutoff_technosphere = cutoff_technosphere
            self.cutoff_biosphere = cutoff_biosphere

            self.fu = self.mc.cs['inv'][act_number]
            self.activity = bw.get_activity(self.mc.rev_activity_index[act_number])
            self.method = self.mc.cs['ia'][method_number]

        except Exception as e:
            traceback.print_exc()
            print('Initializing the GSA failed.')
            return None

        print('-- GSA --\n Project:', bw.projects.current, 'CS:', self.mc.cs_name,
              'Activity:', self.activity, 'Method:', self.method)

        # get non-stochastic LCA object with reverse dictionaries
        self.lca = get_lca(self.fu, self.method)

        # =============================================================================
        #   Filter exchanges and get metadata DataFrames
        # =============================================================================
        dfs = []
        # technosphere
        if self.mc.include_technosphere:
            self.t_indices = filter_technosphere_exchanges(self.fu, self.method,
                                                           cutoff=cutoff_technosphere,
                                                           max_calc=1e4)
            self.t_exchanges, self.t_indices = get_exchanges(self.lca, self.t_indices)
            self.dft = get_exchanges_dataframe(self.t_exchanges, self.t_indices)
            if not self.dft.empty:
                dfs.append(self.dft)

        # biosphere
        if self.mc.include_biosphere:
            self.b_indices = filter_biosphere_exchanges(self.lca, cutoff=cutoff_biosphere)
            self.b_exchanges, self.b_indices = get_exchanges(self.lca, self.b_indices, biosphere=True)
            self.dfb = get_exchanges_dataframe(self.b_exchanges, self.b_indices, biosphere=True)
            if not self.dfb.empty:
                dfs.append(self.dfb)

        # characterization factors
        if self.mc.include_cfs:
            self.dfcf = get_CF_dataframe(self.lca, only_uncertain_CFs=True)  # None if no stochastic CFs
            if not self.dfcf.empty:
                dfs.append(self.dfcf)

        # parameters
        # remark: the exchanges affected by parameters are NOT removed in this implementation. Thus the GSA results
        # will potentially show both the parameters AND the dependent exchanges
        self.dfp = get_parameters_DF(self.mc)  # Empty df if no parameters
        if not self.dfp.empty:
            dfs.append(self.dfp)

        # Join dataframes to get metadata
        self.metadata = pd.concat(dfs, axis=0, ignore_index=True, sort=False)
        self.metadata.set_index('GSA name', inplace=True)

        # =============================================================================
        #     GSA
        # =============================================================================

        # Get X (Technosphere, Biosphere and CF values)
        X_list = list()
        if self.mc.include_technosphere and self.t_indices:
            self.Xa = get_X(self.mc.A_matrices, self.t_indices)
            X_list.append(self.Xa)
        if self.mc.include_biosphere and self.b_indices:
            self.Xb = get_X(self.mc.B_matrices, self.b_indices)
            X_list.append(self.Xb)
        if self.mc.include_cfs and not self.dfcf.empty:
            self.Xc = get_X_CF(self.mc, self.dfcf, self.method)
            X_list.append(self.Xc)
        if self.mc.include_parameters and not self.dfp.empty:
            self.Xp = get_X_P(self.dfp)
            X_list.append(self.Xp)

        self.X = np.concatenate(X_list, axis=1)
        # print('X', self.X.shape)

        # Get Y (LCA scores)
        self.Y = self.mc.get_results_dataframe(act_key=self.activity.key)[self.method].to_numpy()
        self.Y = np.log(self.Y)  # this makes it more robust for very uneven distributions of LCA results
        # (e.g. toxicity related impacts); for not so large differences in LCIA results it should not matter

        # define problem
        self.names = self.metadata.index  # ['GSA name']
        # print('Names:', len(self.names))
        self.problem = get_problem(self.X, self.names)

        # perform delta analysis
        time_delta = time()
        self.Si = delta.analyze(self.problem, self.X, self.Y, print_to_console=False)
        print('Delta analysis took {} seconds'.format(np.round(time() - time_delta, 2), ))

        # put GSA results in to dataframe
        self.dfgsa = pd.DataFrame(self.Si, index=self.names).sort_values(by='delta', ascending=False)
        self.dfgsa.index.names = ['GSA name']

        # join with metadata
        self.df_final = self.dfgsa.join(self.metadata, on='GSA name')
        self.df_final.reset_index(inplace=True)
        self.df_final['pedigree'] = [str(x) for x in self.df_final['pedigree']]

        print('GSA took {} seconds'.format(np.round(time() - start, 2)))
Exemple #34
0
 def analyze_delta(self):
     # Delta Moment-Independent Measure
     return delta.analyze(self.sa_problem,
                          self.samples_x,
                          self.samples_y,
                          print_to_console=self.options["print_to_console"])
Exemple #35
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
 sel_LAMBDA_DF = comp_df[(comp_df['decision_type'] == decision)
                         & (comp_df['auction_type'] == auc)
                         & (comp_df['layer'] == 'nan')]
 X = pd.concat([
     sel_LAMBDA_DF[' No. Nodes'],
     sel_LAMBDA_DF[' Interconnection Prob'],
     sel_LAMBDA_DF[' Damage Prob'], sel_LAMBDA_DF[' Resource Cap ']
 ],
               axis=1,
               keys=['N', 'pi', 'pd', 'Rc']).to_numpy()
 Y = pd.concat([sel_LAMBDA_DF['lambda_U']], axis=1,
               keys=['lambda_U']).to_numpy().ravel()
 delta_perf = delta.analyze(problem,
                            X,
                            Y,
                            num_resamples=100,
                            conf_level=0.95,
                            print_to_console=True,
                            seed=None)
 for idx, para in enumerate(delta_perf['names']):
     sens_perf = sens_perf.append(
         {
             'config_param': para,
             'auction': auc,
             'decision': decision,
             'delta': delta_perf['delta'][idx],
             'delta_CI': delta_perf['delta_conf'][idx]
         },
         ignore_index=True)
 delta_dict_perf[auc, decision] = pd.DataFrame.from_dict({
     x: delta_perf['delta_vec'][idx]