如何在 R 中创建分段常数(Bin Smooth)模型?
How to Create Piecewise Constant (Bin Smooth) Model in R?
我找遍了这个问题的答案。
如果您有一个解释变量 x 和一个响应 y,您如何在 R 中拟合分段常量回归模型?
我知道 segmented
包可用于创建分段非常数模型,但我不知道如何将每条线段的斜率限制为 0。我需要能够使用模型进行预测,这就是为什么我不能简单地使用 regressogram
函数的原因。
感谢您的帮助,
杰克
您可以使用 approxfun
在 base R 中执行此操作,方法是包含参数 method = "constant"
由于您不提供数据,我使用 R 中内置的数据做了一个示例。
StepFun = approxfun(x=iris$Sepal.Length,
y = iris$Sepal.Width, method = "constant")
编辑
我现在认为问题是将 x 的范围分成 bin 并创建一个分段常数函数(使用每个 bin 的 y 的平均值)。我给出了两个版本。一种更容易,一种更符合 OP 的评论。这两个都是使用 cut
对数据进行分箱来完成的。
版本 1:指定 bin 的端点
如果您只想自己指定 bin,这很容易。请注意,我正在绘制大量中间点。这避免了图中出现任何倾斜区域。
## To specify break boundaries
BREAKS = seq(4,8,0.5)
BINS = cut(iris$Sepal.Length, breaks=BREAKS, labels=FALSE)
MEANS = aggregate(iris$Sepal.Length, list(BINS), mean)$x
Step2 = approxfun(x=BREAKS[-1], y = MEANS, method = "constant")
curve(Step2, xlim=c(4.5,8),n=1001)
版本 2:指定每个 bin 的点数
这个版本的目标不是让 bin 的宽度相同,而是让每个 bin 包含(大约)相同数量的点。
您实际上不能保证可以做到这一点。如果您的数据中有多个相同的 x 值,则可能无法为每个 bin 获得完全相同的点数,但这将使您尽可能接近。这个想法是使用 quantiles
来告诉您每个箱子的点数近似相同的箱子边界。
## To specify number of points per bin
PointsPerBin = 15
Q = seq(0,1, PointsPerBin/length(iris$Sepal.Length))
QBREAKS = quantile(iris$Sepal.Length, Q)
QBINS = cut(iris$Sepal.Length, breaks=QBREAKS, labels=FALSE)
QMEANS = aggregate(iris$Sepal.Length, list(QBINS), mean)$x
Step3 = approxfun(x=QBREAKS[-1], y = QMEANS, method = "constant")
curve(Step3, xlim=c(4.5,8),n=1001)
同样,如果您使用少量的点,绘图中看起来会有倾斜区域。
我找遍了这个问题的答案。
如果您有一个解释变量 x 和一个响应 y,您如何在 R 中拟合分段常量回归模型?
我知道 segmented
包可用于创建分段非常数模型,但我不知道如何将每条线段的斜率限制为 0。我需要能够使用模型进行预测,这就是为什么我不能简单地使用 regressogram
函数的原因。
感谢您的帮助,
杰克
您可以使用 approxfun
在 base R 中执行此操作,方法是包含参数 method = "constant"
由于您不提供数据,我使用 R 中内置的数据做了一个示例。
StepFun = approxfun(x=iris$Sepal.Length,
y = iris$Sepal.Width, method = "constant")
编辑
我现在认为问题是将 x 的范围分成 bin 并创建一个分段常数函数(使用每个 bin 的 y 的平均值)。我给出了两个版本。一种更容易,一种更符合 OP 的评论。这两个都是使用 cut
对数据进行分箱来完成的。
版本 1:指定 bin 的端点
如果您只想自己指定 bin,这很容易。请注意,我正在绘制大量中间点。这避免了图中出现任何倾斜区域。
## To specify break boundaries
BREAKS = seq(4,8,0.5)
BINS = cut(iris$Sepal.Length, breaks=BREAKS, labels=FALSE)
MEANS = aggregate(iris$Sepal.Length, list(BINS), mean)$x
Step2 = approxfun(x=BREAKS[-1], y = MEANS, method = "constant")
curve(Step2, xlim=c(4.5,8),n=1001)
版本 2:指定每个 bin 的点数
这个版本的目标不是让 bin 的宽度相同,而是让每个 bin 包含(大约)相同数量的点。
您实际上不能保证可以做到这一点。如果您的数据中有多个相同的 x 值,则可能无法为每个 bin 获得完全相同的点数,但这将使您尽可能接近。这个想法是使用 quantiles
来告诉您每个箱子的点数近似相同的箱子边界。
## To specify number of points per bin
PointsPerBin = 15
Q = seq(0,1, PointsPerBin/length(iris$Sepal.Length))
QBREAKS = quantile(iris$Sepal.Length, Q)
QBINS = cut(iris$Sepal.Length, breaks=QBREAKS, labels=FALSE)
QMEANS = aggregate(iris$Sepal.Length, list(QBINS), mean)$x
Step3 = approxfun(x=QBREAKS[-1], y = QMEANS, method = "constant")
curve(Step3, xlim=c(4.5,8),n=1001)
同样,如果您使用少量的点,绘图中看起来会有倾斜区域。