列名称 - xgboost预测新数据

时间:2017-01-16 01:04:50

标签: r sparse-matrix xgboost

我从未制作过xgboost模型,而是关注如何处理xgboost模型中的新数据预测。特别是当列名称与训练模型稀疏矩阵列名称不匹配时 - 由于添加了新列或者在将新数据转换为稀疏矩阵时删除了某些列。

如果我尝试使用额外或一些缺少的列名来预测新数据的xgboost模型,该怎么办?我看到这肯定发生,并希望创建代码来解释它,以便预测是正确的。如果已经存在更优雅的解决方案,我宁愿避免将解决方案混在一起。

因此,如果新数据稀疏矩阵具有不同的列名,那么具体是什么?

我最好的猜测是分解(基于训练数据水平的水平)>创建稀疏矩阵>然后删除不匹配的列(在训练的数据集和新数据之间)。

我创建了虚拟数据(在下面的代码中)作为给定不同列名的预测错误的示例。

第一步=构建模型(仅用于说明目的,我知道它是一个糟糕的构建)

第二步=重新采样整个数据集然后预测(=没有问题。预测匹配)

第3步=仅从10%的数据中选择然后进行预测 - 由于列名不同,这会导致预测错误。

以下是代码:

步骤1创建虚拟数据并创建一个懒惰的xgboost模型,仅用于说明目的。

library(xgboost) # for xgboost algo
library(Matrix) # for sparse matrix

### Create dummy data
num_rows <- 100

set.seed(1234)

target <- runif(num_rows)

dummy_data <- data.frame(
LETTER_SINGLE=sample(LETTERS,num_rows,replace=TRUE),
DOUBLE_LETTER=paste(sample(LETTERS,num_rows,replace=TRUE),sample(LETTERS,num_rows,replace=TRUE),sep=""),
TRIPLE_LETTER=paste(sample(LETTERS,num_rows,replace=TRUE),sample(LETTERS,num_rows,replace=TRUE),sample(LETTERS,num_rows,replace=TRUE),sep=""),
stringsAsFactors=FALSE
)


## STEP 1 CREATE XGBOOST MODEL AND GET PREDICTED VALUES TO COMPARE WITH FUTURE DATA CUTS.
model_data_01 <- dummy_data
target_01 <- target
# create matrix
model_01_sparse <- sparse.model.matrix(~ .-1, data = model_data_01) 

# colnames model 1
colnames_trained_model <- colnames(model_01_sparse)

# train a model
xgb_fit_01 <- 
xgboost(data = model_01_sparse,
label = target_01,
#param = best_param,
nrounds=100,
verbose = T
)

pred_01 <- predict(xgb_fit_01,newdata=model_01_sparse)

步骤2.测试以查看观察顺序是否会导致预测差异。扰流板 - 没有预测错误发生。

## STEP 2 CREATE SHUFFLED DATA (SAME DATA SAMPLES BUT SHUFFLED) THEN PREDICT AND COMPARE.
sample_order <- sample(1:num_rows)

model_data_shuffled <- dummy_data[sample_order,]
target_shuffled <- target[sample_order]

# They are different
head(model_data_01)
head(model_data_shuffled)

# create matrix
model_shuffled_sparse <- sparse.model.matrix(~ .-1, data = model_data_shuffled) 

# colnames model 1
colnames_shuffled <- colnames(model_shuffled_sparse)

pred_shuffled <- predict(xgb_fit_01,newdata=model_shuffled_sparse)

# check if predictions differ
pred_01[sample_order] - pred_shuffled
## This matched. Yay. sparse.model.matrix function must first sort alphabetically then create column names.
# due to same column names
mean(colnames_trained_model == colnames_shuffled)

步骤3.仅对选定的几行进行采样并预测,以查看丢失的列(在稀疏矩阵中)是否会导致预测错误。

## STEP 2 WORKED FINE SO ONTO...
## STEP 3 RANDOMLY SAMPLE ONLY A HANDFUL OF ROWS PREDICT AND COMPARE.
sample_order_02 <- sample(1:(num_rows*0.1))

model_data_shuffled_02 <- dummy_data[sample_order_02,]
target_shuffled_02 <- target[sample_order_02]
# create matrix
model_shuffled_sparse_02 <- sparse.model.matrix(~ .-1, data = model_data_shuffled_02)   

# colnames model 1
colnames_shuffled_02 <- colnames(model_shuffled_sparse_02)

pred_shuffled_02 <- predict(xgb_fit_01,newdata=model_shuffled_sparse_02)

# check if predictions differ
pred_01[sample_order_02] - pred_shuffled_02
## This did not matched. Damn.

# Due to different column names
colnames_trained_model
colnames_shuffled_02

mean(colnames_trained_model == colnames_shuffled_02)

正如您所看到的,由于备用矩阵中缺少列名,最后一次尝试会导致预测值出现差异。 如果有一个优雅的解决方案供我学习,我不想一起破解丑陋的解决方案。 所以我的问题是......是否有一种优雅的方法可以强制稀疏模型矩阵列名称与构建模型(用于预测新数据的模型)相匹配?

我在网上搜索过,到目前为止找不到任何最佳实践解决方案。

如果有人可以通过回答问题或指导我朝着正确的方向提供帮助而非常感激。

1 个答案:

答案 0 :(得分:0)

您的生产环境是什么? R,Python,Java还是别的什么?

我们的想法是通过特定于生产环境的包装库来使用XGBoost功能(包括训练和预测),而不是直接使用。例如,在Python中,您可以使用Scikit-Learn wrappers,它将功能工程和选择任务封装到可重用的sklearn.pipeline.Pipeline对象中。您将在开发环境中1)fit管道对象(XGBoost估算器是最终任务的地方)并将其序列化为pickle文件,2)将pickle文件从开发环境移动到生产环境,以及3)de-从pickle文件序列化它并在生产环境中用于transforming新数据。这是一个高级API,它完全抽象出低级细节,例如XGBoost“内部”数据矩阵的布局。

对于独立于平台的解决方案,您可以在标准化的PMML representation中导出XGBoost模型(以及相关的数据预处理逻辑)。