Code
library(ggplot2)
# make regular sequence over the range of vector x (similar to modelr::seq_range)
<- function(x, length = length(x)) {
seq_range <- range(x)
ran seq.int(ran[1], ran[2], length.out = length)
}
Dokument obsahuje postup konštrukcie združeného rozdelenia náhodného vektora pomocou súboru pozorovaní,
Knižnice a funkcie
library(ggplot2)
# make regular sequence over the range of vector x (similar to modelr::seq_range)
<- function(x, length = length(x)) {
seq_range <- range(x)
ran seq.int(ran[1], ran[2], length.out = length)
}
Načítanie údajov
<- mtcars |>
dat subset(select = c(disp, mpg))
empirická hustota s jadrovým vyhladením
|>
dat ::pivot_longer(cols = everything(),
tidyrnames_to = "variable", values_to = "value") |>
ggplot() + aes(x = value) +
geom_histogram(aes(y = after_stat(density)), bins = 5, color="white") +
stat_density(geom="line", adjust = 1.) +
facet_wrap(~ variable, scales = "free")
číselné charakteristiky
|>
dat ::summarise(across(.cols = c(mpg, disp),
dplyr.fns = list(mean = mean, sdev = sd)
) )
mpg_mean mpg_sdev disp_mean disp_sdev
1 20.09062 6.026948 230.7219 123.9387
# alternatívne, pri väčšom počte premenných alebo charakteristík:
#dat |>
# tidyr::pivot_longer(cols = everything(),
# names_to = "variable", values_to = "value") |>
# dplyr::group_by(variable) |>
# dplyr::summarise(across(.cols = value,
# .fns = list(mean = mean, sdev = sd),
# .names = "{.fn}"
# ))
test normality (p-hodnota)
|> sapply(function(x) shapiro.test(x)$p.value) |> round(3) dat
disp mpg
0.021 0.123
bodový graf
ggplot(dat) + aes(x = disp, y = mpg) + geom_point()
korelačný koeficient
sapply(c("pearson", "kendall", "spearman"), function(x) cor(dat, method = x)[1,2])
pearson kendall spearman
-0.8475514 -0.7681311 -0.9088824
test nulovosti korelačného koeficientu
cor.test(~ disp + mpg, dat) # cor.test(~ ., dat)$p.value |> round(3)
Pearson's product-moment correlation
data: disp and mpg
t = -8.7472, df = 30, p-value = 9.38e-10
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.9233594 -0.7081376
sample estimates:
cor
-0.8475514
::ggscatterhist(dat, x = "disp", y = "mpg",
ggpubrmargin.plot = "histogram", bins = 5,
margin.params = list(fill = "lightgray"),
)# Pridaním ďalšej premennej s farebným odlíšením by sa dal pozorovať jej vplyv zvlášť na marginálne rozdelenia a na vzťah medzi disp a mpg.
<- list() # kontajner model
$emp <- list(
modelcdf = function(x) {
|> # nxp
dat apply(MARGIN = 1, '<=', x) |> # returns pxn matrix
apply(2, all) |> # that's why MARGIN = 2
mean()
}
)# model$emp$cdf(c(300, 20)) # alebo copula::F.n(c(300, 20), as.matrix(dat))
odhad parametrov metódou momentov
<- sapply(dat, mean)
mu <- cov(dat)
Sigma cbind(mean = mu, Sigma) |> round(1) # spojený výpis strednej hodnoty a kovariančnej matice
mean disp mpg
disp 230.7 15360.8 -633.1
mpg 20.1 -633.1 36.3
poskladanie PDF a CDF
$norm <- list(
modelpdf = function(x) mvtnorm::dmvnorm(x, mean = mu, sigma = Sigma),
cdf = function(x) apply(rbind(x), 1, function(y)
::pmvnorm(upper = y, mean = mu, sigma = Sigma)) |> as.numeric()
mvtnorm
)# model$norm$pdf(c(300, 20))
# Balík probhat (spolu so závislosťami barsurf, intoo a kubik) treba stiahnuť z archívu CRAN a nainštalovať zo súboru.
$smoo <- list(
modelpdf = probhat::pdfmv.cks(as.matrix(dat), a = c(0,0)),
cdf = probhat::cdfmv.cks(as.matrix(dat), a = c(0,0))
)# model$smoo$cdf(c(300,20))
Neparametrickým odhadom je empirické rozdelenie. Reprezentované je tabuľkou relatívnych početností alebo distribučnou funkciou (so schodkovitým grafom)
$marg$mpg$emp$cdf <- ecdf(dat$mpg)
model$marg$disp$emp$cdf <- ecdf(dat$disp)
model#plot(model$marg$mpg$emp$cdf, from=0, to=30)
Najprv iba ilustrujeme rôzne metódy odhadu parametrov rozdelenia.
<- with(dat, {
fit_norm <- c(mean = mean(mpg), sd = sd(mpg))
start <- lmomco::lmoms(mpg) # alebo lmom::samlmu(mpg)
lmoments rbind(
mom = start,
mle = MASS::fitdistr(mpg, densfun = dnorm,
start = as.list(start))$estimate,
lse = optim(par = start,
fn = function(pars) sum((model$marg$mpg$emp$cdf(mpg) - pnorm(mpg, mean=pars[1], sd=pars[2]))^2))$par,
lmo = lmomco::lmoms(mpg) |> lmomco::parnor() |> getElement("para")
# lmo = lmom::samlmu(dat$mpg) |> lmom::pelnor() # balík je od autora metódy
)
}) fit_norm
mean sd
mom 20.09062 6.026948
mle 20.09062 5.932030
lse 19.02397 5.378611
lmo 20.09062 6.022948
Odhady sú viac-menej podobné, najviac sa líši odhad minimalizáciou štvorca vzdialenosti ku empirickej CDF (pre ktorú možno existuje aj optimalizovaná verzia). Vezmeme najjednoduchší odhad, teda metódou momentov.
$marg$mpg$nor <- fit_norm["mom",] |>
modellist(
(\(par) pdf = function(x) dnorm(x, mean=par[1], sd=par[2]),
cdf = function(x) pnorm(x, mean=par[1], sd=par[2]),
qua = function(x) qnorm(x, mean=par[1], sd=par[2])
))()# plot(model$marg$mpg$nor$cdf, from=0, to=40, col=4)
# lines(model$marg$mpg$emp$cdf, from=0, to=40)
Pre premennú disp, pri ktorej bola zamietnutá hypotéza o normalite, si zvolíme (minimálne) dve konkurenčné parametrické triedy rozdelenia, medzi ktorými sa potom rozhodneme, napr. log-normálne a exponenciálne. (Pre kontrolu metódy rozkladu pomocou kopúl odhadneme aj normálne rozdelenie, aby sa takto zložené rozdelenie dalo porovnať s normálnym).
$marg$disp$lnor <- dat$disp |>
modelc(meanlog = mean(log(x)), sdlog = sd(log(x))))() |> # odhad metódou momentov
(\(x) list(
(\(par) pdf = function(x) dlnorm(x, meanlog=par[1], sdlog=par[2]),
cdf = function(x) plnorm(x, meanlog=par[1], sdlog=par[2]),
qua = function(x) qlnorm(x, meanlog=par[1], sdlog=par[2])
))()
$marg$disp$exp <- dat$disp |>
modelc(lambda = 1 / mean(x)))() |> # odhad metódou momentov
(\(x) list(
(\(par) pdf = function(x) dexp(x, rate = par),
cdf = function(x) pexp(x, rate = par),
qua = function(x) qexp(x, rate = par)
))()
$marg$disp$nor <- dat$disp |>
modelc(mean = mean(x), sd = sd(x)))() |>
(\(x) list(
(\(par) pdf = function(x) dnorm(x, mean=par[1], sd=par[2]),
cdf = function(x) pnorm(x, mean=par[1], sd=par[2]),
qua = function(x) qnorm(x, mean=par[1], sd=par[2])
))()
Zobrazenie
plot(model$marg$disp$lnor$cdf, from=0, to=500, col=4, ylab="CDF")
plot(model$marg$disp$exp$cdf, from=0, to=500, col=2, add=T)
plot(model$marg$disp$nor$cdf, from=0, to=500, col=3, add=T)
plot(model$marg$disp$emp$cdf, add=T)
legend("bottomright", legend = c("empirical", "log-normal", "exponential", "normal"), title = "distribution", col = c(1,4,2,3), lty=1, pch=c(19, NA, NA, NA))
Test dobrej zhody
#ks.test(x = dat$disp, y = model$marg$disp$lnor$cdf)
#goftest::cvm.test(x = dat$disp, null = model$marg$disp$lnor$cdf)
sapply(c("lnor", "exp", "nor"), function(x)
::cvm.test(dat$disp,
goftestnull = model$marg$disp[[x]]$cdf
c("statistic","p.value")] |> unlist()
)[|> round(3) )
lnor exp nor
statistic.omega2 0.118 0.541 0.149
p.value 0.507 0.031 0.394
Exponenciálne rozdelenie nie je vhodné na popis rozdelenia disp. Keby testom prešli obe, rozhodli by sme sa aj podľa výšky testovacej štatistiky, pretože predstavuje mieru vzdialenosti od empirickej CDF (pre KS test je to maximálny rozdiel, zatiaľčo pre CvM súčet štvorcov rozdielov).
<- list() dat01
Najprv vypočítame pseudo-pozorovania U=F(X) pomocou empirických marginálnych CDF.
$emp <- dat |>
dat01transform(disp = model$marg$disp$emp$cdf(disp),
mpg = model$marg$mpg$emp$cdf(mpg)
)# Kopula CDF
$cop$emp$cdf <- function(x) copula::C.n(x, X = dat01$emp)
model# model$cop$emp$cdf(c(0.5,1))
Zobrazenie pseudo-pozorovaní, čiže (prakticky) hustoty kopuly
plot(dat01$emp, xlab="F(disp)", ylab="F(mpg)", main="Empirická hustota kopule")
Pseudopozorovania pomocou parametrických marginálnych CDF. Na odhad kopuly môžeme použiť aj dáta z neparametrických marginálnych CDF. Parametrické však budeme potrebovať pri spätnej transformácii na výpočet kvantilov a strednej hodnoty.
$par <- dat |>
dat01transform(disp = model$marg$disp$lnor$cdf(disp),
mpg = model$marg$mpg$nor$cdf(mpg)
)
Kopula normálneho rozdelenia (Gaussovská)
$cop$nor <- copula::normalCopula(param = -0.5) |> # štartovacia kopula
model::fitCopula(data = as.matrix(dat01$par)) |> # odhad
copulaslot(name="copula") |> # extrakcia objektu
list(
(\(obj) obj = obj, # odhadnutý objekt
pdf = function(x) copula::dCopula(x, copula = obj),
cdf = function(x) copula::pCopula(x, copula = obj)
))()# model$cop$nor$obj@parameters # odhadnutý parameter kopule
# model$cop$nor$pdf(c(0.5,0.5)) # P(X<medianX, Y<medianY)
Preklopená (rotovaná) Gumbelova kopula
$cop$rgum <- copula::gumbelCopula(param = 2) |> # štartovacia kopula
model::rotCopula(flip = c(TRUE, FALSE)) |> # preklopenie cez u1=0.5
copula::fitCopula(data = as.matrix(dat01$par)) |> # odhad
copulaslot(name="copula") |> # extrakcia kopule
list(
(\(obj) obj = obj, # fitted object
pdf = function(x) copula::dCopula(x, copula = obj),
cdf = function(x) copula::pCopula(x, copula = obj)
))()
Preklopená (rotovaná) Claytonova kopula (MLE zlyhala, preto inverziou tau)
$cop$rcla <- copula::claytonCopula(param = 1) |> # štartovacia kopula
model::rotCopula(flip = c(FALSE, TRUE)) |> # preklopenie cez u2=0.5
copula::fitCopula(data = as.matrix(dat01$par), method="itau") |> # odhad
copulaslot(name="copula") |> # extrakcia kopule
list(
(\(obj) obj = obj, # fitted object
pdf = function(x) copula::dCopula(x, copula = obj),
cdf = function(x) copula::pCopula(x, copula = obj)
))()
simulácie z modelu
$cop$nor$obj |>
model::rCopula(n=100) |>
copulaplot(xlab="F(disp)", ylab="F(mpg)", main="Kopula normálneho rozdelenia")
$cop$rgum$obj |>
model::rCopula(n=100) |>
copulaplot(xlab="F(disp)", ylab="F(mpg)", main="Preklopená Gumbelova kopula")
$cop$rcla$obj |>
model::rCopula(n=100) |>
copulaplot(xlab="F(disp)", ylab="F(mpg)", main="Preklopená Claytonova kopula")
Nasleduje test dobrej zhody (Goodness-of-fit test). Metóda resamplingu simulation = "mult"
je rýchla, ale vhodná skôr pre väčšie súbory údajov. (Pre časovú náročnosť metódy “pb” je výsledok nasledujúceho kódu uvedený iba v komentári.)
# pre jednu kopulu:
# copula::gofCopula(model$cop$rcla$obj, as.matrix(dat), estim.method = "itau", simulation = "pb", ties=TRUE, verbose = T)[c("statistic","p.value")] |> sapply(unname)
# spolu:
mapply(FUN = function(kop, met)
::gofCopula(model$cop[[kop]]$obj,
copulaas.matrix(dat),
N = 10,
estim.method = met,
ties = TRUE, #set to FALSE or NA, if no ties are present
verbose = FALSE # whether to show progress bar
c("statistic","p.value")] |> sapply(unname), # format
)[kop = c("nor", "rgum", "rcla"),
met = c("mpl", "mpl", "itau")
|> round(3)
) # results for bootstrap method, N=1000 and met = c("mpl", "mpl", "itau"):
# nor rgum rcla
# statistic 0.0391 0.0275 0.0214
# p.value 0.153 0.214 0.504
Všetky kopuly sa zdajú byť vhodné na popis závislostnej štruktúry v náhodnom vektore (disp,mpg). Najlepšou vyzerá byť preklopená Claytonova archimedovská kopula.
$mix$obj <- copula::mvdc(
modelcopula = model$cop$rcla$obj,
margins = c("lnorm", "norm"),
paramMargins = list(
c(meanlog = log(mean(dat$disp)), sdlog=log(sd(dat$disp))),
"mom",]
fit_norm[
) )
Takéto zadávanie marg. je trochu nepohodlné, ešteže vytvorenie PDF/CDF z mvdc je ľahšie.
# copula::pMvdc(c(300,20), mvdc = model$mix$obj) # Error
# copula::pMvdc(cbind(c(300,301),c(20,21)), mvdc = model$mix$obj) # OK for nrow>1
$mix$pdf <- function(x) copula::dMvdc(x, model$mix$obj)
model$mix$cdf <- function(x) copula::pMvdc(x, model$mix$obj) model
My ho však nepoužijeme (pre problémy s výpočtom jedinej hodnoty i zobrazením hustoty). Namiesto toho, použijeme marginálne PDF/CDF (keď ich už máme explicitne definované) na zostavenie združeného rozdelenia podľa známych vzťahov:
\begin{split}
f(x_1,x_2) &= c(F_1(x_1),F_2(x_2)) f_1(x_1) f_2(x_2) \\
F(x_1,x_2) &= C(F_1(x_1),F_2(x_2))
\end{split}
Takto dokážeme využiť aj kopulu odhadnutú mimo balíka copula (napr. z balíkov VineCopula, HAC, acopula)
$mix <- with(model, {
model<- marg$disp$lnor$cdf
F1 <- marg$disp$lnor$pdf
f1 <- marg$mpg$nor$cdf
F2 <- marg$mpg$nor$pdf
f2 list(obj = mix$obj,
pdf = function(x) {
<- rbind(x)
x $rcla$pdf(cbind(F1(x[,1]), F2(x[,2]))) * f1(x[,1]) * f2(x[,2])
cop
},cdf = function(x) {
<- rbind(x)
x $rcla$cdf(cbind(F1(x[,1]), F2(x[,2])))
cop
}
)
})# model$mix$cdf(c(300,20))
Kontrolne poskladáme aj združené normálne rozdelenie
$mix.nor <- with(model, {
model<- marg$disp$nor$cdf
F1 <- marg$disp$nor$pdf
f1 <- marg$mpg$nor$cdf
F2 <- marg$mpg$nor$pdf
f2 list(
obj = copula::mvdc(
copula = cop$nor$obj,
margins = c("norm", "norm"),
paramMargins = list(
c(mean = mean(dat$disp), sd = sd(dat$disp)),
"mom",]
fit_norm[
)
),pdf = function(x) {
<- rbind(x) |> unname()
x $nor$pdf(cbind(F1(x[,1]), F2(x[,2]))) * f1(x[,1]) * f2(x[,2])
cop
},cdf = function(x) {
<- rbind(x) |> unname()
x $nor$cdf(cbind(F1(x[,1]), F2(x[,2])))
cop
}
)
})# model$mix.nor$cdf(c(300,20))
Nespojité empirické rozdelenie
<- table(cut(dat$disp, 5), cut(dat$mpg, 5))
pocetnosti2D ::hist3D(z = pocetnosti2D,
plot3Dcol = plot3D::ramp.col(c("lightblue","brown")),
border = "black",
xlab = "disp", ylab = "mpg", zlab = "freq", main = "3D histogram")
::image2D(z = pocetnosti2D,
plot3Dcol = plot3D::ramp.col(c("lightblue","brown")),
xlab = "disp", ylab = "mpg", main = "Mozaikový graf")
Jadrovo vyhladené empirické rozdelenie
plot(model$smoo$pdf,,TRUE)
rect(xleft=0,ybottom=0,xright=300,ytop=20, lty="dashed")
plot(model$smoo$pdf,TRUE)
plot(model$marg$disp$lnor$pdf, from = 0, to = max(dat$disp),
xlab="disp", ylab="hustota")
lines(density(dat$disp), lty="dashed")
legend("topright", c("log-normal","non-param."), lty=c(1,2))
plot(model$marg$mpg$nor$pdf, from = 0, to = max(dat$mpg),
xlab="mpg", ylab="")
lines(density(dat$mpg), lty="dashed")
legend("topright", c("normal","non-par."), lty=c(1,2))
::contourplot2(model$cop$rcla$obj, FUN = copula::dCopula,
copularegion=F, labels=F, n.grid=100, cuts = 100,
main = "hustota kopuly")
::wireframe2(model$cop$rcla$obj, FUN = copula::dCopula, region=F,
copulazlab = "hustota")
#z neznámeho dôvodu kreslí nezmysly:
#copula::contourplot2(model$mix$obj, FUN = copula::dMvdc,
# xlim = c(0,300), ylim = c(0,40),
# region=F, labels=F, n.grid=100, cuts = 100)
# graf pomocou základnej funkcie contour()
#local({
# n <- 100
# X <- seq_range(dat$disp,length = n)
# Y <- seq_range(dat$mpg,length = n)
# Z <- outer(X, Y, FUN = function(x,y) model$mix$pdf(cbind(x,y)))
# contour(X, Y, Z, drawlabels = FALSE,
# xlab = "disp", ylab="mpg", main="hustota rozdelenia")
#})
<- expand.grid(disp = seq_range(dat$disp,length = 100),
tmp mpg = seq_range(dat$mpg,length = 100)) |>
transform(density = model$mix$pdf(cbind(disp,mpg)))
# graf pomocou základného balíku lattice:
# lattice::contourplot(density ~ disp + mpg, tmp, labels=FALSE,
# main="hustota rozdelenia (kopula + marginálie)")
ggplot(tmp) + aes(x = disp, y = mpg) + geom_contour(aes(z = density)) +
ggtitle("hustota rozdelenia (kopula + marginálie)")
Pr(X \leq 300, Y \leq 20)
c("emp", "norm", "smoo", "mix", "mix.nor")] |>
model[sapply(function(x) x$cdf(c(300,20))) |>
round(4)
emp norm smoo mix mix.nor
0.2188 0.2244 0.2617 0.2599 0.2137
Rozdiel medzi “nor” a “mix.nor” (oboje predstavujú združené normálne rozdelenie) je spôsobený odlišnými metódami odhadu.
Pr(0 < X \leq 300, 0 < Y \leq 20)
with(model$emp, {
<- c(0,300)
x <- c(0,20)
y cdf(c(x[2],y[2])) - cdf(c(x[1],y[2])) - cdf(c(x[2],y[1])) + cdf(c(x[1],y[1]))
})
[1] 0.21875
Vrstevnicový graf
expand.grid(disp = seq(0, max(dat$disp)*1.3, length.out = 100),
mpg = seq(0, max(dat$mpg)*1.3, length.out = 100)
|>
) transform(CDF = model$mix$cdf(cbind(disp,mpg))) |>
ggplot() + aes(x = disp, y = mpg) +
# metR::geom_contour2(aes(z = CDF, label = stat(level))) + # s popisom vrstevníc
geom_contour(aes(z = CDF, colour = after_stat(level))) +
geom_point(x = 300, y = 20, color = "red") +
ggtitle(" CDF rozdelenia (kopula + marginálie)")
# pomocou lattice:
# lattice::contourplot(x = CDF ~ disp + mpg, at=c(0.1, 0.22, 0.5,0.7,0.8,0.9,0.95),
# main=" CDF (kopula + marginálie)")
podmienená CDF:
$smoo$cdf_disp300 <- dat |>
modelas.matrix() |>
::cdfc.cks(a = c(0,0), conditions = c(disp=300)) # F(mpg|disp=300) probhat
F(mpg=20|disp=300)
$smoo$cdf_disp300(20) model
[1] 0.8210729
znázornenie:
plot(model$smoo$cdf_disp300,
main = "Pr(mpg < x | disp = 300)", xlab="mpg", ylab="CDFc")
abline(v=20, h = model$smoo$cdf_disp300(20), lty="dashed")
podmienená PDF
$norm$pdfc <- function(x, cond) {
model<- match(names(cond), names(dat))
ind <- unname(cond)
cond <- matrix(nrow=length(x), ncol=2)
mat 3-ind] <- x
mat[,<- cond
mat[,ind] $norm$pdf(mat)/dnorm(cond, mean=mu[ind], sd=sqrt(Sigma[ind,ind]))
model
} # f(mpg=20|disp=300)
# model$norm$pdfc(20, cond = c(disp = 300))
# pre porovnanie:
# probhat::pdfc.cks(as.matrix(dat), a = c(0,0), conditions = c(disp=300))(20)
data.frame(mpg = seq_range(dat$mpg, 100)) |>
transform(PDFc = model$norm$pdfc(mpg, cond=c(disp=300))) |>
plot(type="l", main = "f(mpg | disp = 300)")
abline(v = 20, lty="dashed")
podmienená CDF
$norm$cdfc <- Vectorize(function(x, cond) {
model<- 3 - match(names(cond), names(dat)) # 3 = p+1
ind <- mu[ind] - sqrt(Sigma[ind,ind])*4
lo integrate(f = model$norm$pdfc, lower = lo, upper = x, cond = cond)$value # if lower=-Inf, then unexpected behavior occurs, e.g. model$norm$cdfc(70, cond = c(disp = 300)) gives zero
vectorize.args = "x") },
F(mpg=20|disp=300)
$norm$cdfc(20, cond = c(disp = 300)) model
[1] 0.8063011
podmienená PDF
$mix$pdfc <- function(x, cond) {
model<- names(cond)
condname <- match(condname, names(dat))
ind <- unname(cond)
cond <- matrix(nrow=length(x), ncol=2)
mat 3-ind] <- x
mat[,<- cond
mat[,ind] $mix$pdf(mat)/model$marg[[condname]][[c("lnor","nor")[ind]]]$pdf(cond)
model
}#model$mix$pdfc(20, cond = c(disp = 300))
podmienená CDF
$mix$cdfc <- Vectorize(function(x, cond) {
model<- 3 - match(names(cond), names(dat)) # 3 = p+1
ind <- mu[ind] - sqrt(Sigma[ind,ind])*4
lo integrate(f = model$mix$pdfc, lower = lo, upper = x, cond = cond)$value # if lower=-Inf, then unexpected behavior occurs, e.g. model$norm$cdfc(70, cond = c(disp = 300)) gives zero
vectorize.args = "x") },
F(mpg=20|disp=300)
$mix$cdfc(20, cond = c(disp = 300)) model
[1] 0.9584723
podmienená kvantilová funkcia:
$smoo$icdf_disp300 <- dat |>
modelas.matrix() |>
::qfc.cks(a = c(0,0), conditions = c(disp=300)) # F(mpg|disp=300) probhat
kvantil
$smoo$icdf_disp300(0.8210729) model
[1] 19.99966
podmienená kvantilová funkcia F^{-1}(p|X=x)
$norm$icdfc <- function(p, cond) {
model<- 3 - match(names(cond), names(dat)) # 3 = p+1
ind <- mu[ind] + c(-1,1)*sqrt(Sigma[ind,ind])*3
int sapply(p, function(p) uniroot(function(x) model$norm$cdfc(x, cond) - p, interval = int, extendInt = "yes")$root)
}
kontrolný výpočet a podmienený medián
c(0.8063011, 0.5) |>
data.frame(prob = x, quant = model$norm$icdfc(x, c(disp=300))))() (\(x)
prob quant
1 0.8063011 20.0000
2 0.5000000 17.2353
$mix$icdfc <- function(p, cond) {
model<- 3 - match(names(cond), names(dat)) # 3 = p+1
ind <- mu[ind] + c(-1,1)*sqrt(Sigma[ind,ind])*4
int sapply(p, function(p) uniroot(function(x) model$mix$cdfc(x, cond) - p, interval = int, extendInt = "yes")$root)
}
kontrolný výpočet a podmienené kvantily (medián, hranice predikčného intervalu)
c(0.9584249, 0.5, 0.1, 0.9) |>
data.frame(prob = x, quant = model$mix$icdfc(x, c(disp=300))))() (\(x)
prob quant
1 0.9584249 19.99879
2 0.5000000 15.77874
3 0.1000000 11.05249
4 0.9000000 18.97367
E[mpg|disp=300]
funkcia
$smoo$expc <- function(cond) {
model<- 3 - match(names(cond), names(dat)) # 3 = p+1
ind <- mu[ind] + 4*sqrt(Sigma[ind,ind])
up integrate(f = function(x) x * probhat::pdfc.cks(as.matrix(dat), a = c(0,0), conditions = cond)(x),
lower = 0,
upper = up)$value
}
výpočet
$smoo$expc(c(disp=300)) model
[1] 16.4832
funkcia
$norm$expc <- function(cond) {
model<- 3 - match(names(cond), names(dat)) # 3 = p+1
ind <- mu[ind] + c(-1,1)*sqrt(Sigma[ind,ind])*4
int integrate(f = function(x) x * model$norm$pdfc(x, cond),
lower = int[1],
upper = int[2])$value
}
výpočet
$norm$expc(c(disp=300)) model
[1] 17.23532
# kontrola: lm(mpg ~ disp, dat) |> predict(data.frame(disp=300))
funkcia
$mix$expc <- function(cond) {
model<- 3 - match(names(cond), names(dat)) # 3 = p+1
ind <- mu[ind] + c(-1,1)*sqrt(Sigma[ind,ind])*4
int integrate(f = function(x) x * model$mix$pdfc(x, cond),
lower = int[1],
upper = int[2])$value
}
výpočet
$mix$expc(c(disp=300)) model
[1] 15.32598
<- c(mean=model$mix$expc(c(disp=300)),
tmp $mix$icdfc(c(med=0.5, q10=0.1, q90=0.9), c(disp=300))
model|>
) round(2) |> print()
mean med q10 q90
15.33 15.78 11.05 18.97
data.frame(mpg = seq(0, max(dat$mpg), length.out = 100)) |>
transform(hustota = model$mix$pdfc(mpg, cond = c(disp = 300))) |>
ggplot() + aes(x = mpg) + geom_line(aes(y = hustota)) +
scale_x_continuous(breaks = c("0"=0, "10"=10, tmp, "20"=20, "30"=30),
minor_breaks = NULL) +
theme(axis.text.x = element_text(angle=45)) +
ggtitle("Podmienená hustota mpg pre disp = 300")
Vektorizovana funkcia podmienenej hustoty, kde prvá súradnica x je podmieňujúca a druhá súradnica je podmieňovaná premenná:
$mix$pdf2.1 <- function(x) {
model<- rbind(x)
x $mix$pdf(x)/model$marg$disp$lnor$pdf(x[,1])
model }
Vektorizovaná funkcia podmienenej strednej hodnoty, kde argumentom je samozrejme podmieňujúca premenná.
$mix$exp2.1 <- Vectorize(function(x) {
model<- mu[2] + c(-1,1)*sqrt(Sigma[2,2])*4
int integrate(f = function(y) y * model$mix$pdfc(y, cond=c(disp=x)),
lower = int[1],
upper = int[2])$value
})
Podmienená pravdepodobnosť pre zvolené úrovne disp a podmienená stredná hodnota (prerušovaná krivka):
expand.grid(disp = c(100, 200, 300, 400),
mpg = seq(5, 35, 0.1)) |>
transform(density = model$mix$pdf2.1(cbind(disp, mpg))) |>
ggplot() + aes(x = mpg, y = disp) +
geom_point(data = dat) +
geom_line(data = data.frame(disp = seq(80,470,10)) |>
transform(mpg = model$mix$exp2.1(disp)),
linetype = 2) +
::geom_ridgeline(aes(height = density, group = disp),
ggridgesstat="identity", scale=400, alpha=0.5) +
coord_flip() +
ggtitle("Podmienená stredná hodnota a hustota dojazdu pre zvolené úrovne objemu")