ai.onnx.ml - TreeEnsemble

TreeEnsemble - 5 (ai.onnx.ml)

版本

  • 名称: TreeEnsemble (GitHub)

  • : ai.onnx.ml

  • since_version: 5

  • 函数: False

  • 支持级别: SupportType.COMMON

  • 形状推断: True

此版本的操作符自 ai.onnx.ml 的版本 5 起可用。

摘要

树集成操作符。返回批次中每个输入的回归值。输入维度为 [N, F],其中 N 是输入批次大小,F 是输入特征数量。输出维度为 [N, num_targets],其中 N 是批次大小,num_targets 是目标数量,这是一个可配置的属性。

此属性的编码在树的内部节点和叶子节点之间进行分割。值得注意的是,带有 nodes_* 前缀的属性与内部节点相关联,带有 leaf_* 前缀的属性与叶子节点相关联。nodes_* 属性必须具有相同的长度,并编码一系列元组,其定义方式是获取给定位置的所有 nodes_* 字段。

所有以 leaf_* 为前缀的字段表示树叶,并类似地定义叶子元组,并且必须具有相同的长度。

此操作符可用于实现以前的 TreeEnsembleRegressorTreeEnsembleClassifier 节点。TreeEnsembleRegressor 节点直接映射到此节点,并需要更改节点的表示方式。TreeEnsembleClassifier 节点可以通过在此节点之后添加一个 ArgMax 节点来确定最高类别。为了编码类别标签,可以使用 LabelEncoderGatherND 操作符。

属性

  • aggregate_function - INT (默认值是 '1')

    定义如何在一个目标内聚合叶子值。
    ‘AVERAGE’ (0) ‘SUM’ (1) ‘MIN’ (2) ‘MAX (3) 之一,默认为 ‘SUM’ (1)

  • leaf_targetids - INTS (必需)

    此叶子所贡献的目标的索引(必须在 [0, n_targets) 范围内)。

  • leaf_weights - TENSOR (必需)

    每个叶子的权重。

  • membership_values - TENSOR :

    用于每个集合成员节点测试成员资格的成员。按照 node_modes 中出现 ‘BRANCH_MEMBER’ 模式的顺序,列出所有要再次测试的成员,以 NaN 分隔。将具有与模式为 ‘BRANCH_MEMBER’ 的节点相同数量的值集。如果节点不包含任何 ‘BRANCH_MEMBER’ 节点,则可以省略此项。

  • n_targets - INT :

    目标总数。

  • nodes_falseleafs - INTS (必需)

    如果 false 分支是每个节点的叶子,则为 1;如果是内部节点,则为 0。要表示一个叶子树(只有一个节点),可以通过有一个单独的 nodes_* 条目,其 true 和 false 分支引用相同的 leaf_* 条目来实现

  • nodes_falsenodeids - INTS (必需)

    如果 nodes_falseleafs 在某个条目处为 false,则这表示 false 分支节点的位置。此位置可用于索引 nodes_* 条目。如果 nodes_falseleafs 为 false,则它是 leaf_* 属性的索引。

  • nodes_featureids - INTS (必需)

    每个节点的特征 ID。

  • nodes_hitrates - TENSOR :

    每个节点的流行度,用于性能分析,可以省略。

  • nodes_missing_value_tracks_true - INTS :

    对于每个节点,定义在存在 NaN 输入特征时是遵循 true 分支(如果属性值为 1)还是 false 分支(如果属性值为 0)。此属性可以未定义,所有节点的默认值为 false (0)。

  • nodes_modes - TENSOR (必需)

    节点执行的比较操作。这被编码为枚举,其中 0 (‘BRANCH_LEQ’)、1 (‘BRANCH_LT’)、2 (‘BRANCH_GTE’)、3 (‘BRANCH_GT’)、4 (‘BRANCH_EQ’)、5 (‘BRANCH_NEQ’) 和 6 (‘BRANCH_MEMBER’)。请注意,这是一个 uint8 类型的张量。

  • nodes_splits - TENSOR (必需)

    对于模式不是 ‘BRANCH_MEMBER’ 的每个节点,用于分割的阈值。

  • nodes_trueleafs - INTS (必需)

    如果 true 分支是每个节点的叶子,则为 1;如果是内部节点,则为 0。要表示一个叶子树(只有一个节点),可以通过有一个单独的 nodes_* 条目,其 true 和 false 分支引用相同的 leaf_* 条目来实现

  • nodes_truenodeids - INTS (必需)

    如果 nodes_trueleafs 在某个条目处为 false,则这表示 true 分支节点的位置。此位置可用于索引 nodes_* 条目。如果 nodes_trueleafs 为 false,则它是 leaf_* 属性的索引。

  • post_transform - INT (默认值是 '0')

    指示应用于分数的变换。
    ‘NONE’ (0)、‘SOFTMAX’ (1)、‘LOGISTIC’ (2)、‘SOFTMAX_ZERO’ (3) 或 ‘PROBIT’ (4) 之一,默认为 ‘NONE’ (0)

  • tree_roots - INTS (必需)

    每个树根的 nodes_* 索引。树结构派生自每个节点的分支。

