变换之所以有用,是因为你可以用它们来近似非线性函数。如果你上过微积分课程,可能听说过泰勒定理,它指出任何光滑函数都可以用无穷多项式之和来近似。这意味着你可以通过拟合一个类似 y = a_1 + a_2 * x + a_3 * x^2 + a_4 * x ^ 3 的方程,用线性函数任意逼近一个光滑函数。手动输入这样的序列很繁琐,因此 R 提供了一个辅助函数 poly():
model_matrix(df, y ~ poly(x, 2)) #> # A tibble: 3 × 3 #> (Intercept) poly(x, 2)1 poly(x, 2)2 #>
然而,使用 poly() 存在一个主要问题:在数据范围之外,多项式会迅速发散到正无穷或负无穷。一种更安全的替代方案是使用自然样条 splines::ns():
library(splines) model_matrix(df, y ~ ns(x, 2)) #> # A tibble: 3 × 3 #> (Intercept) ns(x, 2)1 ns(x, 2)2 #>
让我们看看当我们尝试近似一个非线性函数时会是什么样子:
sim5 <- tibble( x = seq(0, 3.5 * pi, length = 50), y = 4 * sin(x) + rnorm(length(x)) ) ggplot(sim5, aes(x, y)) + geom_point()