econml.grf._base_grftree.GRFTree

class econml.grf._base_grftree.GRFTree(*, criterion='mse', splitter='best', max_depth=None, min_samples_split=10, min_samples_leaf=5, min_weight_fraction_leaf=0.0, min_var_leaf=None, min_var_leaf_on_val=False, max_features=None, random_state=None, min_impurity_decrease=0.0, min_balancedness_tol=0.45, honest=True)[source]

基类: econml.tree._tree_classes.BaseTree

广义随机森林(Generalized Random Forest)中的树 [grftree1]。此方法主要应通过 BaseGRF 森林类及其派生类使用,不应作为独立估计器使用。它拟合一棵树,解决局部矩方程问题

E[ m(Z; theta(x)) | X=x] = 0

对于某个矩向量函数 m,该函数将随机变量 Z 的随机样本作为输入,并由某个未知参数 theta(x) 参数化。树中的每个节点包含参数 theta(x) 的局部估计,针对落入该叶节点的 X 的每个区域。

参数
  • criterion ({'mse', 'het'},默认 'mse') – 用于衡量分裂质量的函数。支持的准则有 'mse' 表示线性矩估计树中的均方误差,'het' 表示异质性得分。这些准则解决任何形式的线性矩问题

    E[J * theta(x) - A | X = x] = 0
    
    • 'mse' 准则寻找最大化得分的分裂

      sum_{child} weight(child) * theta(child).T @ E[J | X in child] @ theta(child)
      
      - In the case of a causal tree, this coincides with minimizing the MSE:
      
        .. code-block::
      
          sum_{child} E[(Y - <theta(child), T>)^2 | X=child] weight(child)
      
      - In the case of an IV tree, this roughly coincides with minimize the projected MSE::
      
        .. code-block::
      
          sum_{child} E[(Y - <theta(child), E[T|Z]>)^2 | X=child] weight(child)
      

      在内部,对于超过两种处理或只有一种处理且 fit_intercept=True 的情况,出于计算目的,此准则由计算上更简单的变体近似。特别是,它被替换为

      sum_{child} weight(child) * rho(child).T @ E[J | X in child] @ rho(child)
      

      其中

      rho(child) := J(parent)^{-1} E[A - J * theta(parent) | X in child]
      

      这可以被视为一种诱导异质性的得分,但更侧重于子节点雅可比矩阵 E[J | X in child] 的最小特征值较大的得分,这导致估计的方差更小,参数的识别更强。

    • 'het' 准则寻找最大化纯参数异质性得分的分裂

      sum_{child} weight(child) * rho(child).T @ rho(child)
      

      这可以被视为对理想异质性得分的近似

      weight(left) * weight(right) || theta(left) - theta(right)||_2^2 / weight(parent)^2
      

      [grftree1] 中所述

  • splitter ({“best”},默认 “best”) – 用于在每个节点选择分裂的策略。支持的策略为 “best” 以选择最佳分裂。

  • max_depth (int,默认 None) – 树的最大深度。如果为 None,则节点会一直扩展,直到所有叶节点都纯净或所有叶节点包含的样本少于 min_samples_split。

  • min_samples_split (int 或 float,默认 10) – 分裂内部节点所需的最小样本数

    • 如果为 int,则将其视为最小样本数 min_samples_split

    • 如果为 float,则 min_samples_split 是一个分数,每个分裂所需的最小样本数是 ceil(min_samples_split * n_samples)

  • min_samples_leaf (int 或 float,默认 5) – 叶节点所需的最小样本数。只有当分裂点在任一深度分裂后,左右分支都至少保留 min_samples_leaf 个训练样本时,该分裂点才会被考虑。这可能会使模型更加平滑,尤其是在回归中。

    • 如果为 int,则将其视为最小样本数 min_samples_leaf

    • 如果为 float,则 min_samples_leaf 是一个分数,每个节点所需的最小样本数是 ceil(min_samples_leaf * n_samples)

  • min_weight_fraction_leaf (float,默认 0.0) – 叶节点所需的总权重(所有输入样本的总权重)的最小加权分数。当未提供 sample_weight 时,样本权重相等。

  • min_var_leaf (None 或 (0, infinity) 中的 double,默认 None) – 对感兴趣参数的最小识别度进行约束。这避免了在处理方差较小、或工具变量与处理的相关性较小、或工具变量方差较小的情况下进行分裂。通常对于任何线性矩问题,这转化为对叶节点雅可比矩阵 J(leaf) 的条件,这些条件是良好条件数矩阵的代理,从而导致局部估计的方差更小。不同准则下良好条件数的代理不同,主要是出于计算效率的原因。

    • 如果 criterion='het',则 J(leaf) 的对角线元素被约束为绝对值至少为 min_var_leaf

      for all i in {1, ..., n_outputs}: abs(J(leaf)[i, i]) > `min_var_leaf`
      

      在因果树的上下文中,如果在拟合时传入了残差处理,则这转化为对每个处理坐标 i 的 Var(T[i]) 的要求。在 IV 树的上下文中,如果在拟合时传入了残差工具变量和残差处理,则这转化为对工具变量和处理的每个坐标 i 的 Cov(T[i], Z[i]) > min_var_leaf 的要求。

    • 如果 criterion='mse',由于该准则为每个候选分裂存储了关于叶节点雅可比矩阵的更多信息,因此我们对叶节点雅可比矩阵的成对行列式施加了进一步的约束,因为这只需很小的额外计算成本,即

      for all i neq j:
          sqrt(abs(J(leaf)[i, i] * J(leaf)[j, j] - J(leaf)[i, j] * J(leaf)[j, i])) > `min_var_leaf`
      

      在因果树的上下文中,如果在拟合时传入了残差处理,则这转化为对叶节点内任意两个处理坐标之间的皮尔逊相关系数的约束,即

      for all i neq j:
          sqrt( Var(T[i]) * Var(T[j]) * (1 - rho(T[i], T[j])^2) ) ) > `min_var_leaf`
      

      其中 rho(X, Y) 是两个随机变量 X, Y 的皮尔逊相关系数。因此,此约束也确保在叶节点内任意两对处理不会非常共线性。这个额外的约束主要在输入处理多于两个的情况下起作用。

  • min_var_leaf_on_val (bool,默认 False) – min_var_leaf 约束是否也应在诚实分裂的验证集上强制执行。如果 min_var_leaf=None,则此标志不起作用。设置此标志为 True 应谨慎,因为它部分违反了诚实结构,因为除了 X 变量之外的部分变量(例如进入线性模型雅可比矩阵 J 的变量)被用于构建树的分裂结构。然而,这是一个良性依赖,例如在因果树或 IV 树中,它不使用标签 y。它只使用处理 T 和工具变量 Z 及其局部相关结构来决定分裂是否可行。

  • max_features (int, float, {“auto”, “sqrt”, “log2”}, 或 None,默认 None) – 在寻找最佳分裂时考虑的特征数量

    • 如果为 int,则在每次分裂时考虑 max_features 个特征。

    • 如果为 float,则 max_features 是一个分数,每次分裂时考虑 int(max_features * n_features) 个特征。

    • 如果为 “auto”,则 max_features=n_features

    • 如果为 “sqrt”,则 max_features=sqrt(n_features)

    • 如果为 “log2”,则 max_features=log2(n_features)

    • 如果为 None,则 max_features=n_features

    注意:即使需要实际检查超过 max_features 个特征,对分裂的搜索也不会停止,直到找到节点样本的至少一个有效分区为止。

  • random_state (int, RandomState 实例, 或 None,默认 None) – 控制估计器的随机性。即使 splitter 设置为 "best",特征在每次分裂时总是随机排列的。当 max_features < n_features 时,算法将在每次分裂前随机选择 max_features 个特征,然后在其中找到最佳分裂。但即使 max_features=n_features,找到的最佳分裂也可能在不同的运行中变化。这是因为如果几个分裂的准则改进值相同,则必须随机选择一个分裂。为了在拟合过程中获得确定性行为,random_state 必须固定为一个整数。

  • min_impurity_decrease (float,默认 0.0) – 如果分裂导致的杂质减少大于或等于此值,则该节点将被分裂。加权杂质减少的方程如下

    N_t / N * (impurity - N_t_R / N_t * right_impurity
                        - N_t_L / N_t * left_impurity)
    

    其中 N 是样本总数,N_t 是当前节点的样本数,N_t_L 是左子节点的样本数,N_t_R 是右子节点的样本数。如果传入了 sample_weight,则 NN_tN_t_RN_t_L 都指加权总和。

  • min_balancedness_tol (float in [0, .5];默认 .45) – 我们能容忍的分裂失衡程度。这强制要求每个分裂的每一侧至少保留样本总重量(当 sample_weight 不为 None 时)的 (.5 - min_balancedness_tol) 分数。默认值确保父节点权重的至少 5% 落入分裂的每一侧。设置为 0.0 表示无平衡性约束,设置为 .5 表示完美平衡分裂。为了使形式化推断理论有效,此值必须是一个正的常数,且远离零。

  • honest (bool,默认 True) – 数据是否应分成两个大小相等的样本,其中一半样本用于确定每个节点的最优分裂,另一半样本用于确定每个节点的值。

