common

independence_tests

class castle.common.independence_tests.CITest[source]

Bases: object

Class of conditional independence test that contains multiple method

static chi2_test(data, x, y, z)[source]

Chi-square conditional independence test.

Tests the null hypothesis that x is independent from y given z.

Parameters

datanumpy.ndarray

The dataset on which to test the independence condition.

xint

A variable in data set

yint

A variable in data set

zList, default []

A list of variable names contained in the data set, different from x and y. This is the separating set that (potentially) makes x and y independent.

Returns

chi2float

The test statistic.

dofint

Degrees of freedom

p_valuefloat

The p-value of the test

Examples

>>> import numpy as np
>>> import pandas as pd
>>> np.random.seed(23)
>>> data = np.random.randint(0, 5, size=100).reshape((-1, 4))
>>> chi2, dof, p_value = CITest.chi2_test(data, 0, 1, [])
>>> print(chi2, dof, p_value)
20.542792795683862 16 0.19676171971325737
>>> chi2, dof, p_value = CITest.chi2_test(data, 0, 1, [3])
>>> print(chi2, dof, p_value)
90.66096270618675 80 0.19483257969931803
>>> chi2, dof, p_value = CITest.chi2_test(data, 0, 1, [2, 3])
>>> print(chi2, dof, p_value)
401.830906690841 400 0.46485969015873324
static cressie_read(data, x, y, z)[source]

Cressie Read statistic for conditional independence[1].

Tests the null hypothesis that x is independent of y given z.

References

[1] Cressie, Noel, and Timothy RC Read. “Multinomial goodness‐of‐fit tests.” Journal of the Royal Statistical Society: Series B (Methodological) 46.3 (1984): 440-464.

Parameters

datanumpy.ndarray

The dataset on which to test the independence condition.

xint

A variable in data set

yint

A variable in data set

zList, default []

A list of variable names contained in the data set, different from x and y. This is the separating set that (potentially) makes x and y independent.

Returns

chi2float

The test statistic.

dofint

Degrees of freedom

p_valuefloat

The p-value of the test

Examples

>>> import numpy as np
>>> import pandas as pd
>>> np.random.seed(23)
>>> data = np.random.randint(0, 5, size=10000).reshape((-1, 4))
>>> chi2, dof, p_value = CITest.cressie_read(data, 0, 1, [])
>>> print(chi2, dof, p_value)
20.537851851639562 16 0.19696641879639076
>>> chi2, dof, p_value = CITest.cressie_read(data, 0, 1, [3])
>>> print(chi2, dof, p_value)
90.45257795422611 80 0.19903833818274186
>>> chi2, dof, p_value = CITest.cressie_read(data, 0, 1, [2, 3])
>>> print(chi2, dof, p_value)
404.24753197461905 400 0.43124831946260705
static fisherz_test(data, x, y, z)[source]

Fisher’s z-transform for conditional independence test

Parameters

datandarray

The dataset on which to test the independence condition.

xint

A variable in data set

yint

A variable in data set

zList, default []

A list of variable names contained in the data set different from x and y. This is the separating set that (potentially) makes x and y independent.

Returns

_: None _: None p: float

the p-value of conditional independence.

Examples

>>> import numpy as np
>>> import pandas as pd
>>> np.random.seed(23)
>>> data = np.random.rand(2500, 4)
>>> p_value = CITest.fisherz_test(data, 0, 1, [])
>>> print(p_value)
0.011609430716781555
>>> p_value = CITest.fisherz_test(data, 0, 1, [3])
>>> print(p_value)
0.01137523908727811
>>> p_value = CITest.fisherz_test(data, 0, 1, [2, 3])
>>> print(p_value)
0.011448214156529746
static freeman_tukey(data, x, y, z)[source]

Freeman Tuckey test for conditional independence [1].

Tests the null hypothesis that x is independent of y given z.

References

[1] Read, Campbell B. “Freeman—Tukey chi-squared goodness-of-fit statistics.” Statistics & probability letters 18.4 (1993): 271-278.

Parameters

datanumpy.ndarray

The dataset on which to test the independence condition.

xint

