R中的随机森林(y中的空类和参数长度0)

时间:2012-11-21 14:06:46

标签: r random-forest

我第一次与随机森林交易,我遇到了一些我无法弄清楚的麻烦...... 当我对我的所有数据集(大约3000行)运行分析时,我没有收到任何错误消息。但是当我对我的数据集的一个子集(大约300行)执行相同的分析时,我得到一个错误:

dataset <- read.csv("datasetNA.csv", sep=";", header=T)
names (dataset)
dataset2 <- dataset[complete.cases(dataset$response),]
library(randomForest)
dataset2 <- na.roughfix(dataset2)
data.rforest <- randomForest(dataset2$response ~ dataset2$predictorA + dataset2$predictorB+ dataset2$predictorC + dataset2$predictorD + dataset2$predictorE + dataset2$predictorF + dataset2$predictorG + dataset2$predictorH + dataset2$predictorI, data=dataset2, ntree=100, keep.forest=FALSE, importance=TRUE)

# subset of my original dataset:
groupA<-dataset2[dataset2$order=="groupA",]
data.rforest <- randomForest(groupA$response ~ groupA$predictorA + groupA$predictorB+ groupA$predictorC + groupA$predictorD + groupA$predictorE + groupA$predictorF + groupA$predictorG + groupA$predictorH + groupA$predictorI, data=groupA, ntree=100, keep.forest=FALSE, importance=TRUE)

Error in randomForest.default(m, y, ...) : Can't have empty classes in y.

但是,我的响应变量没有任何空类。

如果我写了像(a+b+c,y)而不是(y ~ a+b+c)的randomForest,我会收到另一条消息:

Error in if (n == 0) stop("data (x) has 0 rows") : 
  argument length zero
Warning messages:
1: In Ops.factor(groupA$responseA + groupA$responseB,  :
  + not meaningful for factors

第二个问题是,当我尝试通过rfImpute()对我的数据进行估算时,我收到了错误消息:

Errore in na.roughfix.default(x) :  roughfix can only deal with numeric data

然而,我的列是所有因素和数字。

有人能看出我错了吗?

8 个答案:

答案 0 :(得分:19)

根据评论中的讨论,这是对潜在解决方案的猜测。

这里的混淆源于因子的水平是变量的属性。无论您采用哪种数据子集,无论该子集有多小,这些级别都将保持不变。这是一个功能,而不是一个错误,也是一个常见的混淆源。

如果您想在子集化时删除缺失级别,请将子集操作包装在droplevels()中:

groupA <- droplevels(dataset2[dataset2$order=="groupA",])

我可能还应该添加许多R用户在开始新会话时设置options(stringsAsFactors = FALSE)(例如在他们的.Rprofile文件中)以避免这些麻烦。这样做的缺点是,如果您经常与其他人共享代码,如果他们没有更改R的默认选项,这可能会导致问题。

答案 1 :(得分:5)

通过子集删除因子级别时, 你必须重置级别:

levels(train11$str);
[1] "B" "D" "E" "G" "H" "I" "O" "T" "X" "Y" "b";
train11$str <- factor(train11$str);
levels(train11$str);
[1] "B" "D" "E" "G" "H" "I" "O" "T" "b"

答案 2 :(得分:3)

在将函数公式传递给randomForest之前尝试使用函数公式:

formula("y ~ a+b+c")

这解决了我的问题。

或者也许randomForest会错误地为另一个参数设置参数。

尝试指定每个参数:

randomForest(,,, data=my_data, mtry=my_mtry, etc)

答案 3 :(得分:3)

这是因为您在将数据发送到随机森林之前对子训练集进行了子设置,而子设置可能会在子设置后从您的响应变量中丢失一些级别,因此需要重新分配这些因子用这个:

dataset2 $ response&lt; - factor(dataset2 $ response)

在子设置后删除数据中不存在的其他级别。

答案 4 :(得分:0)

这似乎是call语句中的问题。 如果您使用公式界面,请调用

randomForest(response ~ predictorA + predictorB + ... + predictorI, data=groupA, ntree=100, keep.forest=FALSE, importance=TRUE)

但明确传递xy

会更方便,更快捷
randomForest(y = groupA$response, x = groupA[,c("predictorA", "predictorB", ...)], ntree=100, keep.forest=FALSE, importance=TRUE)

您可以使用索引代替变量名称。试试这些建议。

答案 5 :(得分:0)

添加到混音中的另一个建议是:您可能不希望read.csv()将字符串解释为因子。尝试将此添加到read.csv以强制转换为字符:

coid = "coid" & num
Try
        Connection.Open()
        Dim Query As String
        Query = "insert into database.coidset (CourseID) values ('" & CourseIDTxtbox.Text & "')"
        Command = New MySqlCommand(Query, Connection)
        DataReader = Command.ExecuteReader

        Connection.Close()
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

    Try
        Connection.Open()
        Dim Query As String
        Query = "alter table database.coidset add " & coid.ToString & " varchar(45) "
        Command = New MySqlCommand(Query, Connection)
        DataReader = Command.ExecuteReader
        Connection.Close()
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try


    Try
        Connection.Open()
        Dim Query As String
        Query = "insert into database.coidset (" & coid.ToString & ") values ('" & COcombobox.Text & "')"
        Command = New MySqlCommand(Query, Connection)
        DataReader = Command.ExecuteReader
        COListBox.Items.Add(COcombobox.Text)
        COListBox.SelectedIndex = -1
        COcombobox.ResetText()
        num = num + 1
        Connection.Close()
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

答案 6 :(得分:0)

randomForest(x =数据,y =标签,重要性= TRUE,ntree = 1000)

label是一个因素,因此在传递给randomForest函数之前,请使用droplevels(label)删除具有零计数的级别。有用。

要检查每个级别的计数,请使用表(标签)功能。

答案 7 :(得分:-1)

今天我和你有同样的问题我已经解决了。 当你做随机森林时,R默认是分类,而我的响应是数字。当您使用子集作为训练数据集时,与测试相比,训练水平受到限制。