feature_importances_

基于它们创建的参数异质性数量的特征重要性。值越高,特征越重要。特征的重要性计算为该特征创建的(标准化)总异质性。每次选择该特征进行分裂都会增加

parent_weight * (left_weight * right_weight)
    * mean((value_left[k] - value_right[k])**2) / parent_weight**2

到该特征的重要性。每个这样的数量也按分裂的深度加权。默认情况下,深度低于 max_depth=4 的分裂不用于此计算,并且深度为 depth 的每个分裂都按 1 / (1 + depth)**2.0 重新加权。有关允许更改这些默认值的方法,请参阅 feature_importances 方法。

类型

ndarray of shape (n_features,)

max_features_

推断出的 max_features 值。

类型

int

n_features_

执行 fit 时的特征数量。

类型

int

n_outputs_

执行 fit 时的输出数量。

类型

int

n_relevant_outputs_

执行 fit 时,我们关心的前 n_relevant_outputs_ 个输出。

类型

int

n_y_

执行 fit 时的原始标签维度。

类型

int

n_samples_

执行 fit 时的训练样本数量。

类型

int

honest_

执行 fit 时是否启用了诚实性

类型

int

tree_

底层 Tree 对象。有关 Tree 对象的属性,请参阅 help(econml.tree._tree.Tree)

