2017-02-15 77 views
3

这实际上是一个完全有用的问题的副本,其答案是(部分)由提问者提供的。原标题:“R中用于文本分析的神经网络模型具有超过512个字符的公式”。他最终解决了这个问题,虽然他给出的推理是错误的,他通过删除问题并使评论和解决方案不可见来加重了这个错误。配方到神经网络的错误


我试图拟合一个神经网络模型来分类2个桶中的一个网站。培训数据特征是网站上所有链接中的词,例如,一个网站可能具有“家”,“约”,“联系人”,“产品”等特征。数据的结构为带有类列的数据框,然后是培训中每个单词的列。每行都有该类别(合格或不合格)以及该网站上显示的每个单词的0和1。

显示合理次数的单词总数约为1000,我希望将它们全部用作特征。但是,公式似乎有225个字符限制,所以我无法这样做。

我没有一个好的数据集来给出可重复的输出,但这里是我的代码和我得到的错误。

如果我尝试做一个公式,它就会被切断:

f <- as.formula(paste("class ~ ", paste(clean.features, collapse = "+", sep = ""))) 
Error in parse(text = x, keep.source = FALSE) : :2:0: unexpected end of input 1: ranty+recipes+contract+just+inventory+types+working+wine+hampshire+suppliers+rise+body+selection+laurel+trek+arlington+cabinet+citrus+advertisers+rhode+highway+intl+province+jewelers+cycles+wy 

如果我尝试使用所有的功能:如果我使用as.formula

nn.model <- neuralnet(paste("class ~ ", paste(clean.features, collapse = "+", sep = "")), data = training.data, 
       hidden = num.nodes) 
       ) 
Error in parse(text = x, keep.source = FALSE) : :2:0: unexpected end of input 1: ranty+recipes+contract+just+inventory+types+working+wine+hampshire+suppliers+rise+body+selection+laurel+trek+arlington+cabinet+citrus+advertisers+rhode+highway+intl+province+jewelers+cycles+wy 

同样的事情发生在数据集中,它表示没有“数据”参数(即使存在):

nn.model <- neuralnet(class ~ . , data = training.data, 
       hidden = num.nodes, 0)) 
       ) 
Error in terms.formula(formula) : '.' in formula and no 'data' argument 

> sessionInfo() 
R version 3.3.2 (2016-10-31) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows >= 8 x64 (build 9200) 

任何变通办法的想法?

+0

链接到原始:http://stackoverflow.com/questions/42235474/formulas-with-more-than-512-characters-for-neuralnet-model-in-r-for-text-analysi –

回答

1

总结:

  • 问题:reformulate(c(paste(sep="","X",1:5), "for", paste(sep="","X",1:5)), quote(Y))
  • 解决方案: deparse(引号(`for`),反引号= TRUE)

详细说明:

调试完以下行后,我也同意你的错误是与R语言中保留关键字的评估有关。

reformulate(c(paste(sep="","X",1:5), "for", paste(sep="","X",1:5)), quote(Y)) 

实际的错误时termtext文本进行解析,并用R

Browse[3]> termtext 
# [1] "response ~ X1+X2+X3+X4+X5+for+X1+X2+X3+X4+X5" 

Browse[3]> n 
debug: rval <- eval(parse(text = termtext, keep.source = FALSE)[[1L]]) 

Browse[3]> n 
# Error in parse(text = termtext, keep.source = FALSE) : 
# <text>:1:30: unexpected '+' 
# 1: response ~ X1+X2+X3+X4+X5+for+ 
#        ^

评估,以重现错误发生时,我评估单独与+关键词后缀的for,我得到了程序终止。

eval(parse(text = "for+", keep.source = FALSE)) 
# Error in parse(text = "for+", keep.source = FALSE) : 
# <text>:1:4: unexpected '+' 
# 1: for+ 
#  ^

完整的调试跟踪:

Browse[3]> n 
debug: if (!is.character(termlabels) || !length(termlabels)) stop("'termlabels' must be a character vector of length at least one") 
Browse[3]> n 
debug: has.resp <- !is.null(response) 
Browse[3]> n 
debug: termtext <- paste(if (has.resp) "response", "~", paste(termlabels, 
                   collapse = "+"), collapse = "") 
Browse[3]> ls() 
# [1] "has.resp" "intercept" "response" "termlabels" 
Browse[3]> has.resp 
# [1] TRUE 
Browse[3]> intercept 
# [1] TRUE 
Browse[3]> response 
# Y 
Browse[3]> termlabels 
# [1] "X1" "X2" "X3" "X4" "X5" "for" "X1" "X2" "X3" "X4" "X5" 

Browse[3]> n 
debug: if (!intercept) termtext <- paste(termtext, "- 1") 
Browse[3]> termtext 
# [1] "response ~ X1+X2+X3+X4+X5+for+X1+X2+X3+X4+X5" 

Browse[3]> n 
debug: rval <- eval(parse(text = termtext, keep.source = FALSE)[[1L]]) 

