Exemple #1
0
    def fit(self, X, y, **fit_params):
        input_dimension = X.shape[1]
        if self.distribution is None:
            self.distribution = BuildDistribution(X)
        if self.enumerate == 'linear':
            enumerateFunction = ot.LinearEnumerateFunction(input_dimension)
        elif self.enumerate == 'hyperbolic':
            enumerateFunction = ot.HyperbolicAnisotropicEnumerateFunction(input_dimension, self.q)
        else:
            raise ValueError('enumerate should be "linear" or "hyperbolic"')
        polynomials = [ot.StandardDistributionPolynomialFactory(self.distribution.getMarginal(i)) for i in range(input_dimension)]
        productBasis = ot.OrthogonalProductPolynomialFactory(polynomials, enumerateFunction)
        adaptiveStrategy = ot.FixedStrategy(productBasis, enumerateFunction.getStrataCumulatedCardinal(self.degree))
        if self.sparse:
            projectionStrategy = ot.LeastSquaresStrategy(ot.LeastSquaresMetaModelSelectionFactory(ot.LARS(), ot.CorrectedLeaveOneOut()))
        else:
            projectionStrategy = ot.LeastSquaresStrategy(X, y.reshape(-1, 1))
        algo = ot.FunctionalChaosAlgorithm(X, y.reshape(-1, 1), self.distribution, adaptiveStrategy, projectionStrategy)
        algo.run()
        self._result = algo.getResult()
        output_dimension = self._result.getMetaModel().getOutputDimension()

        # sensitivity
        si = ot.FunctionalChaosSobolIndices(self._result)
        if output_dimension == 1:
            self.feature_importances_ = [si.getSobolIndex(i) for i in range(input_dimension)]
        else:
            self.feature_importances_ = [[0.0] * input_dimension] * output_dimension
            for k in range(output_dimension):
                for i in range(input_dimension):
                    self.feature_importances_[k][i] = si.getSobolIndex(i, k)
        self.feature_importances_ = np.array(self.feature_importances_)
        return self
Exemple #2
0
    def fit(self, sample, data):
        """Create the predictor.

        The result of the Polynomial Chaos is stored as :attr:`pc_result` and
        the surrogate is stored as :attr:`pc`. It exposes :attr:`self.weights`,
        :attr:`self.coefficients` and Sobol' indices :attr:`self.s_first` and
        :attr:`self.s_total`.

        :param array_like sample: The sample used to generate the data
          (n_samples, n_features).
        :param array_like data: The observed data (n_samples, [n_features]).
        """
        trunc_strategy = ot.FixedStrategy(self.basis, self.n_basis)

        if self.strategy == 'LS':  # least-squares method
            proj_strategy = ot.LeastSquaresStrategy(sample, data)
            _, self.weights = proj_strategy.getExperiment().generateWithWeights()

        elif self.strategy == 'SparseLS':
            app = ot.LeastSquaresMetaModelSelectionFactory(ot.LARS(), ot.CorrectedLeaveOneOut())
            proj_strategy = ot.LeastSquaresStrategy(sample, data, app)
            _, self.weights = proj_strategy.getExperiment().generateWithWeights()

            max_considered_terms = self.sparse_param.get('max_considered_terms', 120)
            most_significant = self.sparse_param.get('most_significant', 30)
            significance_factor = self.sparse_param.get('significance_factor', 1e-3)

            trunc_strategy = ot.CleaningStrategy(ot.OrthogonalBasis(self.basis),
                                                 max_considered_terms,
                                                 most_significant,
                                                 significance_factor, True)
        else:
            proj_strategy = self.proj_strategy
            sample_ = np.zeros_like(self.sample)
            sample_[:len(sample)] = sample
            sample_arg = np.all(np.isin(sample_, self.sample), axis=1)
            self.weights = np.array(self.weights)[sample_arg]

        # PC fitting
        pc_algo = ot.FunctionalChaosAlgorithm(sample, self.weights, data,
                                              self.dist, trunc_strategy)
        pc_algo.setProjectionStrategy(proj_strategy)
        ot.Log.Show(ot.Log.ERROR)
        pc_algo.run()

        # Accessors
        self.pc_result = pc_algo.getResult()
        self.pc = self.pc_result.getMetaModel()
        self.coefficients = self.pc_result.getCoefficients()

        # sensitivity indices
        sobol = ot.FunctionalChaosSobolIndices(self.pc_result)
        self.s_first, self.s_total = [], []
        for i, j in product(range(self.in_dim), range(np.array(data).shape[1])):
            self.s_first.append(sobol.getSobolIndex(i, j))
            self.s_total.append(sobol.getSobolTotalIndex(i, j))

        self.s_first = np.array(self.s_first).reshape(self.in_dim, -1).T
        self.s_total = np.array(self.s_total).reshape(self.in_dim, -1).T
Exemple #3
0
# Plot the observed versus the predicted outputs.

# %%
graph = val.drawValidation()
graph.setTitle("Q2=%.2f%%" % (Q2 * 100))
view = viewer.View(graph)

# %%
# Sensitivity analysis
# --------------------

# %%
# Retrieve Sobol' sensitivity measures associated to the polynomial chaos decomposition of the model.

# %%
chaosSI = ot.FunctionalChaosSobolIndices(result)
print(chaosSI.summary())

# %%
first_order = [chaosSI.getSobolIndex(i) for i in range(dim_input)]
total_order = [chaosSI.getSobolTotalIndex(i) for i in range(dim_input)]
input_names = g.getInputDescription()
graph = ot.SobolIndicesAlgorithm.DrawSobolIndices(input_names, first_order,
                                                  total_order)