类型

Tree 实例

参考文献

grftree1

Athey, Susan, Julie Tibshirani, and Stefan Wager. “Generalized random forests.” The Annals of Statistics 47.2 (2019): 1148-1178 https://arxiv.org/pdf/1610.01271.pdf

__init__(*, criterion='mse', splitter='best', max_depth=None, min_samples_split=10, min_samples_leaf=5, min_weight_fraction_leaf=0.0, min_var_leaf=None, min_var_leaf_on_val=False, max_features=None, random_state=None, min_impurity_decrease=0.0, min_balancedness_tol=0.45, honest=True)[source]

方法

__init__(*[, criterion, splitter, ...])

apply(X[, check_input])

返回每个样本被预测到的叶节点的索引。

decision_path(X[, check_input])

返回树中的决策路径。

feature_importances([max_depth, ...])

基于它们创建的参数异质性数量的特征重要性。值越高,特征越重要。特征的重要性计算为该特征创建的(标准化)总异质性。每次选择该特征进行分裂都会增加::。

fit(X, y, n_y, n_outputs, n_relevant_outputs)

根据数据拟合树

get_depth()

返回决策树的深度。

get_n_leaves()

返回决策树的叶节点数量。

get_params([deep])

获取此估计器的参数。

get_train_test_split_inds()