Browse[3]> n 
# Error in parse(text = termtext, keep.source = FALSE) : 
# <text>:1:30: unexpected '+' 
# 1: response ~ X1+X2+X3+X4+X5+for+ 
#        ^

编辑:

解决方案: 如果这样计算是不可避免的,那么人们可能会找出R语言的关键词第一然后围绕它使用deparse()函数,这将消除t的评估下摆作为该级别的关键词,相反,它将被评估为文字。

reformulate(c(paste(sep="","X",1:5), deparse("for"), paste(sep="","X",1:5)), quote(Y)) 
# Y ~ X1 + X2 + X3 + X4 + X5 + "for" + X1 + X2 + X3 + X4 + X5 

但是这会在模型创建过程中产生错误invalid model。更好的方法是引用deparse()函数中的关键词,然后创建公式并将数据应用于模型。

reformulate(c(paste(sep="","X",1:5), deparse(quote(`for`), backtick = TRUE), paste(sep="","X",1:5)), quote(Y)) 

# Y ~ X1 + X2 + X3 + X4 + X5 + `for` + X1 + X2 + X3 + X4 + X5 

下面是一个例子:

df1 <- data.frame(`for` = 6:10, y = 1:5, stringsAsFactors = FALSE) 
    colnames(df1) <- c('for', 'y') 
    df1 
    # for y 
    # 1 6 1 
    # 2 7 2 
    # 3 8 3 
    # 4 9 4 
    # 5 10 5 

    my_formula <- reformulate(deparse(quote(`for`), backtick = TRUE), 'y') 
    my_formula 
    # y ~ `for` 

    lm(my_formula, data = df1) 
    # Call: 
    # lm(formula = my_formula, data = df1) 
    # 
    # Coefficients: 
    # (Intercept)  `for` 
    #   -5   1 

browser()设置

要更改浏览上的错误,类型的全局设置中options(error = browser),然后调试你的代码,然后改回通过设置options(error = NULL)将其设置为出错时为NULL的出厂默认值。

在我上面的调试过程中,我创建了一个函数myfun并插入了browser()命令,然后找到它。最后,当我调用该函数时,我进入了浏览器模式。完成调试过程后,将删除插入功能代码的browser()命令。 注意:我没有更改出错的出厂默认选项错误在浏览器上使用options()

myfun <- function() 
{ 
    browser() 
    reformulate(c(paste(sep="","X",1:5), "for", paste(sep="","X",1:5)), quote(Y)) 
} 

source('myfun.R') 
myfun() 

对于内部的浏览器所使用的命令的详细信息(csnQ等),见?browser

+0

有见地的示范。建议您添加所需的代码以更改允许使用浏览器的选项的出厂默认设置。 –

2

我打算建议一个可能的起点来隔离问题。如果公式本身的长度存在问题,那么只需创建公式本身就可以重现问题。试试这个:

form <- reformulate(clean.features, quote(class)) 

Ew,只是键入,这使得我的内部R分析器畏缩。请将您的LHS变量重命名为除此类中心R函数之外的其他内容。也许这:

names(training.data)[ names(training.data) %in% "class"] <- "myclass" 
form <- reformulate(clean.features, quote(myclass)) 

的提问回答说我不在这里重复其他意见。我建议他说,他的字符限制为512个字符的理论是不正确的,但他然后发布:

因此,有很多手动审查,它看起来像“for”恰好在在其他帖子中提到的字符限制(512)。但实际的问题是“for”被公认为公式中的一个函数。抱歉,所有的困惑。


这只是不正确的。这个问题与公式中的字符限制无关,而与列的名称为“for”无关。这是R中的一个保留控制函数,可能发生在公式中的任何位置。看到这个演示(呈现出一些保留字做,但不是全部)

f <- reformulate(c(paste(sep="","X",1:5), "for", paste(sep="","X",1:5)), quote(Y)) 
Error in parse(text = termtext, keep.source = FALSE) : 
    <text>:1:30: unexpected '+' 
1: response ~ X1+X2+X3+X4+X5+for+ 
           ^
> f <- reformulate(c(paste(sep="","X",1:5), "class", paste(sep="","X",1:5)), quote(Y)) 
# no error ... OK perhaps not a reserved word 
> f <- reformulate(c(paste(sep="","X",1:5), "in", paste(sep="","X",1:5)), quote(Y)) 
Error in parse(text = termtext, keep.source = FALSE) : 
    <text>:1:27: unexpected 'in' 
1: response ~ X1+X2+X3+X4+X5+in 
          ^
> f <- reformulate(c(paste(sep="","X",1:5), "TRUE", paste(sep="","X",1:5)), quote(Y)) 
# no error, so maybe "TRUE" is not reserved and quote(TRUE) is? 

所以提高的期限是否可以共享一个函数的名称问题是正确的。答案并不完全如我所料。如果有人想提供更谨慎的CS解释,我会很乐意勾选他们的努力。

出现此问题的其他上下文是调用帮助页的前缀?运算符。尝试获得?for的帮助。你只会得到一行续行+提示。解析器正在等待左括号。