我有一个表示测试集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
破坏了数据的结构。
答案 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 - min
中df1
的范围(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]]))})
它的作用。