在R语言中测试正弦曲线模板与测试数据的拟合效果
问题描述
已将数据集划分为训练集和测试集,用训练集拟合正弦曲线的R代码及结果如下:
freq = seq(from=21, to=80, by=0.5) amp = c(-45.22247,-44.87434,-44.30659, -44.104, -44.08027 ,-44.32827, -44.52562, -44.81116, -45.11858, -45.61112, -45.88737, -45.9517, -46.00517,-45.78666, -45.64515, -45.32656, -45.12009, -44.92572, -44.58918,-44.18919, -43.75679, -43.4801, -43.13948, -42.86826 ,-42.59199,-42.23767, -42.06125, -41.99265 ,-41.91103, -41.96361, -42.10183,-42.47087, -42.86456, -43.17823 ,-43.41674, -43.6427 ,-43.79429,-43.71881, -43.58482 ,-43.53886, -43.29379, -43.00895 ,-42.69728,-42.331 ,-42.11675, -41.84402, -41.63068 ,-41.28213, -40.88509,-40.64461 ,-40.47236 ,-40.49424, -40.73463, -41.02037, -41.49101, -41.95741 ,-42.36682, -42.83582 ,-43.08535, -43.16926, -43.20281,-43.08085, -43.08461, -42.96666, -42.70192, -42.57608 ,-42.30105,-42.01737, -41.58435 ,-41.24757, -40.96 ,-40.68981 ,-40.39803,-40.2478, -40.23024, -40.48872, -40.68104, -41.04532, -41.53119,-41.88053, -42.17658, -42.32618, -42.41549 ,-42.36513, -42.38881,-42.25508, -42.13853, -41.89402, -41.66664, -41.3869, -41.02896, -40.83986, -40.44932 ,-40.14661, -39.84292, -39.66413, -39.60376, -39.63048, -39.75595 ,-39.88888, -40.18054 ,-40.491, -40.62274, -40.8282, -40.92761, -41.1448, -41.0102 ,-41.06486, -40.96643,-40.93895 ,-40.72338, -40.58406, -40.44275 ,-40.28842, -40.23578, -40.04179, -39.93855, -39.94855, -39.90564) ssp <- data.frame(freq, amp) A<- (max(ssp$amp)-min(ssp$amp)/2) C<-((max(ssp$amp)+min(ssp$amp))/2) res1<- nlsLM(amp ~ A*sin(omega*freq+phi)+C, data=ssp, start=list(A=A,omega=pi/6,phi=1,C=C)) sumres=summary(res1) co <- coef(res1) #resid(res1) #sum(resid(res1)^2) fit <- function(x, a, b, c, d) {a*sin(b*x+c)+d} # Plot result plot(ssp) curve(fit(x, a=co["A"], b=co["omega"], c=co["phi"], d=co["C"]), add=TRUE ,lwd=2, col="steelblue")
拟合结果:
sumres Formula: amp ~ A * sin(omega * freq + phi) + C Parameters: Estimate Std. Error t value Pr(>|t|) A -1.00030 0.20105 -4.975 2.3e-06 *** omega 0.53007 0.01196 44.332 < 2e-16 *** phi -0.31121 0.64156 -0.485 0.629 C -42.19834 0.14390 -293.248 < 2e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 1.552 on 115 degrees of freedom Number of iterations to convergence: 7 Achieved convergence tolerance: 1.49e-08
尝试用训练得到的系数拟合测试数据时,执行以下代码报错:
newssp = similar to data above res2<- nls(amp ~ co["A"]*sin(co["omega"]*freq+co["phi"])+co["C"], data=newssp)
错误信息:
Error in getInitial.default(func, data, mCall = as.list(match.call(func, : no 'getInitial' method found for "function" objects
需要了解该正弦曲线模板与测试数据的拟合效果,求合适方法。
解决方法
1. 直接计算预测值并评估拟合指标
不需要用nls重新拟合,因为所有参数已固定为训练得到的值,直接用这些参数对测试集的freq计算预测amp,再通过残差平方和、R²等指标评估拟合效果:
# 计算测试集的预测值 newssp$pred_amp <- fit(newssp$freq, a=co["A"], b=co["omega"], c=co["phi"], d=co["C"]) # 计算残差平方和(RSS) rss <- sum((newssp$amp - newssp$pred_amp)^2) # 计算总平方和(TSS) tss <- sum((newssp$amp - mean(newssp$amp))^2) # 计算R² r_squared <- 1 - (rss/tss) # 输出评估指标 cat("残差平方和:", rss, "\n") cat("R²:", r_squared, "\n")
2. 可视化拟合效果
将测试集原始数据和预测曲线绘制在一起,直观观察拟合情况:
# 绘制测试集原始数据 plot(amp ~ freq, data=newssp, main="测试集拟合效果", xlab="频率", ylab="振幅") # 添加预测曲线 curve(fit(x, a=co["A"], b=co["omega"], c=co["phi"], d=co["C"]), add=TRUE, lwd=2, col="steelblue") # 可选:叠加原始点和预测点的连线 lines(newssp$freq, newssp$pred_amp, col="red", type="p", pch=20)
3. 微调部分参数(可选)
如果想在训练集参数基础上微调部分参数适配测试集(比如固定omega和phi,只调整振幅A和偏移C),可以用nls指定固定参数:
# 固定omega和phi,仅拟合A和C res2 <- nls(amp ~ A*sin(co["omega"]*freq + co["phi"]) + C, data=newssp, start=list(A=co["A"], C=co["C"])) # 查看微调后的结果 summary(res2) # 计算微调后的预测值并评估 newssp$pred_amp_tuned <- predict(res2)
内容的提问来源于stack exchange,提问作者etgriffiths
相关产品推荐
相关产品推荐

