Parçalı regresyon çizgisini çizme


10

linesHer parçayı ayrı ayrı çizmek veya kullanmaktan başka bir parçalı modelin regresyon çizgisini çizmenin bir yolu var mı geom_smooth(aes(group=Ind), method="lm", fill=FALSE)?

m.sqft <- mean(sqft)
model <- lm(price~sqft+I((sqft-m.sqft)*Ind))
# sqft, price: continuous variables, Ind: if sqft>mean(sqft) then 1 else 0

plot(sqft,price)
abline(reg = model)
Warning message:
In abline(reg = model) :
  only using the first two of 3regression coefficients

Teşekkür ederim.

Yanıtlar:


6

Bunu nasıl kolayca yapabileceğimi bilmemin tek yolu, modelden tahminleri tahmin etmek sqftve planlamaktır. Genel ablineveya benzeri bir yol yoktur . Bu modellere uyacak ve sizin için çizim altyapısını sağlayacak olan segmentli pakete de göz atabilirsiniz .

Bunu tahminler ve temel grafikler ile yapın. İlk olarak, bazı kukla veriler:

set.seed(1)
sqft <- runif(100)
sqft <- ifelse((tmp <- sqft > mean(sqft)), 1, 0) + rnorm(100, sd = 0.5)
price <- 2 + 2.5 * sqft
price <- ifelse(tmp, price, 0) + rnorm(100, sd = 0.6)
DF <- data.frame(sqft = sqft, price = price,
                 Ind = ifelse(sqft > mean(sqft), 1, 0))
rm(price, sqft)
plot(price ~ sqft, data = DF)

Modeli takın:

mod <- lm(price~sqft+I((sqft-mean(sqft))*Ind), data = DF)

Tahmin etmek ve tahmin etmek için bazı veriler oluşturun:

m.sqft <- with(DF, mean(sqft))
pDF <- with(DF, data.frame(sqft = seq(min(sqft), max(sqft), length = 200)))
pDF <- within(pDF, Ind <- ifelse(sqft > m.sqft, 1, 0))
pDF <- within(pDF, price <- predict(mod, newdata = pDF))

Regresyon çizgilerini çizin:

ylim <- range(pDF$price, DF$price)
xlim <- range(pDF$sqft, DF$sqft)
plot(price ~ sqft, data = DF, ylim = ylim, xlim = xlim)
lines(price ~ sqft, data = pDF, subset = Ind > 0, col = "red", lwd = 2)
lines(price ~ sqft, data = pDF, subset = Ind < 1, col = "red", lwd = 2)

Bunu basit bir işleve kodlayabilirsiniz - yalnızca önceki iki kod parçasındaki adımlara ihtiyacınız vardır - bunun yerine kullanabilirsiniz abline:

myabline <- function(model, data, ...) {
    m.sqft <- with(data, mean(sqft))
    pDF <- with(data, data.frame(sqft = seq(min(sqft), max(sqft),
                                            length = 200)))
    pDF <- within(pDF, Ind <- ifelse(sqft > m.sqft, 1, 0))
    pDF <- within(pDF, price <- predict(mod, newdata = pDF))
    lines(price ~ sqft, data = pDF, subset = Ind > 0, ...)
    lines(price ~ sqft, data = pDF, subset = Ind < 1, ...)
    invisible(model)
}

Sonra:

ylim <- range(pDF$price, DF$price)
xlim <- range(pDF$sqft, DF$sqft)
plot(price ~ sqft, data = DF, ylim = ylim, xlim = xlim)
myabline(mod, DF, col = "red", lwd = 2)

Via parçalı paketin

require(segmented)
mod2 <- lm(price ~ sqft, data = DF)
mod.s <- segmented(mod2, seg.Z = ~ sqft, psi = 0.5,
                   control = seg.control(stop.if.error = FALSE))
plot(price ~ sqft, data = DF)
plot(mod.s, add = TRUE)
lines(mod.s, col = "red")

Bu verilerle, kesme noktasını tahmin etmez mean(sqft), ancak bu paketteki plotve linesyöntemleri myabline, takılan lm()modelden diretcly sizin için bu işi yapmaktan daha genel bir şey uygulamanıza yardımcı olabilir .

Düzenle: Segmentin kesme noktasının konumunu tahmin etmesini istiyorsanız, 'psi'bağımsız değişkeni şu şekilde ayarlayın NA:

mod.s <- segmented(mod2, seg.Z = ~ sqft, psi = NA,
                   control = seg.control(stop.if.error = FALSE))

Sonra segmentedçalışacağız K = 10ait quantiles sqftile, Kayarlı seg.control()ve hangi varsayılan 10. Daha fazlası ?seg.controliçin bakınız .


@Gavin (+1) Benimkinden çok daha eksiksiz bir yanıt; Sadece beğendim.
chl

@Gavin "Segmentlere ayrılmış paket üzerinden" bölümü verilerim için çalışmadı. segmentedKomutu çalıştırdıktan sonra bir "Kesme noktası tahmin edilmedi" aldım .
George Dontas

@ gd047: Özür dilerim, gösterdiğim kodda bir hata oluştu. seq.ZYanıtla bölümlere ayrılmış bir ilişkisi olan değişkenlerin tek taraflı formülünü içeren bir bağımsız değişken sağlamanız gerekir . Cevabımı, sizin için değer seçmeye seq.Z = ~ sqftilişkin bir not ekledim ve ekledim . segmentedpsi
Gavin Simpson

@ gd047 Bu soru orijinal sorunuzu daha iyi bir şekilde ele aldığından cevabımı kaldırmak istiyorum. Bunu benim yerine kabul eder misiniz?
chl

@chl Tabii ki, hala bir hata alıyorum: Hata (model) objF Hata model <- mf: koşul uzunluğu> 1 ise ve sadece ilk eleman kullanılırmodel<mf:argumentisnotinterpretableaslogicalInaddition:Warningmessage:Inif(model)objF
George Dontas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.