重新生成用于诚实树构建结构的训练和评估分裂的输入样本索引的 train_test_split。

init()

此方法应在 fit 之前调用。

predict(X[, check_input])

返回每个 X 的相关拟合局部参数前缀,即 theta(X)。

predict_alpha_and_jac(X[, check_input])

预测线性矩方程的局部雅可比 E[J | X=x] 和局部 alpha E[A | X=x]

predict_full(X[, check_input])

返回每个 X 的拟合局部参数,即 theta(X)。

predict_moment(X, parameter[, check_input])

预测每个样本在给定参数下的局部矩值。

set_params(**params)

设置此估计器的参数。

属性

feature_importances_

n_features_

apply(X, check_input=True)

返回每个样本被预测到的叶节点的索引。

参数
  • X ({array_like},形状 (n_samples, n_features)) – 输入样本。内部将转换为 dtype=np.float64

  • check_input (bool,默认 True) – 允许绕过一些输入检查。除非你知道自己在做什么,否则不要使用此参数。

返回

X_leaves – 对于 X 中的每个数据点 x,返回 x 最终所在的叶节点索引。叶节点编号在 [0; self.tree_.node_count) 范围内,可能存在编号间隔。

返回类型

array_like,形状 (n_samples,)

decision_path(X, check_input=True)

返回树中的决策路径。

参数
  • X ({array_like},形状 (n_samples, n_features)) – 输入样本。内部将转换为 dtype=np.float64

  • check_input (bool,默认 True) – 允许绕过一些输入检查。除非你知道自己在做什么,否则不要使用此参数。

返回

indicator – 返回一个节点指示符 CSR 矩阵,其中非零元素表示样本经过这些节点。

返回类型

稀疏矩阵,形状 (n_samples, n_nodes)

feature_importances(max_depth=4, depth_decay_exponent=2.0)[source]

基于它们创建的参数异质性数量的特征重要性。值越高,特征越重要。特征的重要性计算为该特征创建的(标准化)总异质性。每次选择该特征进行分裂都会增加

parent_weight * (left_weight * right_weight)
    * mean((value_left[k] - value_right[k])**2) / parent_weight**2

到特征的重要性。每个这样的数量也按分裂的深度加权。

参数
  • max_depth (int,默认 4) – 深度大于 max_depth 的分裂不用于此计算

  • depth_decay_exponent (double,默认 2.0) – 每个分裂对总得分的贡献按 1 / (1 + `depth`)**2.0 重新加权。

返回

feature_importances_ – 每个特征引起参数异质性的标准化总重要性

返回类型

ndarray of shape (n_features,)

fit(X, y, n_y, n_outputs, n_relevant_outputs, sample_weight=None, check_input=True)[source]

根据数据拟合树

参数
  • X ((n, d) 数组) – 用于分裂的特征

  • y ((n, m) 数组) – 计算准则函数、评估分裂和估计局部值所需的所有变量,即除了 X 之外进入矩函数的所有值。

  • n_y, n_outputs, n_relevant_outputs (传递给准则对象的辅助信息,这些对象) – 帮助对象将变量 y 解析为每个独立的变量分量。

    • isinstance(criterion, LinearMomentGRFCriterion) 的情况下,y 的前 n_y 列是原始输出,接下来的 n_outputs 列包含矩的 A 部分,再接下来的 n_outputs * n_outputs 列包含以行连续格式表示的矩的 J 部分。线性矩的前 n_relevant_outputs 个参数是我们关心的参数。其余的是无关参数。

  • sample_weight ((n,) 数组,默认 None) – 样本权重

  • check_input (bool,默认 True) – 是否检查输入参数的有效性。如果由生成此树的森林类已检查过变量,则应设置为 False 以提高并行执行时的运行时间。

get_depth()

