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
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
def _buildChaosAlgo(self, inputSample, outputSample): """ Build the functional chaos algorithm without running it. """ if self._distribution is None: # create default distribution : Uniform between min and max of the # input sample inputSample = ot.NumericalSample(inputSample) inputMin = inputSample.getMin() inputMin[0] = np.min(self._defectSizes) inputMax = inputSample.getMax() inputMax[0] = np.max(self._defectSizes) marginals = [ ot.Uniform(inputMin[i], inputMax[i]) for i in range(self._dim) ] self._distribution = ot.ComposedDistribution(marginals) # put description of the inputSample into decription of the distribution self._distribution.setDescription(inputSample.getDescription()) if self._adaptiveStrategy is None: # Create the adaptive strategy : default is fixed strategy of degree 5 # with linear enumerate function polyCol = [0.] * self._dim for i in range(self._dim): polyCol[i] = ot.StandardDistributionPolynomialFactory( self._distribution.getMarginal(i)) enumerateFunction = ot.EnumerateFunction(self._dim) multivariateBasis = ot.OrthogonalProductPolynomialFactory( polyCol, enumerateFunction) # default degree is 3 (in __init__) indexMax = enumerateFunction.getStrataCumulatedCardinal( self._degree) self._adaptiveStrategy = ot.FixedStrategy(multivariateBasis, indexMax) if self._projectionStrategy is None: # sparse polynomial chaos basis_sequence_factory = ot.LAR() fitting_algorithm = ot.KFold() approximation_algorithm = ot.LeastSquaresMetaModelSelectionFactory( basis_sequence_factory, fitting_algorithm) self._projectionStrategy = ot.LeastSquaresStrategy( inputSample, outputSample, approximation_algorithm) return ot.FunctionalChaosAlgorithm(inputSample, outputSample, \ self._distribution, self._adaptiveStrategy, self._projectionStrategy)
def ComputeSparseLeastSquaresChaos(inputTrain, outputTrain, multivariateBasis, totalDegree, myDistribution): """ Create a sparse polynomial chaos based on least squares. * Uses the enumerate rule in multivariateBasis. * Uses the LeastSquaresStrategy to compute the coefficients based on least squares. * Uses LeastSquaresMetaModelSelectionFactory to use the LARS selection method. * Uses FixedStrategy in order to keep all the coefficients that the LARS method selected. Parameters ---------- inputTrain : ot.Sample The input design of experiments. outputTrain : ot.Sample The output design of experiments. multivariateBasis : ot.Basis The multivariate chaos basis. totalDegree : int The total degree of the chaos polynomial. myDistribution : ot.Distribution. The distribution of the input variable. Returns ------- result : ot.PolynomialChaosResult The estimated polynomial chaos. """ selectionAlgorithm = ot.LeastSquaresMetaModelSelectionFactory() projectionStrategy = ot.LeastSquaresStrategy(inputTrain, outputTrain, selectionAlgorithm) enumfunc = multivariateBasis.getEnumerateFunction() P = enumfunc.getStrataCumulatedCardinal(totalDegree) adaptiveStrategy = ot.FixedStrategy(multivariateBasis, P) chaosalgo = ot.FunctionalChaosAlgorithm(inputTrain, outputTrain, myDistribution, adaptiveStrategy, projectionStrategy) chaosalgo.run() result = chaosalgo.getResult() return result
Y = myModel(X) dimension = X.getDimension() # %% # build the orthogonal basis coll = [ ot.StandardDistributionPolynomialFactory(distribution.getMarginal(i)) for i in range(dimension) ] enumerateFunction = ot.LinearEnumerateFunction(dimension) productBasis = ot.OrthogonalProductPolynomialFactory(coll, enumerateFunction) # %% # create the algorithm degree = 6 adaptiveStrategy = ot.FixedStrategy( productBasis, enumerateFunction.getStrataCumulatedCardinal(degree)) projectionStrategy = ot.LeastSquaresStrategy() algo = ot.FunctionalChaosAlgorithm(X, Y, distribution, adaptiveStrategy, projectionStrategy) algo.run() # %% # get the metamodel function result = algo.getResult() metamodel = result.getMetaModel() # %% # Print residuals result.getResiduals()
print('sampling size = ', N) output_database = ishigami_model(input_database) # Learning input/output # Usual chaos meta model enumerate_function = ot.HyperbolicAnisotropicEnumerateFunction(dimension) orthogonal_basis = ot.OrthogonalProductPolynomialFactory( dimension * [ot.LegendreFactory()], enumerate_function) basis_size = 100 # Initial chaos algorithm adaptive_strategy = ot.FixedStrategy(orthogonal_basis, basis_size) # ProjectionStrategy ==> Sparse fitting_algorithm = ot.KFold() approximation_algorithm = ot.LeastSquaresMetaModelSelectionFactory( ot.LARS(), fitting_algorithm) projection_strategy = ot.LeastSquaresStrategy(input_database, output_database, approximation_algorithm) print('Surrogate model...') distribution_ishigami = ot.ComposedDistribution(dimension * [ot.Uniform(-pi, pi)]) algo_pc = ot.FunctionalChaosAlgorithm(input_database, output_database, distribution_ishigami, adaptive_strategy, projection_strategy) algo_pc.run() chaos_result = algo_pc.getResult() print('Surrogate model computed') # Validation lhs_validation = ot.LHSExperiment(distribution_ishigami, 100) input_validation = lhs_validation.generate() output_validation = ishigami_model(input_validation) # Chaos model evaluation
sample_xi_X = result_X.project(sample_X) print("project sample_Y") sample_xi_Y = result_Y.project(sample_Y) print("Compute PCE between coefficients") degree = 1 dimension_xi_X = sample_xi_X.getDimension() dimension_xi_Y = sample_xi_Y.getDimension() enumerateFunction = ot.LinearEnumerateFunction(dimension_xi_X) basis = ot.OrthogonalProductPolynomialFactory( [ot.HermiteFactory()] * dimension_xi_X, enumerateFunction) basisSize = enumerateFunction.getStrataCumulatedCardinal(degree) adaptive = ot.FixedStrategy(basis, basisSize) projection = ot.LeastSquaresStrategy( ot.LeastSquaresMetaModelSelectionFactory(ot.LARS(), ot.CorrectedLeaveOneOut())) ot.ResourceMap.SetAsScalar("LeastSquaresMetaModelSelection-ErrorThreshold", 1.0e-7) algo_chaos = ot.FunctionalChaosAlgorithm(sample_xi_X, sample_xi_Y, basis.getMeasure(), adaptive, projection) algo_chaos.run() result_chaos = algo_chaos.getResult() meta_model = result_chaos.getMetaModel() print("myConvolution=", myConvolution.getInputDimension(), "->", myConvolution.getOutputDimension()) preprocessing = ot.KarhunenLoeveProjection(result_X) print("preprocessing=", preprocessing.getInputDimension(), "->", preprocessing.getOutputDimension()) print("meta_model=", meta_model.getInputDimension(), "->",
enumerateFunction = ot.LinearEnumerateFunction(dimension) productBasis = ot.OrthogonalProductPolynomialFactory( polynomialCollection, enumerateFunction) # Create the adaptive strategy degree = 8 basisSize = enumerateFunction.getStrataCumulatedCardinal(degree) adaptiveStrategy = ot.FixedStrategy(productBasis, basisSize) # Select the fitting algorithm fittingAlgorithm = ot.KFold() leastSquaresFactory = ot.LeastSquaresMetaModelSelectionFactory( ot.LARS(), fittingAlgorithm) # Projection strategy projectionStrategy = ot.LeastSquaresStrategy( inputSample, outputSample, leastSquaresFactory) algo = ot.FunctionalChaosAlgorithm( inputSample, outputSample, distribution, adaptiveStrategy, projectionStrategy) # Reinitialize the RandomGenerator to see the effect of the sampling # method only ot.RandomGenerator.SetSeed(0) algo.run() # Get the results result = algo.getResult() # MetaModelValidation - SPC metaModelValidationSPC = ot.MetaModelValidation( inputValidation, outputValidation, result.getMetaModel()) print("")
# %% # Create a training sample # %% N = 100 inputTrain = im.distributionX.getSample(N) outputTrain = im.model(inputTrain) # %% # Create the chaos. # %% multivariateBasis = ot.OrthogonalProductPolynomialFactory( [im.X1, im.X2, im.X3]) selectionAlgorithm = ot.LeastSquaresMetaModelSelectionFactory() projectionStrategy = ot.LeastSquaresStrategy(inputTrain, outputTrain, selectionAlgorithm) totalDegree = 8 enumfunc = multivariateBasis.getEnumerateFunction() P = enumfunc.getStrataCumulatedCardinal(totalDegree) adaptiveStrategy = ot.FixedStrategy(multivariateBasis, P) chaosalgo = ot.FunctionalChaosAlgorithm(inputTrain, outputTrain, im.distributionX, adaptiveStrategy, projectionStrategy) # %% chaosalgo.run() result = chaosalgo.getResult() metamodel = result.getMetaModel() # %% # Print Sobol' indices
# Create the correlated input distribution S = ot.CorrelationMatrix(2) S[1, 0] = 0.3 R = ot.NormalCopula.GetCorrelationFromSpearmanCorrelation(S) copula = ot.NormalCopula(R) distribution_corr = ot.ComposedDistribution([ot.Normal()] * 2, copula) # %% # ANCOVA needs a functional decomposition of the model enumerateFunction = ot.LinearEnumerateFunction(2) productBasis = ot.OrthogonalProductPolynomialFactory([ot.HermiteFactory()] * 2, enumerateFunction) adaptiveStrategy = ot.FixedStrategy( productBasis, enumerateFunction.getStrataCumulatedCardinal(4)) samplingSize = 250 projectionStrategy = ot.LeastSquaresStrategy( ot.MonteCarloExperiment(samplingSize)) algo = ot.FunctionalChaosAlgorithm(model, distribution, adaptiveStrategy, projectionStrategy) algo.run() result = ot.FunctionalChaosResult(algo.getResult()) # %% # Create the input sample taking account the correlation size = 2000 sample = distribution_corr.getSample(size) # %% # Perform the decomposition ancova = ot.ANCOVA(result, sample) # Compute the ANCOVA indices (first order and uncorrelated indices are computed together) indices = ancova.getIndices()
dim = model.getInputDimension() print("dim=", dim) size = dim + 1 distribution = ot.ComposedDistribution([ot.Normal()] * dim) weightedExperiment = ot.MonteCarloExperiment(distribution, size) inSample, weights = weightedExperiment.generateWithWeights() print("Sample model") t0 = time() outSample = model(inSample) t1 = time() print("t=", t1 - t0, "s, speed=", inSample.getSize() / (t1 - t0), "evals/s") basis = ot.OrthogonalProductPolynomialFactory([ot.HermiteFactory()] * dim) adaptive = ot.FixedStrategy(basis, dim + 1) projection = ot.LeastSquaresStrategy(weightedExperiment) algo = ot.FunctionalChaosAlgorithm(inSample, outSample, distribution, adaptive, projection) algo.run() vector = ot.FunctionalChaosRandomVector(algo.getResult()) # Field of Sobol indices #for i in range(dim): for i in range(15, 16): print("i=", i) sobol = [ vector.getSobolIndex(i, j) for j in range(mesh.getVerticesNumber()) ] field = ot.Field(mesh, [[x] for x in sobol]) graph = field.draw() graph.setTitle("Sobol index field - component " + str(i))
maximumConsideredTerms = 500 mostSignificant = 50 significanceFactor = 1.0e-4 truncatureBasisStrategy_2 = ot.CleaningStrategy( multivariateBasis, maximumConsideredTerms, mostSignificant, significanceFactor, True) # %% # STEP 3: Evaluation strategy of the approximation coefficients # ------------------------------------------------------------- # %% # The technique illustrated is the Least Squares technique where the points come from an design of experiments. Here : the Monte Carlo sampling technique. # %% sampleSize = 100 evaluationCoeffStrategy = ot.LeastSquaresStrategy( ot.MonteCarloExperiment(sampleSize)) # %% # You can specify the approximation algorithm. This is the algorithm that generates a sequence of basis using Least Angle Regression. # %% basisSequenceFactory = ot.LARS() # %% # This algorithm estimates the empirical error on each sub-basis using Leave One Out strategy. # %% fittingAlgorithm = ot.CorrectedLeaveOneOut() # Finally the metamodel selection algorithm embbeded in LeastSquaresStrategy approximationAlgorithm = ot.LeastSquaresMetaModelSelectionFactory( basisSequenceFactory, fittingAlgorithm)
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
myCopula = ot.NormalCopula(R) myCorrelatedInputDistribution = ot.ComposedDistribution( [ot.Normal()] * inputDimension, myCopula) sample = myCorrelatedInputDistribution.getSample(2000) # Orthogonal basis enumerateFunction = ot.LinearEnumerateFunction(inputDimension) productBasis = ot.OrthogonalProductPolynomialFactory( [ot.HermiteFactory()] * inputDimension, enumerateFunction) # Adaptive strategy adaptiveStrategy = ot.FixedStrategy( productBasis, enumerateFunction.getStrataCumulatedCardinal(4)) # Projection strategy samplingSize = 250 projectionStrategy = ot.LeastSquaresStrategy( ot.MonteCarloExperiment(samplingSize)) # Polynomial chaos algorithm algo = ot.FunctionalChaosAlgorithm( model, distribution, adaptiveStrategy, projectionStrategy) algo.run() # Post-process the results result = ot.FunctionalChaosResult(algo.getResult()) ancova = ot.ANCOVA(result, sample) indices = ancova.getIndices() uncorrelatedIndices = ancova.getUncorrelatedIndices() for i in range(inputDimension): value = indices[i] print("ANCOVA index", i, "= %.6g" %
######################## ### Chaos Polynomial ### ######################## polyColl = ot.PolynomialFamilyCollection(dim) for i in range(dim): polyColl[i] = ot.HermiteFactory() enumerateFunction = ot.LinearEnumerateFunction(dim) multivariateBasis = ot.OrthogonalProductPolynomialFactory(polyColl, enumerateFunction) basisSequenceFactory = ot.LARS() fittingAlgorithm = ot.CorrectedLeaveOneOut() approximationAlgorithm = ot.LeastSquaresMetaModelSelectionFactory(basisSequenceFactory, fittingAlgorithm) evalStrategy = ot.LeastSquaresStrategy(Data, Result, approximationAlgorithm) order = 3 P = enumerateFunction.getStrataCumulatedCardinal(order) truncatureBasisStrategy = ot.FixedStrategy(multivariateBasis, P) polynomialChaosAlgorithm = ot.FunctionalChaosAlgorithm(Data, Result, ot.Distribution(myDistribution), truncatureBasisStrategy, evalStrategy) polynomialChaosAlgorithm.run() The_Result = polynomialChaosAlgorithm.getResult() Error = The_Result.getRelativeErrors() ChaosRV = ot.FunctionalChaosRandomVector(The_Result) Mean = ChaosRV.getMean()[0] StD = np.sqrt(ChaosRV.getCovariance()[0,0])
def train(self): self.input_dim = self.training_points[None][0][0].shape[1] x_train = ot.Sample(self.training_points[None][0][0]) y_train = ot.Sample(self.training_points[None][0][1]) # Distribution choice of the inputs to Create the input distribution distributions = [] dist_specs = self.options["uncertainty_specs"] if dist_specs: if len(dist_specs) != self.input_dim: raise SurrogateOpenturnsException( "Number of distributions should be equal to input \ dimensions. Should be {}, got {}".format( self.input_dim, len(dist_specs) ) ) for ds in dist_specs: dist_klass = getattr(sys.modules["openturns"], ds["name"]) args = [ds["kwargs"][name] for name in DISTRIBUTION_SIGNATURES[ds["name"]]] distributions.append(dist_klass(*args)) else: for i in range(self.input_dim): mean = np.mean(x_train[:, i]) lower, upper = 0.95 * mean, 1.05 * mean if mean < 0: lower, upper = upper, lower distributions.append(ot.Uniform(lower, upper)) distribution = ot.ComposedDistribution(distributions) # Polynomial basis # step 1 - Construction of the multivariate orthonormal basis: # Build orthonormal or orthogonal univariate polynomial families # (associated to associated input distribution) polynoms = [0.0] * self.input_dim for i in range(distribution.getDimension()): polynoms[i] = ot.StandardDistributionPolynomialFactory( distribution.getMarginal(i) ) enumerateFunction = ot.LinearEnumerateFunction(self.input_dim) productBasis = ot.OrthogonalProductPolynomialFactory( polynoms, enumerateFunction ) # step 2 - Truncation strategy of the multivariate orthonormal basis: # a strategy must be chosen for the selection of the different terms # of the multivariate basis. # Truncature strategy of the multivariate orthonormal basis # We choose all the polynomials of degree <= degree degree = self.options["pce_degree"] index_max = enumerateFunction.getStrataCumulatedCardinal(degree) adaptive_strategy = ot.FixedStrategy(productBasis, index_max) basis_sequenceFactory = ot.LARS() fitting_algorithm = ot.CorrectedLeaveOneOut() approximation_algorithm = ot.LeastSquaresMetaModelSelectionFactory( basis_sequenceFactory, fitting_algorithm ) projection_strategy = ot.LeastSquaresStrategy( x_train, y_train, approximation_algorithm ) algo = ot.FunctionalChaosAlgorithm( x_train, y_train, distribution, adaptive_strategy, projection_strategy ) # algo = ot.FunctionalChaosAlgorithm(X_train_NS, Y_train_NS) algo.run() self._pce_result = algo.getResult()