A variable in data set

yint

A variable in data set

zList, default []

A list of variable names contained in the data set, different from x and y. This is the separating set that (potentially) makes x and y independent.

Returns

chi2float

The test statistic.

dofint

Degrees of freedom

p_valuefloat

The p-value of the test

Examples

>>> import numpy as np
>>> import pandas as pd
>>> np.random.seed(23)
>>> data = np.random.randint(0, 5, size=10000).reshape((-1, 4))
>>> chi2, dof, p_value = CITest.freeman_tukey(data, 0, 1, [])
>>> print(chi2, dof, p_value)
20.586757281527213 16 0.19494739343907877
>>> chi2, dof, p_value = CITest.freeman_tukey(data, 0, 1, [3])
>>> print(chi2, dof, p_value)
91.06391187965758 80 0.18687227769183953
>>> chi2, dof, p_value = CITest.freeman_tukey(data, 0, 1, [2, 3])
>>> print(chi2, dof, p_value)
nan 400 nan
static g2_test(data, x, y, z)[source]

G squared test for conditional independence. Also commonly known as G-test, likelihood-ratio or maximum likelihood statistical significance test. Tests the null hypothesis that x is independent of y given z.

Parameters

datanumpy.ndarray

The dataset on which to test the independence condition.

xint

A variable in data set

yint

A variable in data set

zList, default []

A list of variable names contained in the data set, different from X and Y. This is the separating set that (potentially) makes X and Y independent.

Returns

chi2float

The test statistic.

dofint

Degrees of freedom

p_valuefloat

The p-value of the test

Examples

>>> import numpy as np
>>> import pandas as pd
>>> np.random.seed(23)
>>> data = np.random.randint(0, 5, size=10000).reshape((-1, 4))
>>> chi2, dof, p_value = CITest.g2_test(data, 0, 1, [])
>>> print(chi2, dof, p_value)
20.55310657691933 16 0.19633494733361465
>>> chi2, dof, p_value = CITest.g2_test(data, 0, 1, [3])
>>> print(chi2, dof, p_value)
90.54473365450676 80 0.1971708971451276
>>> chi2, dof, p_value = CITest.g2_test(data, 0, 1, [2, 3])
>>> print(chi2, dof, p_value)
429.0926603059854 400 0.15195497920948475
static modify_log_likelihood(data, x, y, z)[source]

Modified log likelihood ratio test for conditional independence.

Tests the null hypothesis that x is independent of y given z.

Parameters

datanumpy.ndarray

The dataset on which to test the independence condition.

xint

A variable in data set

yint

A variable in data set

zList, default []

A list of variable names contained in the data set, different from x and y. This is the separating set that (potentially) makes x and y independent.

Returns

chi2float

The test statistic.

dofint

Degrees of freedom

p_valuefloat

The p-value of the test

Examples

>>> import numpy as np
>>> import pandas as pd
>>> np.random.seed(23)
>>> data = np.random.randint(0, 5, size=10000).reshape((-1, 4))
>>> chi2, dof, p_value = CITest.modify_log_likelihood(data, 0, 1, [])
>>> print(chi2, dof, p_value)
20.639717717727184 16 0.19277870421685392
>>> chi2, dof, p_value = CITest.modify_log_likelihood(data, 0, 1, [3])
>>> print(chi2, dof, p_value)
91.97967547179121 80 0.16962335307180806
>>> chi2, dof, p_value = CITest.modify_log_likelihood(data, 0, 1, [2, 3])
>>> print(chi2, dof, p_value)
inf 400 0.0
static neyman(data, x, y, z)[source]

Neyman’s test for conditional independence[1].

Tests the null hypothesis that x is independent of y given z.

References

[1] https://en.wikipedia.org/wiki/Neyman%E2%80%93Pearson_lemma

Parameters

datanumpy.ndarray

The dataset on which to test the independence condition.

xint

A variable in data set

yint

A variable in data set

zList, default []

A list of variable names contained in the data set, different from x and y. This is the separating set that (potentially) makes x and y independent.

Returns

chi2float

The test statistic.

dofint

Degrees of freedom