返回决策树的深度。树的深度是根节点和任何叶节点之间的最大距离。

返回

self.tree_.max_depth – 树的最大深度。

返回类型

int

get_n_leaves()

返回决策树的叶节点数量。

返回

self.tree_.n_leaves – 叶节点数量。

返回类型

int

get_params(deep=True)

获取此估计器的参数。

参数

deep (bool,默认 True) – 如果为 True,则返回此估计器以及包含的作为估计器的子对象的参数。

返回

params – 参数名称映射到其值。

返回类型

dict

get_train_test_split_inds()

重新生成用于诚实树构建结构的训练和评估分裂的输入样本索引的 train_test_split。使用在 fit 时使用的相同随机种子,并重新生成索引。

init()[source]

此方法应在 fit 之前调用。我们添加了这个预处理步骤,以便可以在没有并行化的情况下执行此步骤,因为它包含持有 GIL 并可能阻碍并行执行的代码。我们也没有将此步骤合并到 __init__ 中,因为我们希望 __init__ 仅存储参数以方便克隆。我们也不想直接将 RandomState 对象作为 random_state 传递,因为我们希望保留起始种子,以便能够在对象外部复制对象的随机性。

predict(X, check_input=True)[source]

返回每个 X 的相关拟合局部参数前缀,即 theta(X)。

参数
  • X ({array_like},形状 (n_samples, n_features)) – 输入样本。内部将转换为 dtype=np.float64

  • check_input (bool,默认 True) – 允许绕过一些输入检查。除非你知道自己在做什么,否则不要使用此参数。

返回

theta(X)[ – 每个 X 行的估计相关参数

返回类型

n_relevant_outputs] : array_like,形状 (n_samples, n_relevant_outputs)

predict_alpha_and_jac(X, check_input=True)[source]

预测线性矩方程的局部雅可比 E[J | X=x] 和局部 alpha E[A | X=x]

参数
  • X ({array_like},形状 (n_samples, n_features)) – 输入样本。内部将转换为 dtype=np.float64

  • check_input (bool,默认 True) – 允许绕过一些输入检查。除非你知道自己在做什么,否则不要使用此参数。

返回

  • alpha (array_like,形状 (n_samples, n_outputs)) – 每个样本 x 的局部 alpha E[A | X=x]

  • jac (array_like,形状 (n_samples, n_outputs * n_outputs)) – 以 C 连续格式展平的局部雅可比 E[J | X=x]

predict_full(X, check_input=True)[source]

返回每个 X 的拟合局部参数,即 theta(X)。

参数
  • X ({array_like},形状 (n_samples, n_features)) – 输入样本。内部将转换为 dtype=np.float64

  • check_input (bool,默认 True) – 允许绕过一些输入检查。除非你知道自己在做什么,否则不要使用此参数。

返回

theta(X) – 每个 X 行的所有估计参数

返回类型

array_like,形状 (n_samples, n_outputs)

predict_moment(X, parameter, check_input=True)[source]

预测每个样本在给定参数下的局部矩值

E[J | X=x] theta(x) - E[A | X=x]
参数
  • X ({array_like},形状 (n_samples, n_features)) – 输入样本。内部将转换为 dtype=np.float64

  • parameter ({array_like},形状 (n_samples, n_outputs)) – 每个样本的参数估计

  • check_input (bool,默认 True) – 允许绕过一些输入检查。除非你知道自己在做什么,否则不要使用此参数。

返回

moment – 每个样本 x 的局部矩 E[J | X=x] theta(x) - E[A | X=x]

返回类型

array_like,形状 (n_samples, n_outputs)

set_params(**params)

设置此估计器的参数。

此方法适用于简单的估计器以及嵌套对象(例如 Pipeline)。后者具有 <component>__<parameter> 形式的参数,因此可以更新嵌套对象的每个组件。

参数

**params (dict) – 估计器参数。

返回

self – 估计器实例。

返回类型

估计器实例