The study presented in that section focuses on the growth of particular plant (not specified). The objective is to predict which height will be reached by the plant ... for example in order to evaluate the risk that the plant might require un greater jag on the balcony ...
The problem is that we have no data on the height usually reached by this kind of plant, which prohibits any use of statistics tools ... So ... what ? Yet we have the following information:
.... so we can model the plant growth thanks to a Bayes net and then have access to the variability of its final height!
Let us imagine (for the example purpose):
Some meteorological data (tropical place?):
Some remembrance of biology trainings:
In [1]:
from __future__ import print_function
import openturns as ot
import otagrum
import pyAgrum as gum
import pyAgrum.lib.notebook as gnb
We have to build the Bayes Net now. There are 3 variables that will be named : $Light$, $Moisture$ and $Height$.
In [2]:
# Create variables
light = gum.LabelizedVariable("Light", "quality of light", 0)
moisture = gum.LabelizedVariable("Moisture", "quantity of moisture", 0)
height = gum.DiscretizedVariable("Height", "plant growth")
Both variables $Light$ and $Moisture$ are categorical variables whith the following attributes:
$Height$ is a continuous variable which has to be discretized for the Bayes Net use.
In [3]:
## Create labels and ticks
# light has 2 attributes : Dim and Bright
light.addLabel("Dim")
light.addLabel("Bright")
# moisture has 2 attributes : Dry and Wet
moisture.addLabel("Dry")
moisture.addLabel("Wet")
# height is a discretized variable
[height.addTick(i) for i in range(0, 150, 10)]
height.domainSize()
Out[3]:
Furthermore, there are several influence links : $Light$ on $Moisture$, $(Light,Moisture)$ on $Height$.
In [4]:
## Create the net
bn = gum.BayesNet("Plant Growth")
# Add variables
indexLight = bn.add(light)
indexMoisture = bn.add(moisture)
indexHeight = bn.add(height)
# Add arcs
bn.addArc(indexLight, indexMoisture)
bn.addArc(indexLight, indexHeight)
bn.addArc(indexMoisture, indexHeight)
bn
Out[4]:
The next step is the quantification of the Bayes net.
The variable $Light$ is quantified as follows:
In [5]:
# Create conditional probability tables
# light conditional probability table
bn.cpt(indexLight)[:]= [0.25, 0.75]
gnb.showPotential(bn.cpt(indexLight))
The influence of $Light$ on $Moisture$ is modelized by:
In [6]:
# moisture conditional probability table
# We show the antecedents of moisture with the order in which they were declared
bn.cpt(indexMoisture)[{'Light' : 'Dim'}] = [0.2, 0.8]
bn.cpt(indexMoisture)[{'Light' : 'Bright'}] = [0.6, 0.4]
gnb.showPotential(bn.cpt(indexMoisture))
The influence of $(Light, Moisture)$ on $Height$ is modelized by:
In [7]:
# height has a conditional probability table
# We give here its conditional distributions
# distribution when Dim and Dry
heightWhenDimAndDry = ot.Uniform(0.0, 20.0)
# distribution when Dim and Wet
heightWhenDimAndWet = ot.Triangular(15.0, 30.0, 50.0)
# distribution when Bright and Dry
heightWhenBrightAndDry = ot.Triangular(0.0, 15.0, 30.0)
# distribution when Bright and Wet
heightWhenBrightAndWet = ot.Normal(90.0, 10.0)
# We have to enter some OT distributions whithin aGrUM conditional probability tables
# We show the antecedents of height with the order in which they were declared
# The new class Utils from otagrum is able to marry OT distributions and Agrum conditional probability tables
bn.cpt(indexHeight)[{'Light': 'Dim', 'Moisture': 'Dry'}] = otagrum.Utils.Discretize(heightWhenDimAndDry, height)[:]
bn.cpt(indexHeight)[{'Light': 'Bright', 'Moisture': 'Dry'}] = otagrum.Utils.Discretize(heightWhenBrightAndDry, height)[:]
bn.cpt(indexHeight)[{'Light': 'Dim', 'Moisture': 'Wet'}] = otagrum.Utils.Discretize(heightWhenDimAndWet, height)[:]
bn.cpt(indexHeight)[{'Light': 'Bright', 'Moisture': 'Wet'}] = otagrum.Utils.Discretize(heightWhenBrightAndWet, height)[:]
gnb.showPotential(bn.cpt(indexHeight))
We can study the plant growth variability in different situations like:
In [8]:
# Variability of the plant growth on my balcony
ie = gum.LazyPropagation(bn)
h_dist = otagrum.Utils.FromMarginal(ie.posterior("Height"))
print("Probability (height > 40cm) = ", 1.0 - h_dist.computeCDF(40.0))
h_dist.drawPDF()
Out[8]:
In [9]:
# Variability of the plant growth in my cellar
ie = gum.LazyPropagation(bn)
ie.setEvidence({'Light':'Dim'})
h_dist_dim = otagrum.Utils.FromMarginal(ie.posterior("Height"))
h_dist_dim.setDescription(['Height|Light=Dim'])
print("Probability (height > 40cm)|Light=Dim = ", 1.0 - h_dist_dim.computeCDF(40.0))
h_dist_dim.drawPDF()
Out[9]:
In [10]:
# Variability of the plant growth when the atmosphere is very wet
ie = gum.LazyPropagation(bn)
ie.setEvidence({'Moisture':'Wet'})
h_dist_wet = otagrum.Utils.FromMarginal(ie.posterior("Height"))
h_dist_wet.setDescription(['Height|Moisture=Wet'])
print("Probability (height > 40cm)|Moisture=Wet = ", 1.0 - h_dist_wet.computeCDF(40.0))
h_dist_wet.drawPDF()
Out[10]:
In [11]:
# Get the distribution of the variable "Light"
l_dist_wet = otagrum.Utils.FromPotential(ie.posterior("Light"))
print(l_dist_wet)
l_dist_wet.drawPDF()
Out[11]:
In [12]:
# Get the joint distribution [H, M]
ie = gum.LazyPropagation(bn)
ie.addJointTarget({"Height", "Moisture"})
ie.makeInference()
h_m_dist = otagrum.Utils.FromPotential(ie.jointPosterior({"Height", "Moisture"}))
print(h_m_dist.getDescription())
print(h_m_dist.getMarginal(0))