view = viewer.View(graph)

plt.show()
# %%
# Conclusion
# ----------
#
val = ot.MetaModelValidation(inputTest, outputTest, metamodel)
Q2 = val.computePredictivityFactor()
graph = val.drawValidation()
graph.setTitle("Metamodel validation Q2="+str(Q2))
view = viewer.View(graph)

# %%
# The coefficient of predictivity is not extremely satisfactory for the first output, but is would be sufficient for a central dispersion study.
# The second output has a much more satisfactory Q2: only one single extreme point is far from the diagonal of the graphics.

# %%
# Compute and print Sobol' indices
# --------------------------------

# %%
chaosSI = ot.FunctionalChaosSobolIndices(result) 
print(chaosSI.summary())

# %%
# Let us analyse the results of this global sensitivity analysis.
#
# * We see that the first output involves significant multi-indices with total degree 4. The contribution of the interactions are very significant in this model. 
# * The second output involves multi-indices with total degrees from 1 to 7, with a significant contribution of multi-indices with total degress 5 and 7. The first variable is especially significant, with a significant contribution of the interactions. 

# %%
# Draw Sobol' indices.

# %%
sensitivityAnalysis = ot.FunctionalChaosSobolIndices(result)
first_order = [sensitivityAnalysis.getSobolIndex(i) for i in range(dimension)]
total_order = [sensitivityAnalysis.getSobolTotalIndex(i) for i in range(dimension)]
]
sob_T2 = [
    sob_2[0] + sob_2[1] + sob_3[0], sob_2[0] + sob_2[2] + sob_3[0],
    sob_2[1] + sob_2[2] + sob_3[0]
]
sob_T3 = [sob_3[0]]

model = ot.SymbolicFunction(['xi1', 'xi2', 'xi3'], [
    'sin(xi1) + (' + str(a) + ') * (sin(xi2)) ^ 2 + (' + str(b) +
    ') * xi3^4 * sin(xi1)'
])

# Create the input distribution
distribution = ot.ComposedDistribution([ot.Uniform(-pi, pi)] * dimension)

size = 1000
x = distribution.getSample(size)
y = model(x)

# To reduce the time needed by the test
ot.ResourceMap.SetAsUnsignedInteger(
    "FittingTest-LillieforsMinimumSamplingSize", 4)
ot.ResourceMap.SetAsUnsignedInteger(
    "FittingTest-LillieforsMaximumSamplingSize", 4)
algo = ot.FunctionalChaosAlgorithm(x, y)
algo.run()
result = algo.getResult()
sensitivity = ot.FunctionalChaosSobolIndices(result)

print(sensitivity.summary())
Exemple #6
0
    def fit(self, X, y, **fit_params):
        """Fit PC regression model.

        Parameters
        ----------
        X : array-like, shape = (n_samples, n_features)
            Training data.
        y : array-like, shape = (n_samples, [n_output_dims])
            Target values.

        Returns
        -------
        self : returns an instance of self.

        """
        if len(X) == 0:
            raise ValueError(
                "Can not perform chaos expansion with empty sample")
        # check data type is accurate
        if (len(np.shape(X)) != 2):
            raise ValueError("X has incorrect shape.")
        input_dimension = len(X[1])
        if (len(np.shape(y)) != 2):
            raise ValueError("y has incorrect shape.")
        if self.distribution is None:
            self.distribution = ot.MetaModelAlgorithm.BuildDistribution(X)
        if self.enumeratef == 'linear':
            enumerateFunction = ot.LinearEnumerateFunction(input_dimension)
        elif self.enumeratef == 'hyperbolic':
            enumerateFunction = ot.HyperbolicAnisotropicEnumerateFunction(
                input_dimension, self.q)
        else:
            raise ValueError('enumeratef should be "linear" or "hyperbolic"')
        polynomials = [
            ot.StandardDistributionPolynomialFactory(
                self.distribution.getMarginal(i))
            for i in range(input_dimension)
        ]
        productBasis = ot.OrthogonalProductPolynomialFactory(
            polynomials, enumerateFunction)
        adaptiveStrategy = ot.FixedStrategy(
            productBasis,
            enumerateFunction.getStrataCumulatedCardinal(self.degree))
        if self.sparse:
            # Filter according to the sparse_fitting_algorithm key
            if self.sparse_fitting_algorithm == "cloo":
                fitting_algorithm = ot.CorrectedLeaveOneOut()
            else:
                fitting_algorithm = ot.KFold()
            # Define the correspondinding projection strategy
            projectionStrategy = ot.LeastSquaresStrategy(
                ot.LeastSquaresMetaModelSelectionFactory(
                    ot.LARS(), fitting_algorithm))
        else:
            projectionStrategy = ot.LeastSquaresStrategy(X, y)
        algo = ot.FunctionalChaosAlgorithm(X, y, self.distribution,
                                           adaptiveStrategy,
                                           projectionStrategy)
        algo.run()
        self.result_ = algo.getResult()
        output_dimension = self.result_.getMetaModel().getOutputDimension()

        # sensitivity
        si = ot.FunctionalChaosSobolIndices(self.result_)
        if output_dimension == 1:
            self.feature_importances_ = [
                si.getSobolIndex(i) for i in range(input_dimension)
            ]
        else:
            self.feature_importances_ = [[0.0] * input_dimension
                                         ] * output_dimension
            for k in range(output_dimension):
                for i in range(input_dimension):
                    self.feature_importances_[k][i] = si.getSobolIndex(i, k)
        self.feature_importances_ = np.array(self.feature_importances_)
        return self
 def get_sobol_indices(self):
     return ot.FunctionalChaosSobolIndices(self._pce_result)