R:在给定其他数据框(训练集)的值的情况下,如何规范化一个数据框(测试集)

时间:2018-08-04 11:57:53

标签: r dataframe normalize

我有一个表示测试集T的数据框,另一个表示训练集D的数据框。这两个数据集中的列与从同一数据框中提取的列完全相同。

我使用以下代码对训练集D进行归一化

<input type="button" className="pull-right btn btn-info" style={{width: "33%"}} onClick={this.handleButtonChange.bind(this, marble._id)}
                                                       value="Assign"/> 

数据中的某些列是因子,其他数字是正则化函数的原因。

我想将此标准化步骤应用于测试集T,其中 handleButtonChange(marbleId, e) { var array = [...this.state.selectedMarbles]; // make a separate copy of the array var index = array.indexOf(marbleId); // append that element if(index<0) { array.push(marbleId); e.target.value="Unassign"; e.target.classList.remove("btn-info"); e.target.classList.add("btn-danger"); } else { // remove that element array.splice(index, 1); e.target.value="Assign"; e.target.classList.add("btn-info"); e.target.classList.remove("btn-danger"); } this.setState({selectedMarbles: array}); e.preventDefault() e.stopPropagation(); } <button type="button" className="pull-right btn btn-info" style={{width: "33%"}} onClick={this.handleButtonChange.bind(this, marble._id)} >Select</button> 值取自训练集中而不是测试集中的各个列。我应该怎么做?

谢谢您的指导!


编辑:按照@coffeinjunky的指示,尝试使用以下代码来测试使用混合类型的列(数字和因子)的能力:

  handleButtonChange(marbleId, e) {
    var array = [...this.state.selectedMarbles]; // make a separate copy of the array
    var index = array.indexOf(marbleId);
      // append that element
    if(index<0) {
      array.push(marbleId);
      e.target.innerHTML="Selected";
      e.target.classList.remove("btn-info");
      e.target.classList.add("btn-danger");
    } else {
      // remove that element
      array.splice(index, 1);
      e.target.innerHTML="Select";
      e.target.classList.add("btn-info");
      e.target.classList.remove("btn-danger");
    }
    this.setState({selectedMarbles: array});
    e.preventDefault();
    e.stopPropagation();
  }

但是结果很奇怪:函数也以某种方式存储在数据框中,并且列的名称丢失了。

MaxMinNormalize <- function(num) {
  if (is.factor(num)) num
  else ((num - min(num)) / (max(num) - min(num)))
}

D_n <- as.data.frame(lapply(D, MaxMinNormalize))

我怀疑用于处理因子列的min破坏了数据的结构。

1 个答案:

答案 0 :(得分:0)

最方便的方法可能是使用预先存在的功能。例如,在这里,我们可以使用caret包中提供的功能。

为了说明,让我们获取一些玩具数据:

# get some test data:
df <- mtcars[,c("mpg", "cyl")]
df1 <- df[1:16,]  # training data
df2 <- df[17:32,] # test data to be scaled

让我们看看我们会期望什么。

summary(df1) # some output ommitted
      mpg            cyl     
 Min.   :10.4   Min.   :4.0  
 Max.   :24.4   Max.   :8.0  

summary(df2)
      mpg             cyl       
 Min.   :13.30   Min.   :4.000  
 Max.   :33.90   Max.   :8.000  

我们看到max - mindf1的范围(mpg)是14,而cyl的范围是4。如果我们看一下{ {1}},df2为33.9。从mpg中减去最小值,即10.4,再除以14,应该得到23.5 / 14 = 1.6785。其他列和值也具有类似的数学公式。

现在,让我们使用df1,看看是否获得相同的值。

caret::preProcess

我们首先检查library(caret) train_stats <- preProcess(df1, method = "range") new_df1 <- predict(train_stats, df1) new_df2 <- predict(train_stats, df2) 是否按比例缩放到0-1范围。

new_df1

现在让我们看看是否可以在测试集上获得期望值:

summary(new_df1)
# some output omitted:
      mpg              cyl       
 Min.   :0.0000   Min.   :0.000  
 Max.   :1.0000   Max.   :1.000  

是的,看起来像这样。

现在,仅为了展示如何实现此summary(new_df2) # some output omitted: mpg cyl Min. :0.2071 Min. :0.0000 Max. :1.6786 Max. :1.0000 ,请考虑我们需要遍历每一列,执行一个操作,然后返回新列。这通常可以使用by hand系列的功能来实现。由于两个不同的数据框涉及相同的列名,因此遍历列名似乎是一个主意。例如,

apply

将应用sapply(names(df1), function(x) (...) ) ,并将df1中的每个列名称作为参数。让我们以以下方式使用它:

function

让我们看看是否能达到预期的结果:

df2[] <- sapply(names(df1), function(col) {
    if(is.factor(df2[[col]])) df2[[col]] else (df2[[col]]-min(df1[[col]]))/(max(df1[[col]])-min(df1[[col]]))})

它的作用。