[英]Obtain standardised residuals and "Residual v.s. Fitted" plot for "mlm" object from `lm()`
set.seed(0)
## 2 response of 10 observations each
response <- matrix(rnorm(20), 10, 2)
## 3 covariates with 10 observations each
predictors <- matrix(rnorm(30), 10, 3)
fit <- lm(response ~ predictors)
我一直在使用以下方法為整個模型生成殘差圖:
plot(fitted(fit),residuals(fit))
但是,我想為每個預測變量協變量制作單獨的圖。 我可以通過以下方式一次做一個:
f <- fitted(fit)
r <- residual(fit)
plot(f[,1],r[,1])
然而,這種方法的問題在於它需要可推廣到具有更多預測協變量的數據集。 有沒有辦法在迭代(f)和(r)的每一列時使用 plot ? 或者有沒有辦法讓plot()
可以按顏色對每個協變量進行分組?
確保您使用的是標准化殘差而不是原始殘差
我經常看到plot(fitted(fit), residuals(fit))
但它在統計上是錯誤的。 我們使用plot(fit)
來生成診斷圖,因為我們需要標准化的殘差而不是原始殘差。 閱讀?plot.lm
了解更多信息。 但是對“mlm”的plot
方法的支持很差:
plot(fit)
# Error: 'plot.mlm' is not implemented yet
為“mlm”定義“rstandard”S3 方法
不支持plot.mlm
原因有很多,其中之一是缺少rstandard.mlm
。 對於“lm”和“glm”類,有一個通用的S3方法“rstandard”來獲得標准化殘差:
methods(rstandard)
# [1] rstandard.glm* rstandard.lm*
不支持“傳銷”。 所以我們要先填補這個空白。
得到標准化殘差並不難。 設hii
是帽子矩陣的對角線,殘差的逐點估計標准誤差為sqrt(1 - hii) * sigma
,其中sigma = sqrt(RSS / df.residual)
是估計的殘差標准誤差。 RSS
為殘差平方和; df.residual
是殘差自由度。
hii
可以從模型矩陣的 QR 分解的矩陣因子Q
計算: rowSums(Q ^ 2)
。 對於“mlm”,只有一個 QR 分解,因為所有響應的模型矩陣都相同,因此我們只需要計算一次hii
。
不同的響應有不同的sigma
,但它們優雅地colSums(residuals(fit) ^ 2) / df.residual(fit)
。
現在,讓我們總結一下這些想法,以獲得我們自己的“mlm”的“rstandard”方法:
## define our own "rstandard" method for "mlm" class
rstandard.mlm <- function (model) {
Q <- with(model, qr.qy(qr, diag(1, nrow = nrow(qr$qr), ncol = qr$rank))) ## Q matrix
hii <- rowSums(Q ^ 2) ## diagonal of hat matrix QQ'
RSS <- colSums(model$residuals ^ 2) ## residual sums of squares (for each model)
sigma <- sqrt(RSS / model$df.residual) ## ## Pearson estimate of residuals (for each model)
pointwise_sd <- outer(sqrt(1 - hii), sigma) ## point-wise residual standard error (for each model)
model$residuals / pointwise_sd ## standardised residuals
}
請注意在函數名稱中使用.mlm
來告訴 R 這是關聯的 S3 方法。 一旦我們定義了這個函數,我們就可以在“rstandard”方法中看到它:
## now there are method for "mlm"
methods(rstandard)
# [1] rstandard.glm* rstandard.lm* rstandard.mlm
要調用此函數,我們不必顯式調用rstandard.mlm
; 調用rstandard
就足夠了:
## test with your fitted model `fit`
rstandard(fit)
# [,1] [,2]
#1 1.56221865 2.6593505
#2 -0.98791320 -1.9344546
#3 0.06042529 -0.4858276
#4 0.18713629 2.9814135
#5 0.11277397 1.4336484
#6 -0.74289985 -2.4452868
#7 0.03690363 0.7015916
#8 -1.58940448 -1.2850961
#9 0.38504435 1.3907223
#10 1.34618139 -1.5900891
標准化殘差是N(0, 1)
分布的。
獲取“mlm”的殘差與擬合圖
您的初步嘗試:
f <- fitted(fit); r <- rstandard(fit); plot(f, r)
不是一個壞主意,前提是可以相互識別不同模型的點。 所以我們可以嘗試為不同的模型使用不同的點顏色:
plot(f, r, col = as.numeric(col(f)), pch = 19)
像col
、 pch
和cex
這樣的圖形參數可以采用向量輸入。 我要求plot
對r[,j] ~ f[,j]
使用col = j
,其中j = 1, 2,..., ncol(f)
。 閱讀?par
“顏色規范”,了解col = j
含義。 pch = 19
告訴plot
繪制實心點。 閱讀各種選擇的基本圖形參數。
最后,您可能想要一個傳奇。 你可以做
plot(f, r, col = as.numeric(col(f)), pch = 19, ylim = c(-3, 4))
legend("topleft", legend = paste0("response ", 1:ncol(f)), pch = 19,
col = 1:ncol(f), text.col = 1:ncol(f))
為了給圖例框留出空間,我們稍微擴展了ylim
。 由於標准化殘差為N(0,1)
,因此ylim = c(-3, 3)
是一個很好的范圍。 如果我們想將圖例框放在左上角,我們將ylim
擴展到c(-3, 4)
。 您可以通過ncol
、 title
等更多地自定義您的圖例。
你有多少回復?
如果您的回復不多,則上述建議效果很好。 如果你有很多,建議將它們繪制在單獨的圖中。 您發現for
循環是不錯的,除了您需要將繪圖區域拆分為不同的子圖,可能使用par(mfrow = c(?, ?))
。 如果您采用這種方法,還要設置內邊緣mar
和外邊緣oma
。 您可以閱讀如何為矩陣中的分類時間序列數據生成更好的圖? 舉一個這樣做的例子。
如果你有更多的回應,你可能想要兩者的混合? 假設您有 42 個響應,您可以執行par(mfrow = c(2, 3))
,然后在每個子圖中繪制 7 個響應。 現在的解決方案更多的是基於意見。
我就是這樣解決的。
for(i in 1:ncol(f)) {
plot(f[,i],r[,i])
}
腦洞大開。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.