如何对我的数据执行非线性回归
How to perform a non linear regression for my data
我为每个温度数据设置了温度和不适指数值。当我在温度(x 轴)和计算的不适指数值(y 轴)之间绘制图表时,我得到一条倒 U 形曲线。我想对其进行非线性回归并将其转换为 PMML 模型。我的目标是在给定一定温度的情况下得到预测的不适值。
请找到以下数据集:
Temp <- c(0,5,10,6 ,9,13,15,16,20,21,24,26,29,30,32,34,36,38,40,43,44,45, 50,60)
Disc<-c(0.00,0.10,0.25,0.15,0.24,0.26,0.30,0.31,0.40,0.41,0.49,0.50,0.56, 0.80,0.90,1.00,1.00,1.00,0.80,0.50,0.40,0.20,0.15,0.00)
如何对该数据集进行非线性回归(可能使用 nls
??)?
我确实看过这个,然后我认为它并不像我们大多数人最初想的那样使用nls
那么简单。
nls
适合参数模型,但根据您的数据(散点图),很难提出合理的模型假设。我建议为此使用非参数平滑。
有很多散点图平滑方法,如核平滑ksmooth
、平滑样条smooth.spline
和LOESSloess
。我更喜欢使用 smooth.spline
,下面是我们可以用它做的事情:
fit <- smooth.spline(Temp, Disc)
请阅读 ?smooth.spline
以了解需要什么以及 returns。我们可以通过
检查拟合样条曲线
plot(Temp, Disc)
lines(fit, col = 2)
如果您想在其他地方进行预测,请使用 predict
函数 (predict.smooth.spline
)。比如我们要预测Temp = 20
和Temp = 44
,我们可以使用
predict(fit, c(20,44))$y
# [1] 0.3940963 0.3752191
不建议在 range(Temp)
之外进行预测,因为它可能会受到潜在的不良外推效应的影响。
在使用非参数方法之前,我也尝试过使用回归样条和正交多项式基的非线性回归,但它们没有提供令人满意的结果。主要原因是平滑度没有惩罚。例如,我展示了一些 poly
:
的尝试
try1 <- lm(Disc ~ poly(Temp, degree = 3))
try2 <- lm(Disc ~ poly(Temp, degree = 4))
try3 <- lm(Disc ~ poly(Temp, degree = 5))
plot(Temp, Disc, ylim = c(-0.3,1.0))
x<- seq(min(Temp), max(Temp), length = 50)
newdat <- list(Temp = x)
lines(x, predict(try1, newdat), col = 2)
lines(x, predict(try2, newdat), col = 3)
lines(x, predict(try3, newdat), col = 4)
可以看出拟合曲线是人为的
我们可以按如下方式拟合多项式,但它会过度拟合数据,因为我们有更高的次数:
m <- nls(Disc ~ a + b*Temp + c*Temp^2 + d*Temp^3 + e*Temp^4, start=list(a=0, b=1, c=1, d=1, e=1))
plot(Temp,Disc,pch=19)
lines(Temp,predict(m),lty=2,col="red",lwd=3)
m <- nls(Disc ~ a + b*Temp + c*Temp^2 + d*Temp^3 + e*Temp^4 + f*Temp^5, start=list(a=0, b=1, c=1, d=1, e=1, f=1))
lines(Temp,predict(m),lty=2,col="blue",lwd=3)
m <- nls(Disc ~ a + b*Temp + c*Temp^2 + d*Temp^3 + e*Temp^4 + f*Temp^5 + g*Temp^6, start=list(a=0, b=1, c=1, d=1, e=1, f=1, g=1))
lines(Temp,predict(m),lty=2,col="green",lwd=3)
m.poly <- lm(Disc ~ poly(Temp, degree = 15))
lines(Temp,predict(m),lty=2,col="yellow",lwd=3)
legend(x = "topleft", legend = c("Deg 4", "Deg 5", "Deg 6", "Deg 20"),
col = c("red", "green", "blue", "yellow"),
lty = 2)
我为每个温度数据设置了温度和不适指数值。当我在温度(x 轴)和计算的不适指数值(y 轴)之间绘制图表时,我得到一条倒 U 形曲线。我想对其进行非线性回归并将其转换为 PMML 模型。我的目标是在给定一定温度的情况下得到预测的不适值。
请找到以下数据集:
Temp <- c(0,5,10,6 ,9,13,15,16,20,21,24,26,29,30,32,34,36,38,40,43,44,45, 50,60)
Disc<-c(0.00,0.10,0.25,0.15,0.24,0.26,0.30,0.31,0.40,0.41,0.49,0.50,0.56, 0.80,0.90,1.00,1.00,1.00,0.80,0.50,0.40,0.20,0.15,0.00)
如何对该数据集进行非线性回归(可能使用 nls
??)?
我确实看过这个,然后我认为它并不像我们大多数人最初想的那样使用nls
那么简单。
nls
适合参数模型,但根据您的数据(散点图),很难提出合理的模型假设。我建议为此使用非参数平滑。
有很多散点图平滑方法,如核平滑ksmooth
、平滑样条smooth.spline
和LOESSloess
。我更喜欢使用 smooth.spline
,下面是我们可以用它做的事情:
fit <- smooth.spline(Temp, Disc)
请阅读 ?smooth.spline
以了解需要什么以及 returns。我们可以通过
plot(Temp, Disc)
lines(fit, col = 2)
如果您想在其他地方进行预测,请使用 predict
函数 (predict.smooth.spline
)。比如我们要预测Temp = 20
和Temp = 44
,我们可以使用
predict(fit, c(20,44))$y
# [1] 0.3940963 0.3752191
不建议在 range(Temp)
之外进行预测,因为它可能会受到潜在的不良外推效应的影响。
在使用非参数方法之前,我也尝试过使用回归样条和正交多项式基的非线性回归,但它们没有提供令人满意的结果。主要原因是平滑度没有惩罚。例如,我展示了一些 poly
:
try1 <- lm(Disc ~ poly(Temp, degree = 3))
try2 <- lm(Disc ~ poly(Temp, degree = 4))
try3 <- lm(Disc ~ poly(Temp, degree = 5))
plot(Temp, Disc, ylim = c(-0.3,1.0))
x<- seq(min(Temp), max(Temp), length = 50)
newdat <- list(Temp = x)
lines(x, predict(try1, newdat), col = 2)
lines(x, predict(try2, newdat), col = 3)
lines(x, predict(try3, newdat), col = 4)
可以看出拟合曲线是人为的
我们可以按如下方式拟合多项式,但它会过度拟合数据,因为我们有更高的次数:
m <- nls(Disc ~ a + b*Temp + c*Temp^2 + d*Temp^3 + e*Temp^4, start=list(a=0, b=1, c=1, d=1, e=1))
plot(Temp,Disc,pch=19)
lines(Temp,predict(m),lty=2,col="red",lwd=3)
m <- nls(Disc ~ a + b*Temp + c*Temp^2 + d*Temp^3 + e*Temp^4 + f*Temp^5, start=list(a=0, b=1, c=1, d=1, e=1, f=1))
lines(Temp,predict(m),lty=2,col="blue",lwd=3)
m <- nls(Disc ~ a + b*Temp + c*Temp^2 + d*Temp^3 + e*Temp^4 + f*Temp^5 + g*Temp^6, start=list(a=0, b=1, c=1, d=1, e=1, f=1, g=1))
lines(Temp,predict(m),lty=2,col="green",lwd=3)
m.poly <- lm(Disc ~ poly(Temp, degree = 15))
lines(Temp,predict(m),lty=2,col="yellow",lwd=3)
legend(x = "topleft", legend = c("Deg 4", "Deg 5", "Deg 6", "Deg 20"),
col = c("red", "green", "blue", "yellow"),
lty = 2)