我构建了一个 XGBoost 模型并试图检查各个估计量。作为参考,这是一个具有离散和连续输入特征的二元分类任务。输入特征矩阵是
scipy.sparse.csr_matrix
.
然而,当我去检查单个估计器时,我发现很难解释二进制输入特征,例如下面的
f60150
。最底部图表中的实值 f60150
很容易解释 - 它的标准位于该特征的预期范围内。然而,对二进制特征进行的比较,<X> < -9.53674e-07
没有意义。这些特征中的每一个都是 1 或 0。 -9.53674e-07
是一个非常小的负数,我想这只是 XGBoost 或其基础绘图库中的一些浮点特性,但使用这种比较没有意义当特征始终为正时。有人可以帮助我理解哪个方向(即 yes, missing
与 no
对应于这些二进制特征节点的真/假侧吗?
这是一个可重现的示例:
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()
在
booleanize
和 to_int
设置为 True
的情况下运行上述命令会产生以下图表:
在
booleanize
和 to_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()
您在 XGBoost 树可视化中看到的比较值通常用于将数据拆分为决策树中的两个分支。对于二进制特征,例如由
booleanize_csr_matrix
函数创建的特征,比较确实用于确定样本应遵循哪个分支(True 或 False)。
在 XGBoost 二元分类模型的背景下:
如果像
f60150
这样的二元特征有<X> < -9.53674e-07
这样的比较,这意味着树会根据特征f60150
的值是否小于-9.53674e-07
来分割样本。
如果特征始终为正(即 1 或 0),则比较仍应以相同的方式解释。比较
<X> < -9.53674e-07
本质上相当于“f60150
等于 0 还是 1?”
XGBoost 可能会用浮点数进行分割的方式来表示二值特征,但比较的目的仍然是根据特征值将样本分成不同的分支。在实践中,这个小负数被用作分裂的阈值,但它不影响二值特征的解释。
因此,对于二元特征,比较值用于确定特征是0还是1,这就是树在分类时做出决策的方式。对于二元特征,这些比较通常很简单,用于将样本分为两组:一组特征为 0,另一组特征为 1。