.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_example/application/plot_metamodel.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_example_application_plot_metamodel.py: Metamodel a FMU time-dependent output ===================================== .. GENERATED FROM PYTHON SOURCE LINES 6-27 This example shows how to create a metamodel of the :doc:`epidemiological model<../../examples/model_description>`. **To decrease the model simulation costs, let's create a metamodel.** Metamodeling a model with time-dependent output is a difficult problem. We will combine two methods: Karhunen-Loeve dimension reduction should precede the Kriging metamodeling. We will proceed the following way: - simulate the FMU *n* times on a design of experiment, - concentrate the information of the time-dependent output via Karhunen-Loeve, - metamodel the Karhunen-Loeve coefficients. The composition of the coefficients metamodel with the inverse Karhunen-Loeve will make the global metamodel. References ---------- - [anonymous1978]_ .. GENERATED FROM PYTHON SOURCE LINES 29-31 Create the metamodel ++++++++++++++++++++ .. GENERATED FROM PYTHON SOURCE LINES 34-38 .. code-block:: Python import otfmi.example.utility import openturns as ot import openturns.viewer as otv .. GENERATED FROM PYTHON SOURCE LINES 39-42 We load the FMU as a :class:`~otfmi.FMUPointToFieldFunction`. We concentrate on the first time unit of the epidemiological model output. The single uncertain input of the model is the ``ìnfection_rate``. .. GENERATED FROM PYTHON SOURCE LINES 42-52 .. code-block:: Python path_fmu = otfmi.example.utility.get_path_fmu("epid") function = otfmi.FMUPointToFieldFunction( path_fmu, inputs_fmu=["infection_rate"], outputs_fmu=["infected"], start_time=0.0, final_time=15.0, ) mesh = function.getOutputMesh() .. GENERATED FROM PYTHON SOURCE LINES 53-55 We create a Monte-Carlo design of experiment, on which we simulate the FMU. The simulation inputs and outputs will be used to train the metamodel. .. GENERATED FROM PYTHON SOURCE LINES 55-68 .. code-block:: Python inputLaw = ot.Uniform(1.5, 2.5) inputSample = inputLaw.getSample(10) outputFMUSample = function(inputSample) graph = outputFMUSample.draw().getGraph(0, 0) graph.setTitle("FMU simulations") graph.setXTitle("Time") graph.setYTitle("Number of infected") graph.setLegendFontSize(6.) graph.setLegends([f"{line[0]:.2f}" for line in inputSample[:10]]) view = otv.View(graph, legend_kw={"title": "infection rate", "loc": "upper left"}) .. image-sg:: /auto_example/application/images/sphx_glr_plot_metamodel_001.png :alt: FMU simulations :srcset: /auto_example/application/images/sphx_glr_plot_metamodel_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 69-70 We define a function to visualize the upcoming Karhunen-Loeve modes. .. GENERATED FROM PYTHON SOURCE LINES 70-95 .. code-block:: Python def drawKL(scaledKL, KLev, mesh, title="Scaled KL modes"): graph_modes = scaledKL.drawMarginal() graph_modes.setTitle(title + " scaled KL modes") graph_modes.setXTitle("$x$") graph_modes.setYTitle(r"$\sqrt{\lambda_i}\phi_i$") data_ev = [[i, KLev[i]] for i in range(scaledKL.getSize())] graph_ev = ot.Graph() graph_ev.add(ot.Curve(data_ev)) graph_ev.add(ot.Cloud(data_ev)) graph_ev.setTitle(title + " KL eigenvalues") graph_ev.setXTitle("$k$") graph_ev.setYTitle(r"$\lambda_i$") graph_ev.setAxes(True) graph_ev.setGrid(True) graph_ev.setLogScale(2) bb = graph_ev.getBoundingBox() lower = bb.getLowerBound() lower[1] = 1.0e-7 bb = ot.Interval(lower, bb.getUpperBound()) graph_ev.setBoundingBox(bb) return graph_modes, graph_ev .. GENERATED FROM PYTHON SOURCE LINES 96-99 We compute the Karhunen-Loeve decomposition of the model outputs. The underlying assumption is that these outputs are realizations of a stochastic process. .. GENERATED FROM PYTHON SOURCE LINES 99-104 .. code-block:: Python threshold = 1e-4 algoKL = ot.KarhunenLoeveSVDAlgorithm(outputFMUSample, threshold) algoKL.run() resultKL = algoKL.getResult() .. GENERATED FROM PYTHON SOURCE LINES 105-106 Let be curious and plot the Karhunen-Loeve modes: .. GENERATED FROM PYTHON SOURCE LINES 106-111 .. code-block:: Python phi_Y = resultKL.getScaledModesAsProcessSample() lambda_Y = resultKL.getEigenvalues() graph_modes_Y, graph_ev_Y = drawKL(phi_Y, lambda_Y, mesh, "Y") view = otv.View(graph_modes_Y) .. image-sg:: /auto_example/application/images/sphx_glr_plot_metamodel_002.png :alt: Y scaled KL modes :srcset: /auto_example/application/images/sphx_glr_plot_metamodel_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 112-114 Now that Karhunen-Loeve algorithm is trained, we can project them in the smaller-dimension space: .. GENERATED FROM PYTHON SOURCE LINES 114-118 .. code-block:: Python projectionSample = resultKL.project(outputFMUSample) n_mode = projectionSample.getDimension() print(f"Karhunen-Loeve projection in dimension {n_mode}") .. rst-class:: sphx-glr-script-out .. code-block:: none Karhunen-Loeve projection in dimension 3 .. GENERATED FROM PYTHON SOURCE LINES 119-122 We keep on following our road map, by metamodeling the projection of the curves on the smaller-dimension space. We metamodel the Karhunen-Loeve coefficients using ordinary Kriging. .. GENERATED FROM PYTHON SOURCE LINES 122-137 .. code-block:: Python dim = inputSample.getDimension() # only 1 input dimension univb = ot.ConstantBasisFactory(dim).build() # univariate basis coll = [ot.AggregatedFunction( [univb.build(i)] * n_mode) for i in range(univb.getSize())] basis = ot.Basis(coll) # multivariate basis covarianceModel = ot.SquaredExponential(dim) covarianceModel = ot.TensorizedCovarianceModel([covarianceModel] * n_mode) algo = ot.KrigingAlgorithm(inputSample, projectionSample, covarianceModel, basis) algo.run() result = algo.getResult() metamodel = result.getMetaModel() .. GENERATED FROM PYTHON SOURCE LINES 138-140 We have created all pieces for a "PointToField" metamodel. Let put these pieces together: .. GENERATED FROM PYTHON SOURCE LINES 140-149 .. code-block:: Python def globalMetamodel(sample): emulatedCoefficients = metamodel(sample) restoreFunction = ot.KarhunenLoeveLifting(resultKL) emulatedProcessSample = restoreFunction(emulatedCoefficients) return emulatedProcessSample .. GENERATED FROM PYTHON SOURCE LINES 150-152 Validate the metamodel ++++++++++++++++++++++ .. GENERATED FROM PYTHON SOURCE LINES 155-157 We create a new Monte-Carlo design of experiment. On this design of experiment, the FMU is simulated as well as the metamodel. .. GENERATED FROM PYTHON SOURCE LINES 157-161 .. code-block:: Python inputTestSample = inputLaw.getSample(10) outputFMUTestSample = function(inputTestSample) outputMetamodelTestSample = globalMetamodel(inputTestSample) .. GENERATED FROM PYTHON SOURCE LINES 162-163 First, we have a visual check: .. GENERATED FROM PYTHON SOURCE LINES 163-180 .. code-block:: Python gridLayout = ot.GridLayout(1, 2) graph1 = outputFMUTestSample.draw().getGraph(0, 0) graph1.setTitle("FMU simulations") graph2 = outputMetamodelTestSample.draw().getGraph(0, 0) graph2.setTitle("Metamodel") for graph in [graph1, graph2]: graph.setXTitle("Time") graph.setYTitle("Number of infected") graph.setLegends([f"{line[0]:.3f}" for line in inputSample[:10]]) gridLayout.setGraph(0, 0, graph1) gridLayout.setGraph(0, 1, graph2) view = otv.View( gridLayout, legend_kw={"title": "infection rate", "loc": "upper left"} ) .. image-sg:: /auto_example/application/images/sphx_glr_plot_metamodel_003.png :alt: , FMU simulations, Metamodel :srcset: /auto_example/application/images/sphx_glr_plot_metamodel_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 181-184 We validate the pertinence of Karhunen-Loeve decomposition: As the epidemiological model considers a population size of 763, the residual mean error on the field is acceptable. .. GENERATED FROM PYTHON SOURCE LINES 184-189 .. code-block:: Python validationKL = ot.KarhunenLoeveValidation(outputFMUTestSample, resultKL) graph = validationKL.computeResidualMean().draw() graph.setYTitle("infected residual mean") view = otv.View(graph) .. image-sg:: /auto_example/application/images/sphx_glr_plot_metamodel_004.png :alt: KL residual mean - 0 marginal :srcset: /auto_example/application/images/sphx_glr_plot_metamodel_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 190-192 We validate the Kriging (using the Karhunen-Loeve coefficients of the test sample): .. GENERATED FROM PYTHON SOURCE LINES 192-200 .. code-block:: Python projectFunction = ot.KarhunenLoeveProjection(resultKL) coefficientSample = projectFunction(outputFMUTestSample) predictions = metamodel(inputTestSample) validation = ot.MetaModelValidation(coefficientSample, predictions) Q2 = validation.computeR2Score()[0] print(Q2) .. rst-class:: sphx-glr-script-out .. code-block:: none 0.9999999980175561 .. GENERATED FROM PYTHON SOURCE LINES 201-205 The predictivity factor is very close to 1, which is satisfying. Further statistical tests exist in `OpenTURNS `_ to assert the quality of the obtained metamodel. .. GENERATED FROM PYTHON SOURCE LINES 207-217 ---------------------- The ``globalMetamodel`` (computationnally faster than the FMU) created with the above script can now be used as a faster substitute to the FMU for - `sensitivity analysis `_, - `parameter inference `_, - `estimate a failure probability `_, etc. .. GENERATED FROM PYTHON SOURCE LINES 220-221 .. code-block:: Python otv.View.ShowAll() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.752 seconds) .. _sphx_glr_download_auto_example_application_plot_metamodel.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_metamodel.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_metamodel.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_metamodel.zip `