导出带有用于预测的最少信息的插入符号 R 模型

MLE*_*LEN 5 r r-caret

我想导出以下模型,以便其他用户可以打开它并使用predict函数来预测新观察的类。这是它唯一的用途。我可以保存 mod_fit,但它会占用大量空间,最终用户可以访问我不想要的信息。有什么简便的方法吗?

library(caret)
library(dplyr)

iris2 <- iris %>% filter(Species != "setosa") %>% mutate(Species = as.character(Species))
mod_fit <- train(Species ~., data = iris2, method = "glm")
Run Code Online (Sandbox Code Playgroud)

lio*_*ori 5

以下是从目标使用可能不需要的数据中修剪 R 对象的通用过程。它本质上是启发式的,但我已经成功地应用了它两次,运气好的话它运行得很好。

您可以使用名为 的函数测量对象大小object.size

> object.size(mod_fit)
528616 bytes
Run Code Online (Sandbox Code Playgroud)

确实,对于具有四个预测变量的线性模型来说,相当多。例如,您可以使用以下str函数检查对象内部的内容:

> str(mod_fit)
List of 23
 $ method      : chr "glm"
 $ modelInfo   :List of 15
  ..$ label     : chr "Generalized Linear Model"
  ..$ library   : NULL
  ..$ loop      : NULL
  ..$ type      : chr [1:2] "Regression" "Classification"
  ..$ parameters:'data.frame':  1 obs. of  3 variables:
  .. ..$ parameter: Factor w/ 1 level "parameter": 1
  .. ..$ class    : Factor w/ 1 level "character": 1
[…]
 $ coefnames   : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
 $ xlevels     : Named list()
 - attr(*, "class")= chr [1:2] "train" "train.formula"
Run Code Online (Sandbox Code Playgroud)

相当多的数据。因此,让我们检查每个元素占用多少空间:

> sort(sapply(mod_fit, object.size))
        pred   preProcess      yLimits         dots     maximize       method 
           0            0            0           40           48           96 
   modelType       metric    perfNames      xlevels    coefnames       levels 
         104          104          160          192          296          328 
        call     bestTune      results        times     resample  resampledCM 
         936         1104         1584         2024         2912         4152 
trainingData        terms      control    modelInfo   finalModel 
        5256         6112        29864       211824       259456 
Run Code Online (Sandbox Code Playgroud)

现在我们可以尝试从这个对象中一个一个地删除元素,并predict从最大的开始检查哪些元素是工作所必需的:

> test_obj <- mod_fit; test_obj$finalModel <- NULL; predict(test_obj, iris2)
Error in if (modelFit$problemType == "Classification") { : 
  argument is of length zero
Run Code Online (Sandbox Code Playgroud)

哎呀,finalModel似乎很重要。这里的任何类型的错误都会告诉您无法删除该元素。怎么样,比方说,control

> test_obj <- mod_fit; test_obj$control <- NULL; predict(test_obj, iris2)
  [1] versicolor versicolor versicolor versicolor versicolor versicolor
  [7] versicolor versicolor versicolor versicolor versicolor versicolor
 [13] versicolor versicolor versicolor versicolor versicolor versicolor
[…]
 [97] virginica  virginica  virginica  virginica 
Levels: versicolor virginica
Run Code Online (Sandbox Code Playgroud)

所以,似乎control不需要。您可以递归地执行此过程,例如:

> sort(sapply(mod_fit$finalModel, object.size))
           offset         contrasts             param              rank 
                0                 0                40                48 
[…]
            model            family 
            17056            163936 
> sort(sapply(mod_fit$finalModel$family, object.size))
      link     family   valideta    linkfun    linkinv     mu.eta dev.resids 
        96        104        272        560        560        560       1992 
  variance    validmu initialize        aic   simulate 
      2064       6344      18712      27512     103888 
> test_obj <- mod_fit; test_obj$finalModel$family$simulate <- NULL; predict(test_obj, iris2)
  [1] versicolor versicolor versicolor versicolor versicolor versicolor
[…]
 [97] virginica  virginica  virginica  virginica 
Levels: versicolor virginica
Run Code Online (Sandbox Code Playgroud)

通过足够的尝试,您将知道对象的哪些部分是必要的,哪些不是——并在存储模型之前删除它们。

注意:虽然这可能会减少对象的不必要部分,但您可能会意外删除仅有用于预测的部分。但是,对于始终以相同方式工作的简单模型,例如glm,这不应该发生。

此外,不保证此过程的结果不会泄露您不希望模型用户看到的模型信息。一般没有这样的保证,甚至有一些方法可以重建关于模型和训练数据的重要信息,即使是从通常不容易解释的黑盒模型中