如何将线性模型与阶跃函数相结合
How to combine linear model with step function
假设我们有这个数据:
library(tidyverse)
library(modelr)
set.seed(42)
d1 <- tibble(x = 0:49, y = 5*x + rnorm(n = 50))
d2 <- tibble(x = 50:99, y = 10*x + rnorm(n = 50))
data <- rbind(d1, d2)
ggplot(data, aes(x, y)) +
geom_point()
如何拟合该数据?
我尝试了什么:
线性模型
m1 <- lm(y ~ x, data = data)
data %>%
add_predictions(m1) %>%
gather(key = cat, value = y, -x) %>%
ggplot(aes(x, y, color = cat)) +
geom_point()
步进函数
# step model
m2 <- lm(y ~ cut(x, 2), data = data)
data %>%
add_predictions(m2) %>%
gather(key = cat, value = y, -x) %>%
ggplot(aes(x, y, color = cat)) +
geom_point()
两者如何结合?
从数学上讲,您的模型采用以下形式
{ a_0 + a_1 x when x < 50
y = {
{ b_0 + b_1 x when x >= 50
您可以将其与指标函数结合起来,以单线方程的形式得出:
y = a_0 + (b_0 - a_0) * 1[x >= 50] + a_1 * x + (b_1 - a_1) * x * 1[x >= 50] + error
简化一下,我们可以这样写:
y = c_0 + c_1 * x + c_2 * z + c_3 * x * z + error
我写 z = 1[x >= 50]
的地方是为了强调这个指标函数只是另一个回归变量
在 R 中,我们可以这样拟合
lm(y ~ x * I(x >= 50), data = data)
其中 *
将根据需要完全交互 x
和 1[x >= 50]
。
with(data, {
plot(x, y)
reg = lm(y ~ x * I(x >= 50))
lines(x, predict(reg, data.frame(x)))
})
如果您不知道跳跃发生在 50,道路是敞开的,但是您可以比较均方误差:
x_range = 1:100
errs = sapply(x_range, function(BREAK) {
mean(lm(y ~ x * I(x >= BREAK), data = data)$residuals^2)
})
plot(x_range, errs)
x_min = x_range[which.min(errs)]
axis(side = 1L, at = x_min)
abline(v = x_min, col = 'red')
假设我们有这个数据:
library(tidyverse)
library(modelr)
set.seed(42)
d1 <- tibble(x = 0:49, y = 5*x + rnorm(n = 50))
d2 <- tibble(x = 50:99, y = 10*x + rnorm(n = 50))
data <- rbind(d1, d2)
ggplot(data, aes(x, y)) +
geom_point()
如何拟合该数据?
我尝试了什么:
线性模型
m1 <- lm(y ~ x, data = data)
data %>%
add_predictions(m1) %>%
gather(key = cat, value = y, -x) %>%
ggplot(aes(x, y, color = cat)) +
geom_point()
步进函数
# step model
m2 <- lm(y ~ cut(x, 2), data = data)
data %>%
add_predictions(m2) %>%
gather(key = cat, value = y, -x) %>%
ggplot(aes(x, y, color = cat)) +
geom_point()
两者如何结合?
从数学上讲,您的模型采用以下形式
{ a_0 + a_1 x when x < 50
y = {
{ b_0 + b_1 x when x >= 50
您可以将其与指标函数结合起来,以单线方程的形式得出:
y = a_0 + (b_0 - a_0) * 1[x >= 50] + a_1 * x + (b_1 - a_1) * x * 1[x >= 50] + error
简化一下,我们可以这样写:
y = c_0 + c_1 * x + c_2 * z + c_3 * x * z + error
我写 z = 1[x >= 50]
的地方是为了强调这个指标函数只是另一个回归变量
在 R 中,我们可以这样拟合
lm(y ~ x * I(x >= 50), data = data)
其中 *
将根据需要完全交互 x
和 1[x >= 50]
。
with(data, {
plot(x, y)
reg = lm(y ~ x * I(x >= 50))
lines(x, predict(reg, data.frame(x)))
})
如果您不知道跳跃发生在 50,道路是敞开的,但是您可以比较均方误差:
x_range = 1:100
errs = sapply(x_range, function(BREAK) {
mean(lm(y ~ x * I(x >= BREAK), data = data)$residuals^2)
})
plot(x_range, errs)
x_min = x_range[which.min(errs)]
axis(side = 1L, at = x_min)
abline(v = x_min, col = 'red')