Skip to content

Causality from time series

The causality function and its methods provide a common interface for testing causal hypotheses. For analysing time series, all you need to do is provide a source and a target. Then, choose one of the available causality tests to quantify the (directional) dynamical dependence between source and target.

All high-level causality test are integrated with the uncertainty handling machinery in UncertainData.jl. Any combination of real-valued vectors, Vector{<:AbstractUncertainValue}, or AbstractUncertainValueDataset are accepted as inputs to causality, making uncertainty quantification on the causality statistics a breeze.

For more fine grained control over the analysis, check out the syntax overview for low-level estimators.

# CausalityToolsBase.causalityFunction.

causality(source, target, test::CausalityTest)

Test for a causal influence from source to target using the provided causality test.

Examples

Real-valued time series

x, y = rand(300), rand(300)

# Define some causality tests and apply them to `x` and `y`.
test_ccm = ConvergentCrossMappingTest(timeseries_lengths = [45, 50], n_reps = 20)
test_cm = CrossMappingTest(n_reps = 10)
test_vf = VisitationFrequencyTest(binning = RectangularBinning(5), ηs = 1:5)
test_tog = TransferOperatorGridTest(binning = RectangularBinning(5), ηs = 1:5)
test_jdd = JointDistanceDistributionTest()
test_jddt = JointDistanceDistributionTTest()
predtest = VisitationFrequencyTest(binning = RectangularBinning(5), ηs = -5:5)
test_pa = PredictiveAsymmetryTest(predictive_test = predtest)

causality(x, y, test_ccm)
causality(x, y, test_cm)
causality(x, y, test_vf)
causality(x, y, test_tog)
causality(x, y, test_jdd)
causality(x, y, test_jddt)
causality(x, y, test_pa)

Uncertain data

If your data have uncertainties, use the machinery in UncertainData.jl to define uncertain values, then use them directly as inputs to causality. Uncertain data may be mixed with regular real-valued vectors.

Any combination of real-valued vectors, Vector{<:AbstractUncertainValue} and AbstractUncertainValueDatasets are thus accepted for source and target. If uncertain data are provided, the data are resampled element-wise and the draws are used as input to the causality UncertainIndexValueDatasets are not yet supported. For more info, see the documentation for UncertainData.jl

# Vectors of uncertain values. Also, convert to uncertain datasets
uvals_x = [UncertainValue(Normal, rand(Normal(0, 5)), abs(rand(Normal(0, 3)))) for i = 1:100]
uvals_y = [UncertainValue(Normal, rand(Normal(0, 5)), abs(rand(Normal(0, 3)))) for i = 1:100];
uvx = UncertainValueDataset(uvals_x)
uvy = UncertainValueDataset(uvals_y)

# Draw a single realisation of `uvx` and a single realisation of `uvy`
x, y = resample(uvx), resample(uvy)

# A transfer entropy test using the [`TransferOperatorGrid`](@ref) estimator.
test_tog = TransferOperatorGridTest(binning = RectangularBinning(5), ηs = 1)

# `causality` accepts all combinations of real-valued and uncertain data types.
causality(x, y, test_tog)
causality(x, uvy, test_tog)
causality(uvx, y, test_tog)
causality(uvx, uvy, test_tog)
causality(x, uvals_y, test_tog)
causality(uvals_x, y, test_tog)
causality(uvals_x, uvals_y, test_tog)

source

Resampling uncertain time series with constraints

# CausalityToolsBase.causalityMethod.

causality(source, target, resampling::ConstrainedResampling{N}, 
    test::CausalityTest)

Test for a causal influence from source to target using the provided causality test. Both source and target might be uncertain data, which is resampled according to the resampling scheme.

This method uses the machinery from UncertainData.jl to constrain the furnishing distributions of the uncertain data during resampling, which offers complete control over the resampling procedure.

Arguments

  • source: The source. May be a real-valued vector, a Vector{AbstractUncertainValue}, or a AbstractUncertainValueDataset.
  • target: The target. May be a real-valued vector, a Vector{AbstractUncertainValue}, or a AbstractUncertainValueDataset.
  • resampling: A ConstrainedResampling instance. For one time series, provide the ConstrainedResampling constructor with either a single sampling constraint or a vector of sampling constraints. For two time series, provide the ConstrainedResampling constructor with a tuple, where each element in the tuple is either a single sampling constraint or a vector of sampling constraints. The sampling constraints comprising the first element of the tuple is then mapped to the uncertain values in source, and the second tuple is mapped to the elements of target.
  • test: An instance of a causality test.

Sampling constraints

See UncertainData.jl for a list of possible constraints and how to construct them. The examples below show a few alternatives. See also ConstrainedResampling.

Examples

# Vectors of uncertain values. Also, convert to uncertain datasets
uvals_x = [UncertainValue(Normal, rand(Normal(0, 5)), abs(rand(Normal(0, 3)))) for i = 1:100]
uvals_y = [UncertainValue(Normal, rand(Normal(0, 5)), abs(rand(Normal(0, 3)))) for i = 1:100];
uvx = UncertainValueDataset(uvals_x)
uvy = UncertainValueDataset(uvals_y)

# Draw a single realisation of `uvx` and a single realisation of `uvy`
x, y = resample(uvx), resample(uvy)

# A transfer entropy test using the [`TransferOperatorGrid`](@ref) estimator.
test_tog = TransferOperatorGridTest(binning = RectangularBinning(5), ηs = 1)

##############################
# Perform causality tests
##############################
# No constraints are needed, because no data are uncertain
causality(x, y, test_tog) 

# Applying the same constraint to all elements of the uncertain vectors
# ---------------------------------------------------------------------
onevar_constraints = ConstrainedResampling(TruncateStd(1))
twovar_constraints = ConstrainedResampling(TruncateStd(2), TruncateStd(1))


# Only one variable is constrained, so provide only one set of constraints
causality(x, uvy, onevar_constraints, test_tog) 
causality(uvx, y, onevar_constraints, test_tog)
causality(x, uvals_y, onevar_constraints, test_tog)
causality(uvals_x, y, onevar_constraints, test_tog)

# Both variables are constrained, so provide two sets of constraints
causality(uvx, uvy, twovar_constraints, test_tog)
causality(uvals_x, uvals_y, twovar_constraints, test_tog) 

# Applying different constraints on each element of the uncertain vectors
# -----------------------------------------------------------------------
constraints_x = [TruncateStd(1 + rand(Uniform(-0.5, 0.5))) for uv in uvals_x]
constraints_y = [TruncateStd(1 + rand(Uniform(-0.2, 0.2))) for uv in uvals_y]

# Constraints for x alone, constraints for y alone
crx = ConstrainedResampling(constraints_x)  
cry = ConstrainedResampling(constraints_y) 

# Compute causality statistic between one real-valued time series and an 
# uncertain time series. Resample the uncertain values according to the 
# `ConstrainedResampling`s we just defined.
causality(x, uvy, cry, test_tog) 
causality(uvx, y, crx, test_tog)
causality(x, uvals_y, cry, test_tog)
causality(uvals_x, y, crx, test_tog)

# Compute causality statistic between two uncertain time series. 
# We define separately constraints for y and y
crxy = ConstrainedResampling(constraints_x, constraints_y) 
causality(uvx, uvy, crxy, test_tog)
causality(uvals_x, uvals_y, crxy, test_tog) 

source

Resampling schemes

# UncertainData.Resampling.ConstrainedResamplingType.

ConstrainedResampling(constraint::NTuple{N, Union{SamplingConstraint, Vector{<:SamplingConstraint}}})

Indicates that resampling should be performed with constraints on the uncertain values.