输入

  • X (异构) - T

    输入形状 [批次大小,特征数量]

输出

  • Y (异构) - T

    输出形状 [批次大小,目标数量]

类型约束

  • T 在 ( tensor(double), tensor(float), tensor(float16) )

    输入类型必须是数值类型的张量。

示例

_tree_ensemble_single_tree

import numpy as np
import onnx

node = onnx.helper.make_node(
    "TreeEnsemble",
    ["X"],
    ["Y"],
    domain="ai.onnx.ml",
    n_targets=2,
    membership_values=None,
    nodes_missing_value_tracks_true=None,
    nodes_hitrates=None,
    aggregate_function=1,
    post_transform=0,
    tree_roots=[0],
    nodes_modes=make_tensor(
        "nodes_modes",
        onnx.TensorProto.UINT8,
        (3,),
        np.array([0, 0, 0], dtype=np.uint8),
    ),
    nodes_featureids=[0, 0, 0],
    nodes_splits=make_tensor(
        "nodes_splits",
        onnx.TensorProto.DOUBLE,
        (3,),
        np.array([3.14, 1.2, 4.2], dtype=np.float64),
    ),
    nodes_truenodeids=[1, 0, 1],
    nodes_trueleafs=[0, 1, 1],
    nodes_falsenodeids=[2, 2, 3],
    nodes_falseleafs=[0, 1, 1],
    leaf_targetids=[0, 1, 0, 1],
    leaf_weights=make_tensor(
        "leaf_weights",
        onnx.TensorProto.DOUBLE,
        (4,),
        np.array([5.23, 12.12, -12.23, 7.21], dtype=np.float64),
    ),
)

x = np.array([1.2, 3.4, -0.12, 1.66, 4.14, 1.77], np.float64).reshape(3, 2)
y = np.array([[5.23, 0], [5.23, 0], [0, 12.12]], dtype=np.float64)
expect(
    node,
    inputs=[x],
    outputs=[y],
    name="test_ai_onnx_ml_tree_ensemble_single_tree",
)

_tree_ensemble_set_membership

import numpy as np
import onnx

node = onnx.helper.make_node(
    "TreeEnsemble",
    ["X"],
    ["Y"],
    domain="ai.onnx.ml",
    n_targets=4,
    aggregate_function=1,
    membership_values=make_tensor(
        "membership_values",
        onnx.TensorProto.FLOAT,
        (8,),
        [1.2, 3.7, 8, 9, np.nan, 12, 7, np.nan],
    ),
    nodes_missing_value_tracks_true=None,
    nodes_hitrates=None,
    post_transform=0,
    tree_roots=[0],
    nodes_modes=make_tensor(
        "nodes_modes",
        onnx.TensorProto.UINT8,
        (3,),
        np.array([0, 6, 6], dtype=np.uint8),
    ),
    nodes_featureids=[0, 0, 0],
    nodes_splits=make_tensor(
        "nodes_splits",
        onnx.TensorProto.FLOAT,
        (3,),
        np.array([11, 232344.0, np.nan], dtype=np.float32),
    ),
    nodes_trueleafs=[0, 1, 1],
    nodes_truenodeids=[1, 0, 1],
    nodes_falseleafs=[1, 0, 1],
    nodes_falsenodeids=[2, 2, 3],
    leaf_targetids=[0, 1, 2, 3],
    leaf_weights=make_tensor(
        "leaf_weights", onnx.TensorProto.FLOAT, (4,), [1, 10, 1000, 100]
    ),
)

x = np.array([1.2, 3.4, -0.12, np.nan, 12, 7], np.float32).reshape(-1, 1)
expected = np.array(
    [
        [1, 0, 0, 0],
        [0, 0, 0, 100],
        [0, 0, 0, 100],
        [0, 0, 1000, 0],
        [0, 0, 1000, 0],
        [0, 10, 0, 0],
    ],
    dtype=np.float32,
)
expect(
    node,
    inputs=[x],
    outputs=[expected],
    name="test_ai_onnx_ml_tree_ensemble_set_membership",
)