p_valuefloat

The p-value of the test

Examples

>>> import numpy as np
>>> import pandas as pd
>>> np.random.seed(23)
>>> data = np.random.randint(0, 5, size=10000).reshape((-1, 4))
>>> chi2, dof, p_value = CITest.neyman(data, 0, 1, [])
>>> print(chi2, dof, p_value)
20.804888528281907 16 0.1861329703686255
>>> chi2, dof, p_value = CITest.neyman(data, 0, 1, [3])
>>> print(chi2, dof, p_value)
95.07200788651971 80 0.11980672825724373
>>> chi2, dof, p_value = CITest.neyman(data, 0, 1, [2, 3])
>>> print(chi2, dof, p_value)
nan 400 nan
castle.common.independence_tests.hsic_test(x, y, alpha=0.05, normalize=True)[source]

Hilbert-Schmidt independence criterion

HSIC with a Gaussian kernel for the independence test, where we used the gamma distribution as an approximation for the distribution of the HSIC.

References

https://papers.nips.cc/paper/3201-a-kernel-statistical-test-of-independence.pdf

Parameters

x: numpy array

Data of the first variable. (n, dim_x) numpy array.

y: numpy array

Data of the second variable. (n, dim_y) numpy array.

alphafloat, default 0.05

significance level

normalize: bool, default True

whether use data normalization

Returns

out: int, 0 or 1

If 0, x and y are not independent. If 1, x and y are independent.

Examples

>>> import numpy as np
>>> np.random.seed(1)
>>> x = np.random.rand(500, 2)
>>> print(hsic_test(x[:, [0]], x[:, [1]]))
1
>>> x = np.random.rand(500, 1)
>>> z = x * 2
>>> print(hsic_test(x, z))
0
castle.common.independence_tests.power_divergence(data, x, y, z, lambda_=None)[source]

This function tests the null hypothesis that the categorical data.

The null hypothesis for the test is x is independent of y given z. A lot of the frequency comparison based statistics (eg. chi-square, G-test etc) belong to power divergence family, and are special cases of this test.

Parameters

datanumpy.ndarray

The dataset on which to test the independence condition.

xint

A variable in data set

yint

A variable in data set

zList, default []

A list of variable names contained in the data set, different from X and Y. This is the separating set that (potentially) makes X and Y independent.

lambda_float or str, optional

By default, the statistic computed in this test is Pearson’s chi-squared statistic [2]. lambda_ allows a statistic from the Cressie-Read power divergence family [3] to be used instead. For convenience, lambda_ may be assigned one of the following strings, in which case the corresponding numerical value is used:

String              Value   Description
"pearson"             1     Pearson's chi-squared statistic.
                            In this case, the function is
                            equivalent to `stats.chisquare`.
"log-likelihood"      0     Log-likelihood ratio. Also known as
                            the G-test [3]_.
"freeman-tukey"      -1/2   Freeman-Tukey statistic.
"mod-log-likelihood" -1     Modified log-likelihood ratio.
"neyman"             -2     Neyman's statistic.
"cressie-read"        2/3   The power recommended in [5]_.

Returns

chi2float

The test statistic.

dofint

Degrees of freedom

p_valuefloat

The p-value of the test

References

See Also

scipy.stats.power_divergence scipy.stats.chi2_contingency

Examples

>>> import numpy as np
>>> import pandas as pd
>>> np.random.seed(23)
>>> data = np.random.randint(0, 5, size=100).reshape((-1, 4))
>>> data = np.concatenate([data, data.sum(axis=1).reshape(-1, 1)], axis=1)
>>> chi2, dof, p_value = power_divergence(data, 0, 1, [])
>>> print(chi2, dof, p_value)
>>> 16.005291005291006 16 0.45259159404543464
>>> chi2, dof, p_value = power_divergence(data, 0, 1, [3])
>>> print(chi2, dof, p_value)
>>> 25.333333333333336 25 0.4438225249645223
>>> chi2, dof, p_value = power_divergence(data, 0, 1, [3, 4])
>>> print(chi2, dof, p_value)
>>> 0.0 5 1.0

plot_dag

