xgboost.plot_tree:二进制特征解释

bla*_*ite 7 python machine-learning xgboost

我已经构建了一个XGBoost模型并试图检查各个估算器.作为参考,这是具有离散和连续输入特征的二元分类任务.输入要素矩阵是a scipy.sparse.csr_matrix.

然而,当我去检查个体估计器时,我发现难以解释二进制输入特征,f60150如下所示.f60150最底层图表中的实数值很容易解释 - 其标准在该特征的预期范围内.但是,对二进制特征进行的比较<X> < -9.53674e-07没有意义.这些特征中的每一个都是1或0. -9.53674e-07是一个非常小的负数,我想这只是XGBoost或其基础绘图库中的一些浮点特性,但在特征中使用该比较没有意义永远是积极的.有人可以帮助我了解哪些方向(即yes, missingno对应这些二进制功能节点,其真/假的一面?

这是一个可重复的例子:

import numpy as np
import scipy.sparse
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
from xgboost import plot_tree, XGBClassifier
import matplotlib.pyplot as plt

def booleanize_csr_matrix(mat):
    ''' Convert sparse matrix with positive integer elements to 1s '''
    nnz_inds = mat.nonzero()
    keep = np.where(mat.data > 0)[0]
    n_keep = len(keep)
    result = scipy.sparse.csr_matrix(
        (np.ones(n_keep), (nnz_inds[0][keep], nnz_inds[1][keep])),
        shape=mat.shape
    )
    return result

### Setup dataset
res = fetch_20newsgroups()

text = res.data
outcome = res.target

### Use default params from CountVectorizer to create initial count matrix
vec = CountVectorizer()
X = vec.fit_transform(text)

# Whether to "booleanize" the input matrix
booleanize = True

# Whether to, after "booleanizing", convert the data type to match what's returned by `vec.fit_transform(text)`
to_int = True

if booleanize and to_int:
    X = booleanize_csr_matrix(X)
    X = X.astype(np.int64)

# Make it a binary classification problem
y = np.where(outcome == 1, 1, 0)

# Random state ensures we will be able to compare trees and their features consistently
model = XGBClassifier(random_state=100)
model.fit(X, y)

plot_tree(model, rankdir='LR'); plt.show()
Run Code Online (Sandbox Code Playgroud)

运行上面的booleanizeto_int设置以True产生以下图表:

在此输入图像描述

运行上面的booleanizeto_int设置以False产生以下图表:

在此输入图像描述

哎呀,即使我做一个非常简单的例子,我得到"正确"的结果,无论是否X还是y被整数或浮点数类型.

X = np.matrix(
    [
        [1,0],
        [1,0],
        [0,1],
        [0,1],
        [1,1],
        [1,0],
        [0,0],
        [0,0],
        [1,1],
        [0,1]
    ]
)

y = np.array([1,0,0,0,1,1,1,0,1,1])

model = XGBClassifier(random_state=100)
model.fit(X, y)

plot_tree(model, rankdir='LR'); plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

小智 0

您在 XGBoost 树可视化中看到的比较值通常用于将数据拆分为决策树中的两个分支。对于二进制特征,例如由booleanize_csr_matrix函数创建的特征,比较确实用于确定样本应遵循哪个分支(True 或 False)。

在 XGBoost 二元分类模型的上下文中:

  • 如果二元特征(例如 )f60150具有诸如 之类的比较<X> < -9.53674e-07,则意味着树将根据特征值是否f60150小于 来分割样本-9.53674e-07

  • 如果该特征始终为正(即 1 或 0),则比较仍应以相同的方式解释。比较<X> < -9.53674e-07本质上相当于“等于f601500 还是 1?”

XGBoost 可以用浮点数进行分割的方式来表示二进制特征,但比较的目的仍然是根据特征值将样本分成不同的分支。在实践中,这个小负数被用作分裂的阈值,但它不影响二值特征的解释。

因此,对于二元特征,比较值用于确定特征是0还是1,这就是树在分类时做出决策的方式。对于二元特征,这些比较通常很简单,用于将样本分为两组:一组特征为 0,另一组特征为 1。