因果发现 CausalDiscovery


在因果推断任务中,首先要找到潜在的因果关系,即所谓的因果结构。理论上,这些关系能够通过设计随机实验或者施加干涉被揭露。 然而,现实中这些方法的代价过于昂贵,有些甚至不可行。因此,近年来许多通过直接利用观测数据来分析因果结构的技术被提出来,如 PC算法 (Spirtes2001) ,No-Tears算法 (Zheng2018)。这些技术称为因果发现

YLearn因果发现实现了一个基于分数的 No-Tears 算法。之后会陆续加入更多的方法。

No-Tears 算法

No-Tears 揭示了有向无环图 (DAG) 结构的问题可以通过在具有强制执行无环条件的约束的实矩阵上制定连续优化问题来解决。 具体地说,对于给定的向量 $x \in \mathbb{R}^d$,存在一个矩阵 $V$ ,满足某个噪声向量 $x = Vx + \eta$ ,使 $\eta \in \mathbb{R}^d$的优化问题可以描述如下:

$$\min_{W \in \mathbb{R}^{d\times d}} F(W) , \quad s.t. \quad h(W) = 0$$

其中, $F(W)$ 是一个衡量 $|x - Wx|$ 的连续方程;

此外,

$$h(W) = tr\left( e^{W \circ W} \right)$$

其中 $\circ$ 是阿达玛乘积(Hadamard product)。整个公式可以通过一些优化技术来解决,比如梯度下降。

NO-TEARS 算法的类是 CausalDiscovery.


    import pandas as pd
    
    from ylearn.exp_dataset.gen import gen
    from ylearn.causal_discovery import CausalDiscovery
    
    X = gen()
    X = pd.DataFrame(X, columns=[f'x{i}' for i in range(X.shape[1])])
    cd = CausalDiscovery(hidden_layer_dim=[3])
    est = cd(X, threshold=0.01, return_dict=True)
    
    print(est)
    

    >>> OrderedDict([('x0', []), ('x1', ['x0', 'x2', 'x3', 'x4']), ('x2', ['x0']), ('x3', ['x0', 'x2', 'x4']), ('x4', ['x0', 'x2'])])