R &引用;在…%*%中出错:“不一致的论点”;在回归中使用自函数
我有一个函数Q(x | delta):R^n-->R,我想拟合一个非线性分位数回归。函数Q(.)使用了一些矩阵运算,如果不使用它将非常复杂。问题在于,当公式参数中使用的函数中存在矩阵运算时,nlrq(非线性分位数回归)和nls(非线性回归)似乎不起作用R &引用;在…%*%中出错:“不一致的论点”;在回归中使用自函数,r,matrix-multiplication,non-linear-regression,R,Matrix Multiplication,Non Linear Regression,我有一个函数Q(x | delta):R^n-->R,我想拟合一个非线性分位数回归。函数Q(.)使用了一些矩阵运算,如果不使用它将非常复杂。问题在于,当公式参数中使用的函数中存在矩阵运算时,nlrq(非线性分位数回归)和nls(非线性回归)似乎不起作用 以举例说明,考虑更简单的函数f(x1,x2,a,b,c),当我不使用矩阵运算时,我可以用在NLRQ和NLS函数的公式参数中,但是当它用矩阵运算写时,公式公式中不起作用。 library('quantreg') ## Genera
以举例说明,考虑更简单的函数f(x1,x2,a,b,c),当我不使用矩阵运算时,我可以用在NLRQ和NLS函数的公式参数中,但是当它用矩阵运算写时,公式公式中不起作用。
library('quantreg')
## Generating the data
x1<- rnorm(200)
x2<- rnorm(200)
y<- 1+3*sin(x1)+2*cos(x2) +rnorm(200)
Dat<- data.frame(y,x1,x2)
## The function F1 without matrix operation
F1<- function(x_1, x_2, a, b,c){a+b*sin(x_1)+c*cos(x_2)}
## The function F2 with matrix operation
F2<- function(x_1, x_2, a, b,c){t(c(1,sin(x_1),cos(x_2)))%*%c(a,b,c)}
## Both functions work perfectly
F1(x_1=3, x_2=2, a=1, b=3,c=2)
F2(x_1=3, x_2=2, a=1, b=3,c=2)
## But only F1 can be estimated by nls and nlrq
nls_1<-nls(y ~ F1(x_1 = x1, x_2 = x2, a = 1, b, c),
data = Dat, start = list(b = 3, c = 2))
nlrq_1<-nlrq(y ~ F1(x_1 = x1, x_2 = x2, a = 1, b, c),
data = Dat, start = list(b = 3, c = 2), tau = 0.9)
## When F2 is used in the formula argument an error happens
nls_2<-nls(y ~ F2(x_1 = x1, x_2 = x2, a = 1, b, c),
data = Dat, start = list(b = 3, c = 2))
nlrq_2<-nlrq(y ~ F2(x_1 = x1, x_2 = x2, a = 1, b, c),
data = Dat, start = list(b = 3, c = 2), tau = 0.9)
library('quantreg')
##生成数据
x1您的函数F2()
不适用于向量参数x_1
,x_2
。。。因为c(…)
只构造了一个长向量(不是矩阵)。
见:
结果:
#> F1(x_1=c(3,5), x_2=c(2,4), a=1, b=3,c=2)
#[1] 0.5910664 -3.1840601
#> F2(x_1=c(3,5), x_2=c(2,4), a=1, b=3,c=2)
#error in t(c(1, sin(x_1), cos(x_2))) %*% c(a, b, c) : ...
函数nls()
和nlrq()
正在向函数F2()
(分别为F1()
)发送向量(即数据帧Dat
)中的列)
以下是F2()
的一些矢量化定义:
F2()的其他定义
F2对于这一点,您可以使用通用优化功能。R中通常的默认值是optim
,但是还有很多其他的
这是最小二乘回归的例子。损失函数是残差的平方和。我已经重写了F2函数,这样它就可以处理向量参数了
sumsq <- function(beta)
{
F2 <- function(x1, x2, a, b, c)
{
cbind(1, sin(x1), cos(x2)) %*% c(a, b, c)
}
yhat <- F2(Dat$x1, Dat$x2, beta[1], beta[2], beta[3])
sum((Dat$y - yhat)^2)
}
beta0 <- c(mean(Dat$y), 1, 1)
optim(beta0, sumsq, method="BFGS")
#initial value 731.387431
#final value 220.265745
#converged
#$par
#[1] 0.8879371 3.0211286 2.1639280
#
#$value
#[1] 220.2657
#
#$counts
#function gradient
# 25 7
#
#$convergence
#[1] 0
#
#$message
#NULL
你可以对分位数回归做类似的事情,但那会更复杂。根据其他答案,我发现问题在于用c()
函数在F2内部构建向量。当我改用rbind()
时,无论是nls()
还是nlrq()
,估计都能很好地工作
接下来,我将显示F2的更正版本
## Changing c() for rbind()
F2<- function(x_1, x_2, a, b,c){t(rbind(1,sin(x_1),cos(x_2)))%*%rbind(a,b,c)}
## Now nls() and nlrq() work properly
nls_2<-nls(y ~ F2(x_1 = x1, x_2 = x2, a = 1, b, c),
data = Dat, start = list(b = 3, c = 2))
nlrq_2<-nlrq(y ~ F2(x_1 = x1, x_2 = x2, a = 1, b, c),
data = Dat, start = list(b = 3, c = 2), tau = 0.9)
##更改rbind()的c()
抱歉,我忘了提到要使用nlrq需要quantreg软件包,然后在代码中添加install.packages('quantreg')
和library('quantreg')
。我没想到函数会使用向量参数,但是你给了我一个想法,用rbind而不是c在F2内部构建向量,因此,估计工作正常!非常感谢。当我回到我原来的问题时,我理解了为什么你指出函数不接受向量作为参数是一个问题。nls和nlrq函数使用解释变量的整个向量作为公式中的参数。
sumsq <- function(beta)
{
F2 <- function(x1, x2, a, b, c)
{
cbind(1, sin(x1), cos(x2)) %*% c(a, b, c)
}
yhat <- F2(Dat$x1, Dat$x2, beta[1], beta[2], beta[3])
sum((Dat$y - yhat)^2)
}
beta0 <- c(mean(Dat$y), 1, 1)
optim(beta0, sumsq, method="BFGS")
#initial value 731.387431
#final value 220.265745
#converged
#$par
#[1] 0.8879371 3.0211286 2.1639280
#
#$value
#[1] 220.2657
#
#$counts
#function gradient
# 25 7
#
#$convergence
#[1] 0
#
#$message
#NULL
nls(y ~ F1(x_1=x1, x_2=x2, a=1, b, c),
data=Dat, start=list(b=3, c=2))
Nonlinear regression model
model: y ~ F1(x_1 = x1, x_2 = x2, a = 1, b, c)
data: Dat
b c
3.026 2.041
residual sum-of-squares: 221
Number of iterations to convergence: 1
Achieved convergence tolerance: 7.823e-10
## Changing c() for rbind()
F2<- function(x_1, x_2, a, b,c){t(rbind(1,sin(x_1),cos(x_2)))%*%rbind(a,b,c)}
## Now nls() and nlrq() work properly
nls_2<-nls(y ~ F2(x_1 = x1, x_2 = x2, a = 1, b, c),
data = Dat, start = list(b = 3, c = 2))
nlrq_2<-nlrq(y ~ F2(x_1 = x1, x_2 = x2, a = 1, b, c),
data = Dat, start = list(b = 3, c = 2), tau = 0.9)