xgboost 二元逻辑回归
xgboost binary logistic regression
我在使用 xgboost 进行逻辑回归 运行 时遇到问题,可以在以下示例中进行总结。
假设我有一个非常简单的数据框,其中包含两个预测变量和一个目标变量:
df= pd.DataFrame({'X1' : pd.Series([1,0,0,1]), 'X2' : pd.Series([0,1,1,0]), 'Y' : pd.Series([0,1,1,0], )})
我可以post图像因为我是新来的,但是我们可以清楚地看到当X1=1且X2=0时,Y为0,而当X1=0且X2=1时,Y为1。
我的想法是建立一个模型,输出一个观察值属于每个 类 的概率,所以如果我 运行 xgboost 试图预测两个新的观察值 (1,0 ) 和 (0,1) 像这样:
X = df[['X1','X2']].values
y = df['Y'].values
params = {'objective': 'binary:logistic',
'num_class': 2
}
clf1 = xgb.train(params=params, dtrain=xgb.DMatrix(X, y), num_boost_round=100)
clf1.predict(xgb.DMatrix(test.values))
输出是:
array([[ 0.5, 0.5],
[ 0.5, 0.5]], dtype=float32)
我想,这意味着对于第一次观察,它属于每个 类 的概率为 50%。
我想知道如果变量之间的关系很清楚,为什么算法不会输出适当的 (1,0) 或更接近它的值。
仅供参考,我确实尝试了更多数据(为简单起见,我只使用了 4 行)并且行为几乎相同;我注意到的是,不仅概率总和不为 1,而且它们通常非常小,如下所示:
(此结果在不同的数据集上,与上面的示例无关)
array([[ 0.00356463, 0.00277259],
[ 0.00315137, 0.00268578],
[ 0.00453343, 0.00157113],
好的 - 这是正在发生的事情..
关于它为什么不起作用的线索在于,在较小的数据集中它无法正确训练。我训练了这个精确的模型并观察了所有树木的倾倒,你会发现它们无法分裂。
(下面的树堆)
没有分裂,它们已经被修剪了!
[1] "booster[0]" "0:leaf=-0" "booster[1]" "0:leaf=-0" "booster[2]" "0:leaf=-0"
[7] "booster[3]" "0:leaf=-0" "booster[4]" "0:leaf=-0" "booster[5]" "0:leaf=-0"
[13] "booster[6]" "0:leaf=-0" "booster[7]" "0:leaf=-0" "booster[8]" "0:leaf=-0"
[19] "booster[9]" "0:leaf=-0"
每个叶子的权重都不足以压倒 xgboost
的内部正则化(惩罚它用于生长)
此参数可能会或可能不会从 python 版本访问,但如果您执行 github 安装
,则可以从 R
获取它
http://xgboost.readthedocs.org/en/latest/parameter.html
lambda [default=1] L2 regularization term on weights
alpha [default=0] L1 regularization term on weights
基本上这就是为什么您的示例在添加更多数据时训练得更好,但仅使用 4 个示例和默认设置根本无法训练的原因。
我在使用 xgboost 进行逻辑回归 运行 时遇到问题,可以在以下示例中进行总结。
假设我有一个非常简单的数据框,其中包含两个预测变量和一个目标变量:
df= pd.DataFrame({'X1' : pd.Series([1,0,0,1]), 'X2' : pd.Series([0,1,1,0]), 'Y' : pd.Series([0,1,1,0], )})
我可以post图像因为我是新来的,但是我们可以清楚地看到当X1=1且X2=0时,Y为0,而当X1=0且X2=1时,Y为1。
我的想法是建立一个模型,输出一个观察值属于每个 类 的概率,所以如果我 运行 xgboost 试图预测两个新的观察值 (1,0 ) 和 (0,1) 像这样:
X = df[['X1','X2']].values
y = df['Y'].values
params = {'objective': 'binary:logistic',
'num_class': 2
}
clf1 = xgb.train(params=params, dtrain=xgb.DMatrix(X, y), num_boost_round=100)
clf1.predict(xgb.DMatrix(test.values))
输出是:
array([[ 0.5, 0.5],
[ 0.5, 0.5]], dtype=float32)
我想,这意味着对于第一次观察,它属于每个 类 的概率为 50%。
我想知道如果变量之间的关系很清楚,为什么算法不会输出适当的 (1,0) 或更接近它的值。
仅供参考,我确实尝试了更多数据(为简单起见,我只使用了 4 行)并且行为几乎相同;我注意到的是,不仅概率总和不为 1,而且它们通常非常小,如下所示: (此结果在不同的数据集上,与上面的示例无关)
array([[ 0.00356463, 0.00277259],
[ 0.00315137, 0.00268578],
[ 0.00453343, 0.00157113],
好的 - 这是正在发生的事情..
关于它为什么不起作用的线索在于,在较小的数据集中它无法正确训练。我训练了这个精确的模型并观察了所有树木的倾倒,你会发现它们无法分裂。
(下面的树堆)
没有分裂,它们已经被修剪了!
[1] "booster[0]" "0:leaf=-0" "booster[1]" "0:leaf=-0" "booster[2]" "0:leaf=-0"
[7] "booster[3]" "0:leaf=-0" "booster[4]" "0:leaf=-0" "booster[5]" "0:leaf=-0"
[13] "booster[6]" "0:leaf=-0" "booster[7]" "0:leaf=-0" "booster[8]" "0:leaf=-0"
[19] "booster[9]" "0:leaf=-0"
每个叶子的权重都不足以压倒 xgboost
的内部正则化(惩罚它用于生长)
此参数可能会或可能不会从 python 版本访问,但如果您执行 github 安装
,则可以从R
获取它
http://xgboost.readthedocs.org/en/latest/parameter.html
lambda [default=1] L2 regularization term on weights
alpha [default=0] L1 regularization term on weights
基本上这就是为什么您的示例在添加更多数据时训练得更好,但仅使用 4 个示例和默认设置根本无法训练的原因。