class castle.common.plot_dag.GraphDAG(est_dag, true_dag=None, show=True, save_name=None)[source]

Bases: object

Visualization for causal discovery learning results.

Parameters

est_dag: np.ndarray

The DAG matrix to be estimated.

true_dag: np.ndarray

The true DAG matrix.

show: bool

Select whether to display pictures.

save_name: str

The file name of the image to be saved.

priori_knowledge

class castle.common.priori_knowledge.PrioriKnowledge(n_nodes)[source]

Bases: object

A class for a priori knowledge.

Parameters

n_nodes: int

denotes the number of nodes

Attributes

matrix: np.ndarray

0 : i does not have a directed edge to j; 1 : i has a directed edge to j; -1 : No prior background_knowledge is available to know if either of

the two cases above (0 or 1) is true.

add_forbidden_edge(i, j) None[source]

Add a forbidden edge between i and j.

Parameters

i: int

denotes location of the source node

j: int

denotes location of the target node

Examples

>>> p = PrioriKnowledge(4)
>>> p.add_forbidden_edge(0, 1)
>>> print(p.matrix)
[[ 0  0 -1 -1]
 [-1  0 -1 -1]
 [-1 -1  0 -1]
 [-1 -1 -1  0]]
add_forbidden_edges(edges) None[source]

Add multiple forbidden edges using a list of tuples.

Parameters

edges: list

list of (i, j)

Examples

>>> p = PrioriKnowledge(4)
>>> p.add_forbidden_edges([(0, 1), (1, 2)]
>>> print(p.matrix)
[[ 0  0 -1 -1]
 [-1  0  0 -1]
 [-1 -1  0 -1]
 [-1 -1 -1  0]]
add_required_edge(i, j) None[source]

Add a required edge i–>j.

Parameters

i: int

denotes location of the source node

j: int

denotes location of the target node

Examples

>>> p = PrioriKnowledge(4)
>>> p.add_required_edge(0, 1)
>>> print(p.matrix)
[[ 0  1 -1 -1]
 [-1  0 -1 -1]
 [-1 -1  0 -1]
 [-1 -1 -1  0]]
add_required_edges(edges) None[source]

Add multiple required edges using a list of tuples.

Parameters

edges: list

list of (i, j)

Examples

>>> p = PrioriKnowledge(4)
>>> p.add_required_edges([(0, 1), (1, 2)]
>>> print(p.matrix)
[[ 0  1 -1 -1]
 [-1  0  1 -1]
 [-1 -1  0 -1]
 [-1 -1 -1  0]]
add_undirected_edge(i, j) None[source]

Add an edge with unknown direction i—j.

Parameters

i: int

denotes location of the source node

j: int

denotes location of the target node

Examples

>>> p = PrioriKnowledge(4)
>>> p.add_undirected_edge(0, 1)
>>> print(p.matrix)
[[ 0  1 -1 -1]
 [ 1  0 -1 -1]
 [-1 -1  0 -1]
 [-1 -1 -1  0]]
add_undirected_edges(edges) None[source]

Add multiple edges with unknown direction by using a list of tuples.

Parameters

edges: list

list of (i, j)

Examples

>>> p = PrioriKnowledge(4)
>>> p.add_undirected_edges([(0, 1), (1, 2)]
>>> print(p.matrix)
[[ 0  1 -1 -1]
 [ 1  0  1 -1]
 [-1  1  0 -1]
 [-1 -1 -1  0]]
is_forbidden(i, j) bool[source]
is_required(i, j) bool[source]
remove_edge(i, j) None[source]

Remove any edges i—j and j—i.

castle.common.priori_knowledge.orient_by_priori_knowledge(skeleton, priori_knowledge)[source]

Orient the direction of all edges based on a priori knowledge.

Parameters

skeleton: np.ndarray

a skeleton matrix

priori_knowledge: PrioriKnowledge

a class object

Returns

out: np.ndarray

where out[i, j] = out[j, i] = 0 indicates i j; out[i, j] = 1 and out[j, i] = 0 indicates i–>j; out[i, j] = 1 and out[j, i] = 1 indicates i—j;