6. XGBoost
参考:《统计学习方法》提升方法(Boosting)
extreme gradient boosting “梯度提升”是指对损失函数使用梯度下降来确定此新模型中的参数
from xgboost import XGBRegressor
my_model = XGBRegressor(n_estimators=500)
my_model.fit(X_train, y_train)
from sklearn.metrics import mean_absolute_error
predictions = my_model.predict(X_valid)
print("Mean Absolute Error: " + str(mean_absolute_error(predictions, y_valid)))
复制
参数调整:
XGBoost 具有一些可以极大地影响准确性和训练速度的参数
-
:等于我们包含在集合中的模型数量n_estimators
值太低会导致拟合不足,导致训练数据和测试数据的预测不正确。
值太高会导致拟合过度,导致对训练数据的准确预测,但对测试数据的预测不准确
典型值范围是100-1000,尽管这在很大程度上取决于下面讨论的
learning_rate
参数
-
:提供了一种自动为early_stopping_rounds
查找理想值的方法。为n_estimators
设置一个较高的值,然后使用early_stopping_rounds查找停止迭代的最佳时间是很明智的n_estimators
设置
early_stopping_rounds = 5
是一个合理的选择。在这种情况下,连续5轮验证评分下降后停止
当使用
early_stopping_rounds
时,还需要预留一些数据来计算验证分数,这是通过设置
eval_set
参数来完成的
my_model = XGBRegressor(n_estimators=500)
my_model.fit(X_train, y_train,
early_stopping_rounds=5,
eval_set=[(X_valid, y_valid)],
verbose=False)
复制
-
与其简单地将每个组件模型的预测相加即可得到预测,还可以在将每个模型的预测相加之前将其乘以一小数(称为学习率)learning_rate
这意味着添加到集合中的每棵树对我们的帮助都会有所减少
因此,可以为
n_estimators
设置更高的值而不会过度拟合
如果我们使用 early stopping,则会自动确定适当的 tree 的数量
通常,学习率较高 且 estimators 多,会生成更精确的模型,但迭代次数较多,花费较长时间,默认情况下,XGBoost 设置 learning_rate = 0.1
my_model = XGBRegressor(n_estimators=1000, learning_rate=0.05)
my_model.fit(X_train, y_train,
early_stopping_rounds=5,
eval_set=[(X_valid, y_valid)],
verbose=False)
复制
-
:运行较大数据集,并行更快地构建模型n_jobs
通常将参数
n_jobs
设置为等于计算机上的内核数
在较小的数据集上,这无济于事
但是,在大型数据集中很有用,否则将花费很长时间在
fit
命令中等待
my_model = XGBRegressor(n_estimators=1000, learning_rate=0.05, n_jobs=4)
my_model.fit(X_train, y_train,
early_stopping_rounds=5,
eval_set=[(X_valid, y_valid)],
verbose=False)
复制
7. Data Leakage 数据泄露
Data Leakage 相关博文
泄漏会导致模型
看起来很准确
,当开始对模型进行决策为止,然后模型变得
非常不准确
泄漏有两种主要类型:
目标泄漏 target leakage
和
训练-测试污染train-test contamination
- 目标泄漏 target leakage
例子:人们得了肺炎后要服用抗生素药物才能康复
原始数据显示这些列之间存在很强的关系,但是在确定
got_pneumonia
的值后,
took_antibiotic_medicine
经常更改。这是目标泄漏,因为我们要预测的是 是否会患肺炎,是否吃药是在得了肺炎之后的选择,会不确定,
因果关系反了
该模型将发现,对于
took_antibiotic_medicine
值为
False
的任何人都没有肺炎。由于验证数据与训练数据来自同一来源,模型将具有很高的验证(或交叉验证)分数
但是,此模型随后在现实世界中部署时将非常不准确,因为有些患有肺炎的患者也不会接受抗生素治疗
为防止此类数据泄漏,应当将该特征数据排除
- 训练-测试污染 Train-Test Contamination
验证旨在衡量模型如何处理之前
未考虑过的数据
例如,在调用
train_test_split()
之前进行了预处理(例如 fitting an Imputer)。模型可能会获得良好的验证评分,但是在部署模型进行决策时却表现不佳
将验证数据或测试数据中的数据合并到了如何进行预测中,因此即使无法将其推广到新数据,该方法也可能会对特定数据表现良好。当执行更复杂的特征工程时,此问题变得更加微妙(更加危险)
例子:信用卡
没有信用卡的人 —> 100%没有消费支出
有信用卡的人 —> 2%的人,没有消费记录
根据此特征来预测是否会发放信用卡申请,正确率98%
但是有部分持有信用卡的人可能平时没有消费,并且统计出来的费用是这张申请的信用卡的消费,还是申请这张信用卡之前的消费呢?这些都不是很清楚,这就可能造成很大偏差
所以这种可能造成很大偏差的特征要弃用,或者非常谨慎
# Drop leaky predictors from dataset
potential_leaks = ['expenditure', 'share', 'active', 'majorcards']
X2 = X.drop(potential_leaks, axis=1)
# Evaluate the model with leaky predictors removed
cv_scores = cross_val_score(my_pipeline, X2, y,
cv=5,
scoring='accuracy')
print("Cross-val accuracy: %f" % cv_scores.mean())
复制
总结:
- 仔细分离训练和验证数据可以防止
,并且Train-Test Contamination
可以帮助实现这种分离Pipeline
- 谨慎,常识和数据探索相结合可以帮助识别
target leakage
-
思考数据泄露问题,本质上需要考虑特征产生的时间顺序:
如果该特征在你做出类型判断之前可以确定,那么就可以作为类型判断的依据;
如果该特征必须在你做出类型判断之后才可以确定,那么就不可以作为类型判断的依据,否则就是因果倒置