| Title: | Hidden Markov Models and Shifted Compound Poisson-Gamma Renewal Process |
|---|---|
| Description: | Provides functions to define, simulate and fit hidden Markov models, hidden semi-Markov models, and their time-varying versions, to incompletely observed point process records. Such data arise when some events of an underlying point process are not recorded or are otherwise missing. The models treat the number of missing events between each pair of consecutively observed events of a point process record as a hidden process. The number of missing events may be fixed or modelled as a random variable whose distribution can vary over time. When the number of missing events is fixed, the observed event times can be modelled as a compound gamma renewal process. When it is random, the observed process is represented by a shifted compound Poisson-gamma renewal process, which may also depend on time, leading to a time-dependent shifted compound Poisson-gamma renewal process. These modelling frameworks are described in detail in Shahzadi, Wang, Parry and Bebbington (2023) <doi:10.1007/s10463-022-00843-5> and Shahzadi, Wang, Parry and Bebbington (2026) <doi:10.1007/s11634-025-00632-x>. The model parameters are estimated through direct nonlinear numerical optimization of the corresponding likelihood function, and each fit reports whether the change points of its time-dependent components are identified by the data. The package also provides methods for assessing model adequacy through residual analysis. In addition, it calculates and plots the most probable sequences of hidden states, allowing users to examine changes in the underlying missing-event process over time. |
| Authors: | Amina Shahzadi [aut, cre], Ting Wang [aut] |
| Maintainer: | Amina Shahzadi <[email protected]> |
| License: | GPL-3 |
| Version: | 1.0.0 |
| Built: | 2026-10-28 19:17:50 UTC |
| Source: | https://github.com/cran/HMMscpg |
Tools for modelling incomplete geological point process records (such as volcanic eruptions or earthquakes) using hidden Markov models (HMMs) whose state-dependent observation distributions are gamma, shifted compound Poisson-gamma (SCPG), or time-dependent SCPG (TSCPG) renewal processes. The package implements four families of models: standard HMMs, inhomogeneous HMMs (IHMMs), hidden semi-Markov models (HSMMs), and inhomogeneous hidden semi-Markov models (IHSMMs), following Shahzadi et al. (2023, 2026).
Consider a point process with event times
at jump points . A renewal process is defined by interevent
times , , which are
independently and identically distributed, with . Geological
records of random events can be modelled using these processes
(Wang et al., 2022). Missing events are common in geophysical point
process records, and incompleteness varies over time. Given the unknown
nature of missing events, Shahzadi et al.(2023, 2026) proposed several
types of HMMs in which the unknown number of missing events between each
pair of consecutively observed events is characterized by the distribution
of the observed process, the underlying Markov chain, or both.
The package employs four types of HMMs, distinguished by the underlying discrete-time Markov chain (MC), which is described by an initial distribution, a transition probability matrix (TPM), and implicit or explicit state durations. The four types HMMs based on underlying hidden Markov chain are:
has a homogeneous Markov chain (MC) with a time-independent transition probability matrix.
has an inhomogeneous Markov chain (IMC) with a time-dependent transition probability matrix.
has a semi-Markov chain (SMC) with a zero-diagonal transition probability matrix and explicit state durations, following the Markov property at transition times only.
has an inhomogeneous semi-Markov chain (ISMC) with a zero-diagonal transition probability matrix and time-dependent explicit state durations, following the Markov property at transition times only.
For an observation sequence and hidden state sequence
, , with states, states are defined
as:
denotes completeness: no missing events between each pair of consecutively observed events.
represent incompleteness: the number of missing events between each consecutive observed pair.
Each HMM type is further categorized by its observed process as follows:
In State 1 the observed process follows a gamma renewal process;
the observed process may follow
a sum of independent gamma renewal processes when is
fixed, or
an SCPG renewal process when is shifted-Poisson
distributed, or
a TSCPG renewal process when is time-dependent.
The table below lists all types of HMMs considered in this package,
according to the underlying Markov chain (MC) and the renewal process
(RP) as the observed process (OP). In all models, State 1 represents no
missing event between each consecutively observed pair; States
represent incompleteness, with the number of missing
events between each consecutive observed pair as given in the
last column.
| Type of HMM | Type of MC | OP | N |
| HMM with gamma RP | MC | gamma RP | Fixed |
| HMM with SCPG RP | MC | SCPG RP | Shifted Poisson distributed |
| HMM with TSCPG RP | MC | TSCPG RP | Time-dependent shifted Poisson distributed |
| IHMM with gamma RP | IMC | gamma RP | Fixed |
| IHMM with SCPG RP | IMC | SCPG RP | Shifted Poisson distributed |
| IHMM with TSCPG RP | IMC | TSCPG RP | Time-dependent shifted Poisson distributed |
| HSMM with gamma RP | SMC | gamma RP | Fixed |
| HSMM with SCPG RP | SMC | SCPG RP | Shifted Poisson distributed |
| HSMM with TSCPG RP | SMC | TSCPG RP | Time-dependent shifted Poisson distributed |
| IHSMM with gamma RP | ISMC | gamma RP | Fixed |
| IHSMM with SCPG RP | ISMC | SCPG RP | Shifted Poisson distributed |
| IHSMM with TSCPG RP | ISMC | TSCPG RP | Time-dependent shifted Poisson distributed |
Here, denotes the number of missing events between each consecutive observed pair in a
point process record.
Maintainer: Amina Shahzadi [email protected]
Authors:
Amina Shahzadi [email protected]
Ting Wang [email protected]
Shahzadi A, Wang T, Parry M, Bebbington M (2023). “Inhomogeneous hidden semi-Markov models for incompletely observed point processes.” Annals of Institute Statistical Mathematics, 75, 253-280. doi:10.1007/s10463-022-00843-5.
Shahzadi A, Wang T, Parry M, Bebbington M (2026). “Modelling time-inhomogeneous incomplete records of point processes using variants of hidden Markov models.” Advances in Data Analysis and Classification, 20, 663-691. doi:10.1007/s11634-025-00632-x.
Wang T, Bebbington M, Cronin S, Carman J (2022). “Forecasting Eruptions at Poorly Known Volcanoes Using Analogs and Multivariate Renewal Processes.” Geophysical Research Letters, 49(12), e2021GL096715. doi:10.1029/2021GL096715.
Evaluates the density of the shifted compound Poisson-gamma (SCPG) distribution, of its time-dependent version (TSCPG), or of a gamma distribution with a fixed number of missing events.
dscpg( x, rate, shape, scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, log = FALSE, WBsum.method = "direct.evaluation", WBsum.tol = 1e-12, max.direct.terms = 2000L )dscpg( x, rate, shape, scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, log = FALSE, WBsum.method = "direct.evaluation", WBsum.tol = 1e-12, max.direct.terms = 2000L )
x |
A vector of positive, finite interevent times. For the TSCPG
( |
rate |
The number of missing events: for the SCPG, the Poisson mean
|
shape |
The gamma shape parameter |
scale |
The gamma scale parameter |
rate.fix |
Logical. If |
shape.fix |
Logical; used only by |
time.scpg |
Logical. If |
log |
Logical; if |
WBsum.method |
The method used by |
WBsum.tol |
The tolerance |
max.direct.terms |
Passed to |
The model. In a complete record the interevent times
are independent gamma variables with shape and scale
. If events are missing between two observed events, the
observed interevent time is the sum of of them,
Three cases are available.
Fixed number of missing events (rate.fix = TRUE):
, so is gamma with shape and
scale ; means that no event is missing.
SCPG (the default): at least one event is missing and
is shifted Poisson, for , so on
average events are missing. The density is
where
is the series computed by WBsum. The SCPG is the
continuous part of the compound Poisson-gamma distribution of the
Tweedie family (Tweedie, 1984; Smyth and Jorgensen, 2002), shifted so
that at least one event is missing.
TSCPG (time.scpg = TRUE): the Poisson mean changes
along the record as a logistic function of the last occurrence time
(),
It decreases from at the start of the record
(about when is large) towards . It is
halfway, , at the inflection time
, and sets the speed of the change: 80 per
cent of it takes place within of
. The density of is the SCPG density with
in place of , given the preceding
observations, so the order of x matters.
Choosing WBsum.method. The cost of
depends on , which is about
the most probable number of missing events in the interval; the three
methods are described in WBsum. The default
"direct.evaluation" is accurate for every and fast for the
values met in practice: is at most a few hundred in typical
records, and 6.5 at the estimates of the fit.scpg example.
Use "direct.asymptotic" when dscpg stops with the error
"The direct Wright-series evaluation is refused for arguments this large",
which happens only when , or to save time when
, computed from the largest , exceeds about .
Such values arise when is very long compared with , or
when is very large. They also arise during
fit.scpg, whose optimizer may try extreme trial values of the
shape and scale even though is small at the estimates. A trial
value with any is refused at once and treated as
infeasible, but one with many values of between about
and takes up to seconds per observation. If a fit is slow, use
"direct.asymptotic": it gives the same estimates.
"asymptotic.expansion" alone is useful only for checking, since it
fails for small .
The script verify_dscpg.R in the examples directory of the
package reproduces the numbers stated here; run it in the console with
f <- system.file("examples", "verify_dscpg.R",
package = "HMMscpg")
source(f, echo = TRUE)
A numeric vector of densities, or log densities when
log = TRUE, with the same length and names as x.
Tweedie MCK (1984). “An index which distinguishes between some important exponential families.” In Statistics: Applications and New Directions. Proceedings of the Indian Statistical Institute Golden Jubilee International Conference, 579–604.
Smyth GK, Jørgensen B (2002). “Fitting Tweedie's compound Poisson model to insurance claims data: dispersion modelling.” ASTIN Bulletin, 32(1), 143-157.
Smyth GK, Jorgensen B (2002). “Fitting Tweedie's compound Poisson model to insurance claims data: Dispersion modelling.” ASTIN Bulletin, 32(1), 143-157. doi:10.2143/AST.32.1.1020.
Wright EM (1935). “The asymptotic expansion of the generalized hypergeometric function.” Journal of the London Mathematical Society, 10(4), 286–293.
Shahzadi A, Wang T, Parry M, Bebbington M (2026). “Modelling time-inhomogeneous incomplete records of point processes using variants of hidden Markov models.” Advances in Data Analysis and Classification, 20, 663-691. doi:10.1007/s11634-025-00632-x.
# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # PDF of an SCPG distribution pdf_scpg <- dscpg(x_scpg, rate, shape, scale, time.scpg=FALSE, WBsum.method="direct.evaluation") hist(x_scpg, probability = TRUE) # sorted, so that the density is drawn as a curve o <- order(x_scpg) lines(x_scpg[o], pdf_scpg[o], col="blue") # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg) # PDF of a TSCPG distribution pdf_tscpg <- dscpg(x_tscpg, t_rate, shape, scale, time.scpg=TRUE, WBsum.method="direct.evaluation") # Each x_t has its own density, at lambda(t) of its occurrence time, so the # densities are shown as points rather than as one curve hist(x_tscpg, probability = TRUE) points(x_tscpg, pdf_tscpg, col="blue", pch=20)# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # PDF of an SCPG distribution pdf_scpg <- dscpg(x_scpg, rate, shape, scale, time.scpg=FALSE, WBsum.method="direct.evaluation") hist(x_scpg, probability = TRUE) # sorted, so that the density is drawn as a curve o <- order(x_scpg) lines(x_scpg[o], pdf_scpg[o], col="blue") # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg) # PDF of a TSCPG distribution pdf_tscpg <- dscpg(x_tscpg, t_rate, shape, scale, time.scpg=TRUE, WBsum.method="direct.evaluation") # Each x_t has its own density, at lambda(t) of its occurrence time, so the # densities are shown as points rather than as one curve hist(x_tscpg, probability = TRUE) points(x_tscpg, pdf_tscpg, col="blue", pch=20)
Estimates the parameters of an HMM created by hmm.scpg, of
class hmm.gamma, hmm.scpg or hmm.tscpg, by
maximum likelihood.
fit.hmm.scpg( hmmobj, method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )fit.hmm.scpg( hmmobj, method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )
hmmobj |
An object created by |
method |
Optimization method passed to |
maxit |
Maximum number of iterations passed to the |
reltol |
Relative convergence tolerance passed to the |
negative |
Logical. If |
Likelihood. The likelihood sums over all hidden state sequences,
and is computed by the forward algorithm (Baum et al., 1970),
in operations. The forward
variables are rescaled to sum to one at each step, on the log scale, and
is the sum of the logarithms of the scale factors (Zucchini et
al., 2016).
Estimation. is maximized with
optim rather than by the EM algorithm (Dempster et
al., 1977), since the SCPG densities give no closed-form M-step. The
parameters are mapped to unconstrained working parameters: the initial
distribution by logits relative to State , each row of the transition
matrix by logits relative to its diagonal element , and the
observation parameters as in fit.scpg, with the same bounds on
the shape, the Poisson means and, for the TSCPG, , where
. With stationary = TRUE the
initial distribution is computed from the transition matrix and not
estimated. The optimizer may stop at a local maximum, so several starting
values should be tried and the convergence code checked. The densities are
computed with scpg.par$WBsum.method; the default suits almost all
records, and if a fit is slow "direct.asymptotic" gives the same
estimates faster (see dscpg).
Inflection diagnostics (TSCPG). In State the Poisson mean
falls from about to , and the
central 80 per cent of this change takes place within of the
inflection time . The record observes only
at , and only through the observations
that the model attributes to State . The data can therefore locate
only if the change falls inside and enough
observations of State fall within it; otherwise the likelihood is
nearly flat in . The fitted object contains the component
inflection (see Value), and a warning is given when, for some State
,
less than half of the change of takes place on
(change below 0.5). This covers every
outside , and a that
is almost constant over the record; or
the expected number of observations of State within the
central 80 per cent of the change is below 10.
These limits come from simulations of the TSCPG with known states (see
fit.scpg); since the states are hidden here, a fit that meets
them may still locate poorly. After a warning, report
as not identified and compare the model with SCPG states
(time.scpg = FALSE) by AIC. The script verify_fit_hmm_scpg.R
in the examples directory of the package reproduces the statements
of this help page; run it in the console with
f <- system.file("examples", "verify_fit_hmm_scpg.R",
package = "HMMscpg")
source(f, echo = TRUE)
Model selection. The likelihood increases with each state added,
so the number of states and the observation process are chosen by
(Akaike, 1974), together
with the decoded path (vip.hmm.scpg) and the residual process
(sp.hmm.scpg), as recommended by Pohle et al. (2017).
An object of the same class as hmmobj: a list with
xNULL; the data are not kept, and must be attached
as x before vip.hmm.scpg or
sp.hmm.scpg is used.
mc.par, scpg.par
the estimated parameters, in the
form of hmm.scpg, with the settings unchanged.
logLikthe maximized log-likelihood.
nparamthe number of estimated parameters.
convergence, message, counts
as returned by
optim; convergence = 0 indicates
successful convergence.
objective.errorNULL, or the last reason why the
log-likelihood could not be evaluated at a trial value.
inflectionpresent only when time.scpg = TRUE: a data
frame with the inflection diagnostics of Details, one row per State
:
component, label
"lambda" and
"state j".
rate, intercept
the estimates of and
.
inflectionthe inflection time .
first, last
and
: the position of relative to
0 and to , in units of . It lies inside
when first last.
changethe fraction, between 0 and 1, of the change of
that takes place on ,
with
; the first limit fails when it is
below 0.5.
nthe expected number of observations in State
, .
in.bandthe part of n from the whose
lies within the central 80 per cent of the change,
.
rarealways NA here.
flagthe limits that are not met, or "".
Baum LE, Petrie T, Soules G, Weiss N (1970). “A maximization technique occurring in the statistical analysis of probabilistic functions of Markov chains.” The Annals of Mathematical Statistics, 41(1), 164-171. doi:10.1214/aoms/1177697196.
Zucchini W, MacDonald IL, Langrock R (2016). Hidden Markov Models for Time Series: An Introduction Using R, 2 edition. CRC Press, Boca Raton.
Dempster AP, Laird NM, Rubin DB (1977). “Maximum likelihood from incomplete data via the EM algorithm.” Journal of the Royal Statistical Society, Series B, 39(1), 1-22. doi:10.1111/j.2517-6161.1977.tb01600.x.
Akaike H (1974). “A new look at the statistical model identification.” IEEE Transactions on Automatic Control, 19(6), 716-723. doi:10.1109/TAC.1974.1100705.
Pohle J, Langrock R, van Beest FM, Schmidt NM (2017). “Selecting the number of states in hidden Markov models: pragmatic solutions illustrated using animal movement.” Journal of Agricultural, Biological and Environmental Statistics, 22(3), 270-293. doi:10.1007/s13253-017-0283-8.
# ========================================================== # An example of a 2-state HMM with a TSCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.3 at the start of the record towards K = 0.5, around # the inflection time P/R = 300 of the last occurrence time h_{t-1}. The # hidden chain is homogeneous, so only lambda_2(t) changes along the record. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 5 # M rate[3, ] <- 0.01 # R rate[4, ] <- 3 # P: inflection time P/R = 300 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with TSCPG distribution obj_hmm2 <- hmm.scpg(x = NULL, mc.par, scpg.par) class(obj_hmm2) # Simulating a 2-state HMM with TSCPG distribution sim_hmm2 <- sim.hmm.scpg(obj_hmm2, nsim = 200, seed = 1) str(sim_hmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hmm2$x[-200]), h_T = sum(sim_hmm2$x)) # Fitting a 2-state HMM with TSCPG distributions # (the parameters of obj_hmm2 are the starting values) fit_hmm2 <- fit.hmm.scpg(sim_hmm2) # transition matrix (true rows 0.9, 0.1 and 0.2, 0.8) fit_hmm2$mc.par$tpm fit_hmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_hmm2$scpg.par$scale # true 1 fit_hmm2$logLik # Inflection diagnostics of the fitted TSCPG rate lambda_2(t), whose true # inflection time is 300. The change lies inside the record (first > 0 > # last), almost all of it takes place on [0, h_{T-1}] (change >= 0.5), and # about 35 expected observations of State 2 lie within its central 80 per # cent (in.band >= 10), so no warning is given and the inflection time P/R, # estimated at about 300, is identified. fit_hmm2$inflection # ======================================================== # An example of a 3-state HMM with a TSCPG renewal process # ======================================================== # Fitting this 3-state model takes about 30 seconds on a laptop (the # 2-state model above takes about 4 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.50, 0.30, 0.20, 0.25, 0.50, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(1, 1) # K rate[2, ] <- c(1.5, 2.5) # M rate[3, ] <- c(0.02, 0.015) # R rate[4, ] <- c(3, 3) # P: inflection times P/R = 150 and 200 shape <- 1 scale <- 1.7 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with TSCPG distribution obj_hmm2_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) # Simulating a 3-state HMM with TSCPG distribution sim_hmm2_m3 <- sim.hmm.scpg(obj_hmm2_m3, nsim=100, seed=9) # Fitting a 3-state HMM with TSCPG distributions # The fit takes about 30 seconds, so it is wrapped in donttest. fit_hmm2_m3 <- fit.hmm.scpg(sim_hmm2_m3) print(fit_hmm2_m3) # Inflection diagnostics of the fitted TSCPG rates lambda_2(t) and # lambda_3(t) (true inflection times 150 and 200). With 100 observations # both are flagged here, and the fit warns: lambda_2(t) is fitted as almost # constant on the record (its inflection time, 413, lies just after # h_{T-1} = 402, and only 0.2 per cent of its change takes place on # [0, h_{T-1}]), and lambda_3(t) as an abrupt step at about 99 with no # expected observation of State 3 within it. Neither inflection time is # identified; the homogeneous model (time.scpg = FALSE) may be compared by # AIC. fit_hmm2_m3$inflection# ========================================================== # An example of a 2-state HMM with a TSCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.3 at the start of the record towards K = 0.5, around # the inflection time P/R = 300 of the last occurrence time h_{t-1}. The # hidden chain is homogeneous, so only lambda_2(t) changes along the record. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 5 # M rate[3, ] <- 0.01 # R rate[4, ] <- 3 # P: inflection time P/R = 300 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with TSCPG distribution obj_hmm2 <- hmm.scpg(x = NULL, mc.par, scpg.par) class(obj_hmm2) # Simulating a 2-state HMM with TSCPG distribution sim_hmm2 <- sim.hmm.scpg(obj_hmm2, nsim = 200, seed = 1) str(sim_hmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hmm2$x[-200]), h_T = sum(sim_hmm2$x)) # Fitting a 2-state HMM with TSCPG distributions # (the parameters of obj_hmm2 are the starting values) fit_hmm2 <- fit.hmm.scpg(sim_hmm2) # transition matrix (true rows 0.9, 0.1 and 0.2, 0.8) fit_hmm2$mc.par$tpm fit_hmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_hmm2$scpg.par$scale # true 1 fit_hmm2$logLik # Inflection diagnostics of the fitted TSCPG rate lambda_2(t), whose true # inflection time is 300. The change lies inside the record (first > 0 > # last), almost all of it takes place on [0, h_{T-1}] (change >= 0.5), and # about 35 expected observations of State 2 lie within its central 80 per # cent (in.band >= 10), so no warning is given and the inflection time P/R, # estimated at about 300, is identified. fit_hmm2$inflection # ======================================================== # An example of a 3-state HMM with a TSCPG renewal process # ======================================================== # Fitting this 3-state model takes about 30 seconds on a laptop (the # 2-state model above takes about 4 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.50, 0.30, 0.20, 0.25, 0.50, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(1, 1) # K rate[2, ] <- c(1.5, 2.5) # M rate[3, ] <- c(0.02, 0.015) # R rate[4, ] <- c(3, 3) # P: inflection times P/R = 150 and 200 shape <- 1 scale <- 1.7 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with TSCPG distribution obj_hmm2_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) # Simulating a 3-state HMM with TSCPG distribution sim_hmm2_m3 <- sim.hmm.scpg(obj_hmm2_m3, nsim=100, seed=9) # Fitting a 3-state HMM with TSCPG distributions # The fit takes about 30 seconds, so it is wrapped in donttest. fit_hmm2_m3 <- fit.hmm.scpg(sim_hmm2_m3) print(fit_hmm2_m3) # Inflection diagnostics of the fitted TSCPG rates lambda_2(t) and # lambda_3(t) (true inflection times 150 and 200). With 100 observations # both are flagged here, and the fit warns: lambda_2(t) is fitted as almost # constant on the record (its inflection time, 413, lies just after # h_{T-1} = 402, and only 0.2 per cent of its change takes place on # [0, h_{T-1}]), and lambda_3(t) as an abrupt step at about 99 with no # expected observation of State 3 within it. Neither inflection time is # identified; the homogeneous model (time.scpg = FALSE) may be compared by # AIC. fit_hmm2_m3$inflection
Estimates the parameters of an HSMM with class hsmm.gamma, hsmm.scpg
and hsmm.tscpg as typically returned by hsmm.scpg
using direct nonlinear optimization.
fit.hsmm.scpg( hsmmobj, method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )fit.hsmm.scpg( hsmmobj, method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )
hsmmobj |
is a model object with class |
method |
Optimization method passed to |
maxit |
Maximum number of iterations passed to the |
reltol |
Relative convergence tolerance passed to the |
negative |
is a logical argument for negative log-likelihood. Default is |
Likelihood. The likelihood of a right-censored HSMM is evaluated by the forward
algorithm of Guedon (2003). Let
denote the joint state-dependent observation probability of a visit to State
of length ending at time , and let
denote the probability that a visit to State commences at time
, with . The forward variable
, the th observation being the last of a visit to State
, satisfies
The sojourn time in the last visited state is right-censored at ,
only its minimum being known, so the sojourn mass function is replaced by
the survival function ,
and . Treating the final sojourn
as complete would bias the estimated expected sojourn times downwards.
Because the forward variable is indexed by state and elapsed sojourn
jointly, the recursion is of order rather than the
of an HMM, a visit being admissible at any length up to
. The observation products are accumulated by the recursion
of Mitchell and Jamieson (1993).
Scaling is embedded in the recursion at each time step and the logarithms
of the scale factors accumulated.
Estimation. The likelihood is maximized by direct numerical
minimization of the negative log-likelihood using optim
over working parameters defined on the real line. Each row of the
zero-diagonal transition probability matrix is represented by multinomial
logits over its transition probabilities, which for
leaves the embedded chain fully determined and contributing no parameters;
the sojourn parameters are represented by logarithms, or by scaled logits
where dur.lb and dur.ub are supplied; and the observation
parameters are transformed as in fit.scpg. The forward
recursion is evaluated by compiled code. The fitted object is returned on the
natural scale and is suitable for vip.hsmm.scpg and
sp.hsmm.scpg.
Inflection diagnostics (TSCPG). These apply when the observation
process is a TSCPG (time.scpg = TRUE); otherwise the model has no
time-dependent component and inflection is NULL. In each state
the rate
changes
around the inflection time . Over the record the
last occurrence time runs from () to
(), so
is observed only on , and
is identified only when this interval covers the change and
enough observations of state fall within it. Writing
, the sensitivity of to
is at most , so observations more than a
few multiples of from the inflection time carry almost no
information about it; when lies multiples of
outside , the profile information decreases
like , by a factor of about 45 per multiple when the
states are known. The state being hidden, only the
observations attributed to state inform the curve, and less than
they would if the states were known.
The fitted object contains the component inflection (see Value). Its
limits are that at least half of the change of
takes place on (change ), which
places inside this interval, and that in.band is at
least 10. They were derived from profile likelihoods of in
simulations of 250 TSCPG observations (see fit.scpg). With
hidden states they are necessary rather than sufficient.
A warning is issued when a limit is not met. The inflection time should then
be reported as not identified rather than by its estimate, and the model
with SCPG states (time.scpg = FALSE) compared by AIC. When a fitted
is nearly constant on ,
is not identified under the hypothesis of no change and the chi-squared
calibration of likelihood-ratio tests and profile intervals fails.
The script verify_fit_hsmm_scpg.R in the examples directory
of the package reproduces the numbers stated on this help page; run it
in the console with
f <- system.file("examples", "verify_fit_hsmm_scpg.R",
package = "HMMscpg")
source(f, echo = TRUE)
The returned object provides estimated HSMM with additional
information about the function evaluation and gradient counts at the
estimated minimum of negative log-likelihood function, convergence code and
minimized likelihood function value as returned by optim and
nparam is the number of parameters to be estimated. With TSCPG renewal
processes it also contains inflection, a data frame with the
inflection diagnostics of Details, one row per state :
component, label
"lambda" and
"state j".
rate, intercept
and .
inflection.
first, last
and
, the values of for the first and
last interevent times, at and . The
inflection time lies in when
first last; otherwise -first is its
distance before 0, or last its distance after , in
units of .
changethe part of the change of ,
between 0 and 1, that takes place on ,
with .
nthe expected number of observations in state ,
, from the smoothed state
probabilities.
in.bandthe part of n from the observations
whose lies in the central 10 to 90 per cent of
the change, where .
rareNA; used by fit.ihmm.scpg.
flagthe limits of Details that are not met, or "".
Guédon Y (2003). “Estimating hidden semi-Markov chains from discrete sequences.” Journal of Computational and Graphical Statistics, 12(3), 604-639. doi:10.1198/1061860032030.
Mitchell CD, Jamieson LH (1993). “Modeling duration in a hidden Markov model with the exponential family.” In Proceedings of the IEEE International Conference on Acoustics, Speech and Signal Processing, 331-334. doi:10.1109/ICASSP.1993.319304.
# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # Simulating a 2-state HSMM with SCPG distribution sim_hsmm1 <- sim.hsmm.scpg(obj_hsmm1, nsim = 150, seed = 1) str(sim_hsmm1[c("x", "states")]) # Number of visits to each state in the simulated path table(rle(sim_hsmm1$states)$values) # Fitting a 2-state HSMM with SCPG distributions # (the parameters of obj_hsmm1 are the starting values) fit_hsmm1 <- fit.hsmm.scpg(sim_hsmm1) fit_hsmm1$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm1$scpg.par$rate # lambda_2 (true 3) fit_hsmm1$scpg.par$shape # alpha (true 1.5) fit_hsmm1$scpg.par$scale # beta (true 1) fit_hsmm1$logLik # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # Simulating a 3-state HSMM with SCPG distribution sim_hsmm1_m3 <- sim.hsmm.scpg(obj_hsmm1_m3, nsim = 80, seed = 1) print(sim_hsmm1_m3) # Fitting a 3-state HSMM with SCPG distributions # The fit takes about 15 seconds, so it is wrapped in donttest. fit_hsmm1_m3 <- fit.hsmm.scpg(sim_hsmm1_m3) print(fit_hsmm1_m3) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # Simulating a 2-state HSMM with a TSCPG distribution sim_hsmm2 <- sim.hsmm.scpg(obj_hsmm2, nsim = 300, seed = 3) str(sim_hsmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2$x[-300]), h_T = sum(sim_hsmm2$x)) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2 are the starting values) fit_hsmm2 <- fit.hsmm.scpg(sim_hsmm2) fit_hsmm2$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_hsmm2$scpg.par$scale # true 1 fit_hsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Inflection diagnostics of the fitted TSCPG rate lambda_2(t), whose true # inflection time is 400. The change lies inside the record (first > 0 > # last), most of it takes place on [0, h_{T-1}] (change >= 0.5), and the # expected number of observations of State 2 within its central 80 per cent # (in.band, from the smoothed state probabilities) is well above 10, so no # warning is given and the inflection time P/R, estimated at about 412, is # identified. fit_hsmm2$inflection # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3) # Simulating a 3-state HSMM with a TSCPG distribution sim_hsmm2_m3 <- sim.hsmm.scpg(obj_hsmm2_m3, nsim = 400, seed = 3) str(sim_hsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rates are evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2_m3$x[-400]), h_T = sum(sim_hsmm2_m3$x)) # Number of visits to each state in the simulated path table(rle(sim_hsmm2_m3$states)$values) # Fitting a 3-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2_m3 are the starting values). The fit # takes about 2 minutes, so it is wrapped in donttest. fit_hsmm2_m3 <- fit.hsmm.scpg(sim_hsmm2_m3) fit_hsmm2_m3$smc.par$tpm # transition matrix of the embedded chain # sojourn parameters mu_1, mu_2, mu_3 (true 4, 3, 3) fit_hsmm2_m3$smc.par$dur fit_hsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_hsmm2_m3$scpg.par$scale # true 0.5 fit_hsmm2_m3$logLik # Inflection diagnostics of the fitted TSCPG rates lambda_2(t) and # lambda_3(t), whose true inflection times are 600 and 900. For each rate # the change lies inside the record (first > 0 > last), most of it takes # place on [0, h_{T-1}] (change >= 0.5), and the expected number of # observations of the state within its central 80 per cent (in.band, from # the smoothed state probabilities) is above 10, so no warning is given and # both inflection times P_j/R_j are identified. fit_hsmm2_m3$inflection# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # Simulating a 2-state HSMM with SCPG distribution sim_hsmm1 <- sim.hsmm.scpg(obj_hsmm1, nsim = 150, seed = 1) str(sim_hsmm1[c("x", "states")]) # Number of visits to each state in the simulated path table(rle(sim_hsmm1$states)$values) # Fitting a 2-state HSMM with SCPG distributions # (the parameters of obj_hsmm1 are the starting values) fit_hsmm1 <- fit.hsmm.scpg(sim_hsmm1) fit_hsmm1$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm1$scpg.par$rate # lambda_2 (true 3) fit_hsmm1$scpg.par$shape # alpha (true 1.5) fit_hsmm1$scpg.par$scale # beta (true 1) fit_hsmm1$logLik # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # Simulating a 3-state HSMM with SCPG distribution sim_hsmm1_m3 <- sim.hsmm.scpg(obj_hsmm1_m3, nsim = 80, seed = 1) print(sim_hsmm1_m3) # Fitting a 3-state HSMM with SCPG distributions # The fit takes about 15 seconds, so it is wrapped in donttest. fit_hsmm1_m3 <- fit.hsmm.scpg(sim_hsmm1_m3) print(fit_hsmm1_m3) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # Simulating a 2-state HSMM with a TSCPG distribution sim_hsmm2 <- sim.hsmm.scpg(obj_hsmm2, nsim = 300, seed = 3) str(sim_hsmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2$x[-300]), h_T = sum(sim_hsmm2$x)) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2 are the starting values) fit_hsmm2 <- fit.hsmm.scpg(sim_hsmm2) fit_hsmm2$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_hsmm2$scpg.par$scale # true 1 fit_hsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Inflection diagnostics of the fitted TSCPG rate lambda_2(t), whose true # inflection time is 400. The change lies inside the record (first > 0 > # last), most of it takes place on [0, h_{T-1}] (change >= 0.5), and the # expected number of observations of State 2 within its central 80 per cent # (in.band, from the smoothed state probabilities) is well above 10, so no # warning is given and the inflection time P/R, estimated at about 412, is # identified. fit_hsmm2$inflection # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3) # Simulating a 3-state HSMM with a TSCPG distribution sim_hsmm2_m3 <- sim.hsmm.scpg(obj_hsmm2_m3, nsim = 400, seed = 3) str(sim_hsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rates are evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2_m3$x[-400]), h_T = sum(sim_hsmm2_m3$x)) # Number of visits to each state in the simulated path table(rle(sim_hsmm2_m3$states)$values) # Fitting a 3-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2_m3 are the starting values). The fit # takes about 2 minutes, so it is wrapped in donttest. fit_hsmm2_m3 <- fit.hsmm.scpg(sim_hsmm2_m3) fit_hsmm2_m3$smc.par$tpm # transition matrix of the embedded chain # sojourn parameters mu_1, mu_2, mu_3 (true 4, 3, 3) fit_hsmm2_m3$smc.par$dur fit_hsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_hsmm2_m3$scpg.par$scale # true 0.5 fit_hsmm2_m3$logLik # Inflection diagnostics of the fitted TSCPG rates lambda_2(t) and # lambda_3(t), whose true inflection times are 600 and 900. For each rate # the change lies inside the record (first > 0 > last), most of it takes # place on [0, h_{T-1}] (change >= 0.5), and the expected number of # observations of the state within its central 80 per cent (in.band, from # the smoothed state probabilities) is above 10, so no warning is given and # both inflection times P_j/R_j are identified. fit_hsmm2_m3$inflection
Estimates the parameters of an IHMM with class ihmm.gamma, ihmm.scpg
and ihmm.tscpg as typically returned by ihmm.scpg
using direct nonlinear optimization.
fit.ihmm.scpg( ihmmobj, method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )fit.ihmm.scpg( ihmmobj, method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )
ihmmobj |
a model object with class |
method |
Optimization method passed to |
maxit |
Maximum number of iterations passed to the |
reltol |
Relative convergence tolerance passed to the |
negative |
is a logical argument for negative log-likelihood. Default is
|
Likelihood. The likelihood of an IHMM is obtained from that of an HMM by replacing the transition probabilities with their time-varying counterparts (Zucchini et al., 2016),
where . With the forward
variable
, the
recursion becomes
and . The transition probability
matrix is reconstructed from its logistic coefficients at each step, using
the occurrence time accumulated from the preceding observations; the
likelihood is consequently not invariant under permutation of the
observations. As in the homogeneous case, the recursion is scaled at each
step and the logarithms of the scale factors accumulated.
Estimation. The likelihood is maximized by direct numerical
minimization of the negative log-likelihood using optim
over working parameters defined on the real line. The transition structure is
described by logistic coefficients. Each pair enters the log-odds , evaluated at the
last occurrence time , and is
represented by and ,
the time as a fraction of , the value of for the last interevent time . The estimates of and are almost perfectly
correlated whenever lies in , whereas
these working parameters are much less correlated and do not depend on the
unit of time. The initial distribution is represented by multinomial logits
and the observation parameters as in fit.scpg. The inverse
transformations are applied to the minimizer, so that the fitted object is a
valid ihmm.scpg object.
Inflection diagnostics. The transition probabilities change along the
record through the log-odds , which is
zero at : for the inflection time of
, and for the time at which . The departure at time uses at
, so over the record is observed for
between () and (). The information about comes
from the departures from state , each weighted by : where the transition probability is close to 0 or 1 the
observed transitions are almost all of one kind. The likelihood is therefore
nearly flat in when the rarer outcome of a departure from
state (moving to , or not) is expected fewer than about 10
times, and exactly flat in one direction when it is never observed. Because
the log-odds is linear, the profile information about
decreases more slowly than for the four-parameter curves of the TSCPG and the
IHSMM: with the states known, by a factor of about 3.7 (against about 45) for
each multiple of by which it lies outside
. When the states are TSCPG (time.scpg = TRUE), the
rates are checked as in fit.hmm.scpg; how
the two kinds of curve affect each other is described at the end of Details.
The fitted object contains the component inflection (see Value). The
limits for a transition are that at least half of the logistic change
takes place on (change ), which
places inside this interval, and that rare is at
least 10; the limits for are those of
fit.hmm.scpg. In
simulations of a two-state IHMM with 300 observations the 95 per cent
profile interval of was bounded when the rarer outcome
of a departure from State 1 was expected 8.6 times (at the true values)
and unbounded when it was expected 5.4 times or fewer, even with 293
departures.
A warning is issued when a limit is not met. The crossing time should then
be reported as not identified rather than by its estimate, and a model with
fewer time-dependent parameters, such as the homogeneous
fit.hmm.scpg, compared by AIC. When a fitted transition
probability is nearly constant on , its crossing time is
not identified under the hypothesis of no change and the chi-squared
calibration of likelihood-ratio tests and profile intervals fails.
Two kinds of time dependence (class ihmm.tscpg). With
time.scpg = TRUE the record can become more complete in two ways:
the transition probabilities govern how often the record
is in an incomplete state, and the Poisson means how
many events are missed while it is there. Both change the mean interevent
time, in State 1 and
in State , so the data tell them apart only through the shape of
the distribution of and the persistence of the states. This
affects their inflection times in two ways. First, is
informed only by the observations of State : if the transitions
make State rare where changes, few observations
inform it, which in.band shows, since it counts the expected
observations of State . Second, as falls, the
interevent times of State (sums of at least two complete ones)
come closer to those of State 1, the state probabilities become less
certain, and every curve is then less precisely determined, which the
counts in.band and rare do not show. In simulations of a
two-state IHMM with 500 observations, whose and
change around 304 and 600 and whose
falls between the levels 5.5 and 0.5 around 200, 400 or 600 (30 records
each), the estimated inflection time of and the
crossing times of and were almost
uncorrelated (Spearman correlations between and 0.21), also
when and changed at the same time.
Their precision depended on
how long the two states stayed distinct: with the inflection time of
at 200 rather than 600, the spread (interquartile range
divided by 1.349) of the estimated inflection times was 124 rather than 49
for and 149 rather than 49 for , and the
mean absolute error of the proportion of events recorded,
, averaged over each quarter of the record, was 0.060
rather than 0.030, although in.band was about the same (medians 49
and 53). When both kinds are fitted, compare the model by AIC with those
that have only one: fit.hmm.scpg with
time.scpg = TRUE (only ) and
fit.ihmm.scpg with time.scpg = FALSE (only
); and report , which combines them, alongside the
inflection times.
The script verify_fit_ihmm_scpg.R in the examples directory
of the package reproduces the numbers stated on this help page; run it
in the console with
f <- system.file("examples", "verify_fit_ihmm_scpg.R",
package = "HMMscpg")
source(f, echo = TRUE)
The returned object provides estimated HMM with additional
information about the function evaluation and gradient counts at the estimated
minimum of negative log-likelihood function, convergence code and minimized
likelihood function value as returned by optim and nparam is
the number of parameters to be estimated. It also contains
inflection, a data frame with the inflection diagnostics of Details,
with one row for each transition , , and, for TSCPG
states, one row for each . For the transitions:
component, label
"a" and "i -> j".
rate, intercept
and .
inflection.
first, last
and
, the log-odds at
and at . The crossing lies in when
first last; otherwise -first is its
distance before 0, or last its distance after , in
units of .
changethe part of the logistic change, between 0 and 1,
that takes place on .
nthe expected number of departures from state ,
, from the smoothed state
probabilities.
in.bandthe part of n from departures whose log-odds
lies in .
rarethe expected number of the rarer outcome of a departure
from state ,
.
flagthe limits of Details that are not met, or "".
Zucchini W, MacDonald IL, Langrock R (2016). Hidden Markov Models for Time Series: An Introduction Using R, 2 edition. CRC Press, Boca Raton.
# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # Simulating a 2-state IHMM with SCPG distribution sim_ihmm1 <- sim.ihmm.scpg(obj_ihmm1, nsim = 200, seed = 1) str(sim_ihmm1[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm1$states, half = ifelse(seq_along(sim_ihmm1$states) <= 100, "first", "second")) # The fit takes about 6 s, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with SCPG distributions # (the parameters of obj_ihmm1 are the starting values) fit_ihmm1 <- fit.ihmm.scpg(sim_ihmm1) fit_ihmm1$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm1$scpg.par$rate # lambda_2 (true 3) fit_ihmm1$scpg.par$shape # true 1.5 fit_ihmm1$scpg.par$scale # true 1 fit_ihmm1$logLik # The fit takes about 6 s, so the code below is wrapped in donttest. # Inflection diagnostics of the fitted transition probabilities a_12(t) and # a_22(t) (true crossing times 250 and 500; labelled "i -> j"). Each curve # is checked against the limits change >= 0.5 and rare >= 10 expected # departures of the rarer kind (moving to State 2, or not). Here both are # met (rare about 19 and 14), so no warning is given; the crossing times # are estimated at about 442 and 486. fit_ihmm1$inflection # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # Simulating a 3-state IHMM with SCPG distribution sim_ihmm1_m3 <- sim.ihmm.scpg(obj_ihmm1_m3, nsim = 200, seed = 2) print(sim_ihmm1_m3) # Fitting a 3-state IHMM with SCPG distributions # The fit takes about 1.5 minutes, so it is wrapped in donttest. fit_ihmm1_m3 <- fit.ihmm.scpg(sim_ihmm1_m3) print(fit_ihmm1_m3) # Inflection diagnostics of the fitted transition probabilities (true # crossing times between 2000 and 3000). The rates r_ij of this example are # small (0.0006 to 0.001), so each change is wide compared with the record # (h_{T-1} = 4733), and with 200 observations only a_12(t) meets the # limits here: the crossing times of a_13(t), a_22(t), a_32(t) and a_33(t) # lie outside the record, with less than half of the change on # [0, h_{T-1}], and a_13(t), a_22(t) and a_23(t) have fewer than 10 # expected departures of the rarer kind. The fit warns, and the flagged # crossing times should be reported as not identified. fit_ihmm1_m3$inflection # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # Simulating a 2-state IHMM with a TSCPG distribution sim_ihmm2 <- sim.ihmm.scpg(obj_ihmm2, nsim = 200, seed = 2) str(sim_ihmm2[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm2$states, half = ifelse(seq_along(sim_ihmm2$states) <= 100, "first", "second")) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2 are the starting values) fit_ihmm2 <- fit.ihmm.scpg(sim_ihmm2) fit_ihmm2$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_ihmm2$scpg.par$scale # true 1 fit_ihmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Inflection diagnostics of the three fitted logistic curves: lambda_2(t) # (true inflection time 400; component "lambda") and a_12(t), a_22(t) # (true crossing times 304 and 600; component "a", labelled "i -> j"). # Each curve is checked against its own limits: change >= 0.5 for all of # them, in.band >= 10 expected observations of State 2 for lambda_2(t), and # rare >= 10 expected departures of the rarer kind for a_ij(t). Here every # limit is met, so no warning is given. lambda_2(t) is located well (402), # but a_12(t) changes slowly (1/r_12 is about 360 time units) and its # crossing time is estimated at 542, while that of a_22(t), at 637, lies # near the end of the record (h_{T-1} = 691), with only 55 per cent of its # change on [0, h_{T-1}]: identified is not the same as precisely # estimated. How the two kinds of curve affect each other is described in # the Details of ?fit.ihmm.scpg. fit_ihmm2$inflection # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3) # Simulating a 3-state IHMM with a TSCPG distribution sim_ihmm2_m3 <- sim.ihmm.scpg(obj_ihmm2_m3, nsim = 500, seed = 1) str(sim_ihmm2_m3[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into the incomplete states become less likely table(state = sim_ihmm2_m3$states, half = ifelse(seq_along(sim_ihmm2_m3$states) <= 250, "first", "second")) # Fitting a 3-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2_m3 are the starting values). The fit # takes about 2.5 minutes, so it is wrapped in donttest. fit_ihmm2_m3 <- fit.ihmm.scpg(sim_ihmm2_m3) fit_ihmm2_m3$imc.par$ttpm[, , 1] # r_ij (rows i, columns j = 2, 3) fit_ihmm2_m3$imc.par$ttpm[, , 2] # w_ij fit_ihmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihmm2_m3$logLik # Inflection diagnostics of the eight fitted logistic curves: lambda_2(t) # and lambda_3(t) (true inflection times 500 and 700; component "lambda") # and the six transition curves (true crossing times 400 to 600; component # "a", labelled "i -> j"). Each curve is checked against its own limits: # change >= 0.5 for all of them, in.band >= 10 expected observations of the # state for lambda_j(t), and rare >= 10 expected departures of the rarer # kind for a_ij(t). # # Here lambda_2(t) and the six transition curves meet their limits, while # lambda_3(t) is flagged: it is fitted as a step, with no observation of # State 3 inside its change. This shows how the two kinds of time # dependence interact: lambda_3(t) is informed only by the observations of # State 3, and the transitions make State 3 rare later in the record (in # the simulated path, 31 of the 70 observations before h = 500 but only 16 # of the 374 after h = 700, where lambda_3(t) changes), so the fit can put # the whole change between two of them (see the Details # of ?fit.ihmm.scpg). Its inflection time should be reported # as not identified; a model with fewer time-dependent parameters may be # compared by AIC. fit_ihmm2_m3$inflection# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # Simulating a 2-state IHMM with SCPG distribution sim_ihmm1 <- sim.ihmm.scpg(obj_ihmm1, nsim = 200, seed = 1) str(sim_ihmm1[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm1$states, half = ifelse(seq_along(sim_ihmm1$states) <= 100, "first", "second")) # The fit takes about 6 s, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with SCPG distributions # (the parameters of obj_ihmm1 are the starting values) fit_ihmm1 <- fit.ihmm.scpg(sim_ihmm1) fit_ihmm1$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm1$scpg.par$rate # lambda_2 (true 3) fit_ihmm1$scpg.par$shape # true 1.5 fit_ihmm1$scpg.par$scale # true 1 fit_ihmm1$logLik # The fit takes about 6 s, so the code below is wrapped in donttest. # Inflection diagnostics of the fitted transition probabilities a_12(t) and # a_22(t) (true crossing times 250 and 500; labelled "i -> j"). Each curve # is checked against the limits change >= 0.5 and rare >= 10 expected # departures of the rarer kind (moving to State 2, or not). Here both are # met (rare about 19 and 14), so no warning is given; the crossing times # are estimated at about 442 and 486. fit_ihmm1$inflection # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # Simulating a 3-state IHMM with SCPG distribution sim_ihmm1_m3 <- sim.ihmm.scpg(obj_ihmm1_m3, nsim = 200, seed = 2) print(sim_ihmm1_m3) # Fitting a 3-state IHMM with SCPG distributions # The fit takes about 1.5 minutes, so it is wrapped in donttest. fit_ihmm1_m3 <- fit.ihmm.scpg(sim_ihmm1_m3) print(fit_ihmm1_m3) # Inflection diagnostics of the fitted transition probabilities (true # crossing times between 2000 and 3000). The rates r_ij of this example are # small (0.0006 to 0.001), so each change is wide compared with the record # (h_{T-1} = 4733), and with 200 observations only a_12(t) meets the # limits here: the crossing times of a_13(t), a_22(t), a_32(t) and a_33(t) # lie outside the record, with less than half of the change on # [0, h_{T-1}], and a_13(t), a_22(t) and a_23(t) have fewer than 10 # expected departures of the rarer kind. The fit warns, and the flagged # crossing times should be reported as not identified. fit_ihmm1_m3$inflection # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # Simulating a 2-state IHMM with a TSCPG distribution sim_ihmm2 <- sim.ihmm.scpg(obj_ihmm2, nsim = 200, seed = 2) str(sim_ihmm2[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm2$states, half = ifelse(seq_along(sim_ihmm2$states) <= 100, "first", "second")) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2 are the starting values) fit_ihmm2 <- fit.ihmm.scpg(sim_ihmm2) fit_ihmm2$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_ihmm2$scpg.par$scale # true 1 fit_ihmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Inflection diagnostics of the three fitted logistic curves: lambda_2(t) # (true inflection time 400; component "lambda") and a_12(t), a_22(t) # (true crossing times 304 and 600; component "a", labelled "i -> j"). # Each curve is checked against its own limits: change >= 0.5 for all of # them, in.band >= 10 expected observations of State 2 for lambda_2(t), and # rare >= 10 expected departures of the rarer kind for a_ij(t). Here every # limit is met, so no warning is given. lambda_2(t) is located well (402), # but a_12(t) changes slowly (1/r_12 is about 360 time units) and its # crossing time is estimated at 542, while that of a_22(t), at 637, lies # near the end of the record (h_{T-1} = 691), with only 55 per cent of its # change on [0, h_{T-1}]: identified is not the same as precisely # estimated. How the two kinds of curve affect each other is described in # the Details of ?fit.ihmm.scpg. fit_ihmm2$inflection # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3) # Simulating a 3-state IHMM with a TSCPG distribution sim_ihmm2_m3 <- sim.ihmm.scpg(obj_ihmm2_m3, nsim = 500, seed = 1) str(sim_ihmm2_m3[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into the incomplete states become less likely table(state = sim_ihmm2_m3$states, half = ifelse(seq_along(sim_ihmm2_m3$states) <= 250, "first", "second")) # Fitting a 3-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2_m3 are the starting values). The fit # takes about 2.5 minutes, so it is wrapped in donttest. fit_ihmm2_m3 <- fit.ihmm.scpg(sim_ihmm2_m3) fit_ihmm2_m3$imc.par$ttpm[, , 1] # r_ij (rows i, columns j = 2, 3) fit_ihmm2_m3$imc.par$ttpm[, , 2] # w_ij fit_ihmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihmm2_m3$logLik # Inflection diagnostics of the eight fitted logistic curves: lambda_2(t) # and lambda_3(t) (true inflection times 500 and 700; component "lambda") # and the six transition curves (true crossing times 400 to 600; component # "a", labelled "i -> j"). Each curve is checked against its own limits: # change >= 0.5 for all of them, in.band >= 10 expected observations of the # state for lambda_j(t), and rare >= 10 expected departures of the rarer # kind for a_ij(t). # # Here lambda_2(t) and the six transition curves meet their limits, while # lambda_3(t) is flagged: it is fitted as a step, with no observation of # State 3 inside its change. This shows how the two kinds of time # dependence interact: lambda_3(t) is informed only by the observations of # State 3, and the transitions make State 3 rare later in the record (in # the simulated path, 31 of the 70 observations before h = 500 but only 16 # of the 374 after h = 700, where lambda_3(t) changes), so the fit can put # the whole change between two of them (see the Details # of ?fit.ihmm.scpg). Its inflection time should be reported # as not identified; a model with fewer time-dependent parameters may be # compared by AIC. fit_ihmm2_m3$inflection
Estimates the parameters of an IHSMM with class ihsmm.gamma, ihsmm.scpg
and ihsmm.tscpg as typically returned by ihsmm.scpg
using direct nonlinear optimization.
fit.ihsmm.scpg( ihsmmobj, method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )fit.ihsmm.scpg( ihsmmobj, method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )
ihsmmobj |
a model object with class |
method |
Optimization method passed to |
maxit |
Maximum number of iterations passed to the |
reltol |
Relative convergence tolerance passed to the |
negative |
is a logical argument for negative log-likelihood. Default is
|
Likelihood. The likelihood of a right-censored IHSMM is evaluated by the extension of
the forward algorithm given by Shahzadi et al. (2023, 2026). The
structure is that of fit.hsmm.scpg, with the sojourn
distribution evaluated at the time at which each visit commences. With
and
, the forward
variable is
where is the shifted Poisson sojourn mass function with
parameter (expected sojourn ). At
the sojourn in the last
visited state is right-censored and the mass function is replaced by the
corresponding survival function , giving
. The expression reduces to the
right-censored HSMM likelihood when the sojourn distributions are
independent of .
The time dependence has a computational consequence. In a homogeneous HSMM the sojourn mass and survival functions are tabulated once; here they are evaluated at every admissible starting time, the forward variable being indexed by state, elapsed sojourn and commencement time. Scaling is embedded in the recursion at each step and the logarithms of the scale factors accumulated. The recursion is evaluated by compiled code, which computes the sojourn mass and survival functions as it proceeds. Fitting an IHSMM is the most demanding of the four model families, and the estimates of the corresponding homogeneous HSMM provide suitable starting values.
Estimation. The likelihood is maximized by direct numerical
minimization of the negative log-likelihood using optim
over working parameters defined on the real line: each row of the
zero-diagonal transition probability matrix by multinomial logits;
and by logarithms; and the pair , which enters
through at the last occurrence time
of the commencement of a visit,
by and , the inflection time
as a fraction of , the
value of for the last interevent time . The
estimates of and are almost perfectly correlated
whenever lies in , whereas these working
parameters are much less correlated and do not depend on the unit of time.
Entries for which tdur.lb and tdur.ub are supplied are
represented by scaled logits instead, and a state with bounds for
or keeps and . The observation parameters
are transformed as in fit.scpg. The fitted object is returned
on the natural scale and is suitable for vip.ihsmm.scpg and
sp.ihsmm.scpg.
Inflection diagnostics. The expected sojourns change along the record
through
, with inflection time , at
which . Two aspects of identifiability should be
noted. A visit that commences at time uses at
, which over the record runs from ()
to (), so the duration
curves are determined only on : when lies
multiples of outside this interval, the values of
on it determine only
three combinations of , and the profile
information about decreases like , by a
factor of about 45 per multiple when the states are known. And the four
duration parameters of a state are
informed by the number of visits to that state, each visit contributing one
sojourn, rather than by the length of the record. When the states are TSCPG
(time.scpg = TRUE), the rates are checked as in
fit.hmm.scpg; how the two kinds of curve affect each other is
described at the end of Details.
The fitted object contains the component inflection (see Value). The
limits for a sojourn parameter are that at least 65 per cent of the
change of takes place on (change
, stricter than the 0.5 of the other curves), which places
inside this interval, and that the state is expected to be
visited at least 20 times; the limits for are those of
fit.hmm.scpg. In simulations of a two-state IHSMM with 150
observations and 12 to 14 visits to each state, the 95 per cent profile
interval of was unbounded wherever the inflection time lay,
including 2.75 multiples of inside ; with the
states known it was bounded around the true value only when the inflection
time lay inside this interval (with the inflection time two multiples
before the start it was bounded but excluded the true value). The limit on
change comes from profile likelihoods of for 900
sojourn curves simulated with the states known (two-state IHSMMs with 150,
300 or 600 observations, between 2 and 32 and the
inflection time at 0.3, 0.6 or 0.9 of the record): of the curves meeting
the limits change and 20 visits, 374 had a bounded
95 per cent interval and 177 did not; raising the limit to 0.65 flagged
32 of the 177 and none of the 374 (0.75 would have flagged 59 and 2). A
limit on in.band, the expected number of visits commencing within
the central 80 per cent of the change, was also tried and rejected: an
abrupt change located between two visits had a bounded interval with
in.band as low as 0, whereas most unbounded intervals had
in.band above 15, so any minimum flagged more identified curves
than unidentified ones (a minimum of 5 flagged 100 and 29).
A warning is issued when a limit is not met. The inflection time should then
be reported as not identified rather than by its estimate, and a model with
fewer time-dependent parameters, such as the homogeneous
fit.hsmm.scpg, compared by AIC. When a fitted
is nearly constant on , is not identified
under the hypothesis of no change and the chi-squared calibration of
likelihood-ratio tests and profile intervals fails.
Two kinds of time dependence (class ihsmm.tscpg). With
time.scpg = TRUE the record can become more complete in two ways:
the sojourn parameters govern how long the chain stays in
the complete and the incomplete states, and the Poisson means
how many events are missed while it is in State
. Both change the mean interevent time, in State 1
and in State , so the data
tell them apart only through the shape of the distribution of
and the lengths of the visits. As for fit.ihmm.scpg,
is informed only by the observations of State ,
which in.band counts, and the states become harder to tell apart as
falls. In simulations of a two-state IHSMM with 300
observations, whose (increasing) and
(decreasing) change around 500 and whose falls between
the levels 6.5 and 0.5 around 200, 500 or 800 (20 records each), the
inflection times of the sojourn parameters were poorly determined wherever
changed (spread, the interquartile range divided by
1.349, between 222 and
273, more than one multiple ). When
and , which both describe State 2, changed at the same time,
their estimated inflection times were negatively correlated (Spearman
correlation : a later fall in the number of missing events was
offset by an earlier shortening of the incomplete visits); otherwise the
correlations between the two kinds of curve lay between and
0.15. The spread of the inflection time of grew from
127 to 261 as it moved from 200 to 800, where State 2 is seldom visited,
which in.band shows (medians 90 and 59). The mean absolute error of
the proportion of events recorded,
, averaged over each quarter of the record, lay between
0.023 and 0.047. When both kinds are fitted, compare the model by AIC with
those that have only one: fit.hsmm.scpg with
time.scpg = TRUE (only ) and
fit.ihsmm.scpg with time.scpg = FALSE (only
); judge the inflection times of and
of the same state jointly, for example by a parametric
bootstrap with sim.ihsmm.scpg; and report , which
combines them, alongside the inflection times.
The script verify_fit_ihsmm_scpg.R in the examples directory
of the package reproduces the numbers stated on this help page; run it
in the console with
f <- system.file("examples", "verify_fit_ihsmm_scpg.R",
package = "HMMscpg")
source(f, echo = TRUE)
The returned object provides estimated IHSMM with additional
information about the function evaluation and gradient counts at the estimated
minimum of negative log-likelihood function, convergence code and minimized
likelihood function value as returned by optim and nparam is
the number of parameters to be estimated. It also contains
inflection, a data frame with the inflection diagnostics of Details,
with one row for each , , and, for TSCPG states,
one row for each . For the sojourn parameters:
component, label
"mu" and "state j".
rate, intercept
and .
inflection.
first, last
and
, the values of
for visits commencing at
() and (). The inflection time
lies in when first last;
otherwise -first is its distance before 0, or last its
distance after , in units of .
changethe part of the change of , between 0
and 1, that takes place on .
nthe expected number of visits to state , the sum
over of the probabilities, given the record, that
a visit to state begins at , obtained from the
forward-backward recursion.
in.bandthe part of n from visits commencing at
with in the central 10 to 90 per cent of the
change, where .
rareNA; used by fit.ihmm.scpg.
flagthe limits of Details that are not met, or "".
Shahzadi A, Wang T, Parry M, Bebbington M (2023). “Inhomogeneous hidden semi-Markov models for incompletely observed point processes.” Annals of Institute Statistical Mathematics, 75, 253-280. doi:10.1007/s10463-022-00843-5.
Shahzadi A, Wang T, Parry M, Bebbington M (2026). “Modelling time-inhomogeneous incomplete records of point processes using variants of hidden Markov models.” Advances in Data Analysis and Classification, 20, 663-691. doi:10.1007/s11634-025-00632-x.
# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # Simulating a 2-state IHSMM with SCPG distribution sim_ihsmm1 <- sim.ihsmm.scpg(obj_ihsmm1, nsim = 150, seed = 3) str(sim_ihsmm1[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm1$states)$values) # The fit takes about 30 s, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with SCPG distributions # (the parameters of obj_ihsmm1 are the starting values) fit_ihsmm1 <- fit.ihsmm.scpg(sim_ihsmm1) fit_ihsmm1$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm1$scpg.par$rate # lambda_2 (true 3) fit_ihsmm1$scpg.par$shape # true 1.5 fit_ihsmm1$scpg.par$scale # true 1 fit_ihsmm1$logLik # The fit takes about 30 s, so the code below is wrapped in donttest. # Inflection diagnostics of the fitted sojourn parameters mu_1(t) and # mu_2(t) (true inflection times D_j/C_j = 500). The duration parameters of # a state are informed by its visits; the limits are change >= 0.65 and at # least 20 expected visits (n). Here both are met (about 21 visits to each # state), so no warning is given; the inflection times are estimated at # about 424 and 452. mu_2(t) is fitted as an abrupt step, with almost no # visit commencing within its change (in.band close to 0); such a step can # still be located, which is why in.band is not a limit for mu_j(t) (see # the Details of ?fit.ihsmm.scpg). fit_ihsmm1$inflection # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # Simulating a 3-state IHSMM with SCPG distribution sim_ihsmm1_m3 <- sim.ihsmm.scpg(obj_ihsmm1_m3, nsim = 150, seed = 1) print(sim_ihsmm1_m3) # Fitting a 3-state IHSMM with SCPG distributions # The fit takes about 2 minutes, so it is wrapped in donttest. fit_ihsmm1_m3 <- fit.ihsmm.scpg(sim_ihsmm1_m3) print(fit_ihsmm1_m3) # Inflection diagnostics of the fitted sojourn parameters (true inflection # times D_j/C_j = 600). The duration parameters of a state are informed by # its visits, and with 150 observations all three curves are flagged here, # and the fit warns: the inflection time of mu_1(t) lies after the record # (4850 against h_{T-1} = 1146, with only 2 per cent of its change on # [0, h_{T-1}]), and States 2 and 3 are expected to be visited only 19.5 # and 6.1 times, fewer than the 20 visits required. fit_ihsmm1_m3$inflection # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # Simulating a 2-state IHSMM with a TSCPG distribution sim_ihsmm2 <- sim.ihsmm.scpg(obj_ihsmm2, nsim = 200, seed = 1) str(sim_ihsmm2[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2$states)$values) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2 are the starting values) fit_ihsmm2 <- fit.ihsmm.scpg(sim_ihsmm2) fit_ihsmm2$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_ihsmm2$scpg.par$scale # true 1 fit_ihsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Inflection diagnostics of the three fitted logistic curves: lambda_2(t) # (true inflection time 400) and mu_1(t), mu_2(t) (true 500). Each curve is # checked against its own limits: change >= 0.5 and in.band >= 10 # observations of State 2 for lambda_2(t); change >= 0.65 and at least 20 # expected visits (n) for mu_1(t) and mu_2(t). Here every limit is met # (about 22 expected visits to each state), so no warning is given, and # the inflection times are estimated at about 399, 530 and 440. The two # kinds of curve describe the same improvement of the record and are # estimated jointly; meeting the limits does not show that their # inflection times are estimated independently of each other (see the # Details of ?fit.ihsmm.scpg). fit_ihsmm2$inflection # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3) # Simulating a 3-state IHSMM with a TSCPG distribution sim_ihsmm2_m3 <- sim.ihsmm.scpg(obj_ihsmm2_m3, nsim = 250, seed = 2) str(sim_ihsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the time-dependent components are evaluated # on [0, h_{T-1}] c(h_T1 = sum(sim_ihsmm2_m3$x[-250]), h_T = sum(sim_ihsmm2_m3$x)) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2_m3$states)$values) # Fitting a 3-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2_m3 are the starting values). The fit # takes about 8 minutes, so it is wrapped in donttest. fit_ihsmm2_m3 <- fit.ihsmm.scpg(sim_ihsmm2_m3) fit_ihsmm2_m3$ismc.par$tpm # transition matrix of the embedded chain fit_ihsmm2_m3$ismc.par$tdur # A, B, C, D of mu_1(t), mu_2(t) and mu_3(t) fit_ihsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihsmm2_m3$scpg.par$scale # true 0.5 fit_ihsmm2_m3$logLik # Inflection diagnostics of the five fitted logistic curves: lambda_2(t) # and lambda_3(t) (true inflection times 400 and 600; component "lambda") # and mu_1(t), mu_2(t) and mu_3(t) (true 500; component "mu"). Each curve # is checked against its own limits: change >= 0.5 and in.band >= 10 # expected observations of the state for lambda_j(t); change >= 0.65 and # at least 20 expected visits (n) for mu_j(t). # # With 250 observations and about 20 visits to each state, two curves are # flagged, one by each kind of limit: # - lambda_2(t): its estimated inflection time, 398, is close to the true # one, but the fitted change is narrow (its central 80 per cent lies # between about 346 and 451) and only 6.5 expected observations of # State 2 fall within it, too few to locate it; # - mu_3(t): it falls on the record, from about 2.8 to 1.2, but as the # tail of a much wider curve whose inflection time D_3/C_3 = -1323 lies # before the start, with only 12 per cent of its change on [0, h_{T-1}]. # Both inflection times should be reported as not identified. The other # three curves meet their limits, which does not make them precise: the # inflection times of mu_1(t) and mu_2(t) are estimated at 729 and 609 # rather than 500, and lambda_3(t) at 586 but falling from about 14 to 2 # instead of from 9.8 to 4.5. The two kinds of curve describe the same # improvement of the record and are estimated jointly (see the Details # of ?fit.ihsmm.scpg). fit_ihsmm2_m3$inflection# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # Simulating a 2-state IHSMM with SCPG distribution sim_ihsmm1 <- sim.ihsmm.scpg(obj_ihsmm1, nsim = 150, seed = 3) str(sim_ihsmm1[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm1$states)$values) # The fit takes about 30 s, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with SCPG distributions # (the parameters of obj_ihsmm1 are the starting values) fit_ihsmm1 <- fit.ihsmm.scpg(sim_ihsmm1) fit_ihsmm1$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm1$scpg.par$rate # lambda_2 (true 3) fit_ihsmm1$scpg.par$shape # true 1.5 fit_ihsmm1$scpg.par$scale # true 1 fit_ihsmm1$logLik # The fit takes about 30 s, so the code below is wrapped in donttest. # Inflection diagnostics of the fitted sojourn parameters mu_1(t) and # mu_2(t) (true inflection times D_j/C_j = 500). The duration parameters of # a state are informed by its visits; the limits are change >= 0.65 and at # least 20 expected visits (n). Here both are met (about 21 visits to each # state), so no warning is given; the inflection times are estimated at # about 424 and 452. mu_2(t) is fitted as an abrupt step, with almost no # visit commencing within its change (in.band close to 0); such a step can # still be located, which is why in.band is not a limit for mu_j(t) (see # the Details of ?fit.ihsmm.scpg). fit_ihsmm1$inflection # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # Simulating a 3-state IHSMM with SCPG distribution sim_ihsmm1_m3 <- sim.ihsmm.scpg(obj_ihsmm1_m3, nsim = 150, seed = 1) print(sim_ihsmm1_m3) # Fitting a 3-state IHSMM with SCPG distributions # The fit takes about 2 minutes, so it is wrapped in donttest. fit_ihsmm1_m3 <- fit.ihsmm.scpg(sim_ihsmm1_m3) print(fit_ihsmm1_m3) # Inflection diagnostics of the fitted sojourn parameters (true inflection # times D_j/C_j = 600). The duration parameters of a state are informed by # its visits, and with 150 observations all three curves are flagged here, # and the fit warns: the inflection time of mu_1(t) lies after the record # (4850 against h_{T-1} = 1146, with only 2 per cent of its change on # [0, h_{T-1}]), and States 2 and 3 are expected to be visited only 19.5 # and 6.1 times, fewer than the 20 visits required. fit_ihsmm1_m3$inflection # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # Simulating a 2-state IHSMM with a TSCPG distribution sim_ihsmm2 <- sim.ihsmm.scpg(obj_ihsmm2, nsim = 200, seed = 1) str(sim_ihsmm2[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2$states)$values) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2 are the starting values) fit_ihsmm2 <- fit.ihsmm.scpg(sim_ihsmm2) fit_ihsmm2$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_ihsmm2$scpg.par$scale # true 1 fit_ihsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Inflection diagnostics of the three fitted logistic curves: lambda_2(t) # (true inflection time 400) and mu_1(t), mu_2(t) (true 500). Each curve is # checked against its own limits: change >= 0.5 and in.band >= 10 # observations of State 2 for lambda_2(t); change >= 0.65 and at least 20 # expected visits (n) for mu_1(t) and mu_2(t). Here every limit is met # (about 22 expected visits to each state), so no warning is given, and # the inflection times are estimated at about 399, 530 and 440. The two # kinds of curve describe the same improvement of the record and are # estimated jointly; meeting the limits does not show that their # inflection times are estimated independently of each other (see the # Details of ?fit.ihsmm.scpg). fit_ihsmm2$inflection # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3) # Simulating a 3-state IHSMM with a TSCPG distribution sim_ihsmm2_m3 <- sim.ihsmm.scpg(obj_ihsmm2_m3, nsim = 250, seed = 2) str(sim_ihsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the time-dependent components are evaluated # on [0, h_{T-1}] c(h_T1 = sum(sim_ihsmm2_m3$x[-250]), h_T = sum(sim_ihsmm2_m3$x)) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2_m3$states)$values) # Fitting a 3-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2_m3 are the starting values). The fit # takes about 8 minutes, so it is wrapped in donttest. fit_ihsmm2_m3 <- fit.ihsmm.scpg(sim_ihsmm2_m3) fit_ihsmm2_m3$ismc.par$tpm # transition matrix of the embedded chain fit_ihsmm2_m3$ismc.par$tdur # A, B, C, D of mu_1(t), mu_2(t) and mu_3(t) fit_ihsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihsmm2_m3$scpg.par$scale # true 0.5 fit_ihsmm2_m3$logLik # Inflection diagnostics of the five fitted logistic curves: lambda_2(t) # and lambda_3(t) (true inflection times 400 and 600; component "lambda") # and mu_1(t), mu_2(t) and mu_3(t) (true 500; component "mu"). Each curve # is checked against its own limits: change >= 0.5 and in.band >= 10 # expected observations of the state for lambda_j(t); change >= 0.65 and # at least 20 expected visits (n) for mu_j(t). # # With 250 observations and about 20 visits to each state, two curves are # flagged, one by each kind of limit: # - lambda_2(t): its estimated inflection time, 398, is close to the true # one, but the fitted change is narrow (its central 80 per cent lies # between about 346 and 451) and only 6.5 expected observations of # State 2 fall within it, too few to locate it; # - mu_3(t): it falls on the record, from about 2.8 to 1.2, but as the # tail of a much wider curve whose inflection time D_3/C_3 = -1323 lies # before the start, with only 12 per cent of its change on [0, h_{T-1}]. # Both inflection times should be reported as not identified. The other # three curves meet their limits, which does not make them precise: the # inflection times of mu_1(t) and mu_2(t) are estimated at 729 and 609 # rather than 500, and lambda_3(t) at 586 but falling from about 14 to 2 # instead of from 9.8 to 4.5. The two kinds of curve describe the same # improvement of the record and are estimated jointly (see the Details # of ?fit.ihsmm.scpg). fit_ihsmm2_m3$inflection
Estimates the parameters of an SCPG or TSCPG distribution, or of a gamma
distribution with a fixed number of missing events, by maximum likelihood;
see dscpg for the models.
fit.scpg( x, rate, shape, scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation", method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )fit.scpg( x, rate, shape, scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation", method = "BFGS", maxit = 1000, reltol = sqrt(.Machine$double.eps), negative = TRUE )
x |
A vector of positive, finite interevent times. For the TSCPG
( |
rate, shape, scale
|
Starting values, as in |
rate.fix |
Logical. If |
shape.fix |
Logical; used only by |
time.scpg |
Logical. If |
WBsum.method |
The method used by |
method |
Optimization method passed to |
maxit |
Maximum number of iterations passed to the |
reltol |
Relative convergence tolerance passed to the |
negative |
Logical. If |
Likelihood. For interevent times the
log-likelihood is , with
the density of dscpg; the parameters are
for the SCPG and
for the TSCPG. For the TSCPG,
depends on , so x
must be in time order.
Estimation. There is no closed-form estimator, and is
maximized with optim over unconstrained working
parameters (Zucchini et al., 2016). The shape is kept in
and , or and , in
, through the scaled logit
of each interval ; the
scale is estimated on the log scale. Without these bounds the likelihood has
a ridge along which the shape tends to zero with almost no gain, while the
series of WBsum needs ever more terms. For the TSCPG, the pair
is replaced by and
, the inflection time as a fraction of
, the last occurrence time used by the
record; is kept in . On this scale the
two working parameters are nearly uncorrelated and do not depend on the unit
of time, whereas and are almost perfectly correlated.
In 16 simulated TSCPG records fitted from perturbed starting values, this
choice reached the best optimum in all 16 fits, against 10 for
. Starting values must lie inside the bounds. The
estimates are returned on the natural scale, and the number of estimated
parameters nparam allows comparison of models by
(Akaike, 1974).
Inflection diagnostics (TSCPG). The rate falls from
about to , and most of this change (the central 80 per
cent) takes place within of the inflection time . The
record observes only at .
The data can therefore locate only if the change falls inside
and enough observations fall within it. Otherwise the
record shows only one end, or only the almost straight middle, of the
S-shaped curve, which many values of fit almost equally well: the
likelihood is nearly flat in , and likelihood-ratio tests and
profile intervals for are unreliable. fit.scpg therefore
returns the component inflection (see Value) and gives a warning when
less than half of the change of takes place on
(change below 0.5). This covers every
outside , and a that is
almost constant over the record; or
fewer than 10 observations lie within the central 80 per cent of the change.
These limits come from profile likelihoods of in 87 simulated
records of 250 observations, with the shape held at 1,
falling between the levels 4.5 and 0.5, between about 0.5
and 10, and the
inflection time at 0.5, 0.9 or 1.15 times . Every fit with
change below 0.5 had a 95 per cent profile interval for
reaching 1.5 record lengths before 0 or after , and every
bounded interval came from a fit with change of at least 0.5. The
limits are necessary rather than sufficient: 22 of the 52 fits that met
them still had unbounded intervals, so a profile likelihood or a parametric
bootstrap should confirm an inflection time that is to be interpreted.
After a warning, report as not identified rather than quoting its
estimate, and compare the fit with the SCPG (time.scpg = FALSE) by
AIC.
The script verify_fit_scpg.R in the examples directory of the
package reproduces the numbers stated here; run it in the console with
f <- system.file("examples", "verify_fit_scpg.R",
package = "HMMscpg")
source(f, echo = TRUE)
A list with components
fun.count, grad.count
numbers of function and
gradient evaluations used by optim.
convergencethe optim convergence code;
0 indicates successful convergence.
nparamthe number of estimated parameters.
llkthe maximized log-likelihood.
rate.estthe estimate of (SCPG) or of
c(K, M, R, P) (TSCPG), or the fixed rate
(rate.fix = TRUE).
shape.est, scale.est
the estimates of
(the supplied value when shape.fix = TRUE) and .
rate.fix, shape.fix, time.scpg,
WBsum.method
the settings used.
objective.errorNULL, or a message when the log
densities at the estimates could not be computed or are not finite.
inflectionNULL unless time.scpg = TRUE. For
the TSCPG, a one-row data frame with the inflection diagnostics of
Details:
component, label
"lambda" and
"record".
rate, intercept
the estimates of and
.
inflectionthe inflection time .
first, last
and
: the position of relative to 0 and
to , in units of . lies inside
when first last.
changethe fraction, between 0 and 1, of the change of
that takes place on ,
with
; the first limit fails when it is
below 0.5.
nthe number of observations .
in.bandthe number of observations whose
lies within the central 80 per cent of the change,
.
rarealways NA for fit.scpg.
flagthe limits that are not met, or "".
Zucchini W, MacDonald IL, Langrock R (2016). Hidden Markov Models for Time Series: An Introduction Using R, 2 edition. CRC Press, Boca Raton.
Akaike H (1974). “A new look at the statistical model identification.” IEEE Transactions on Automatic Control, 19(6), 716-723. doi:10.1109/TAC.1974.1100705.
# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # Fitting an SCPG distribution fit_scpg <- fit.scpg(x_scpg, rate, shape, scale, rate.fix=FALSE, shape.fix = TRUE, WBsum.method = 'direct.evaluation') print(fit_scpg) # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg) # Fitting of a TSCPG distribution fit_tscpg <- fit.scpg(x_tscpg, t_rate, shape, scale, rate.fix=FALSE, shape.fix = FALSE, time.scpg=TRUE, WBsum.method = 'direct.evaluation') print(fit_tscpg)# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # Fitting an SCPG distribution fit_scpg <- fit.scpg(x_scpg, rate, shape, scale, rate.fix=FALSE, shape.fix = TRUE, WBsum.method = 'direct.evaluation') print(fit_scpg) # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg) # Fitting of a TSCPG distribution fit_tscpg <- fit.scpg(x_tscpg, t_rate, shape, scale, rate.fix=FALSE, shape.fix = FALSE, time.scpg=TRUE, WBsum.method = 'direct.evaluation') print(fit_tscpg)
Creates an -state hidden Markov model (HMM) for an incomplete record
of interevent times, with class hmm.gamma, hmm.scpg or
hmm.tscpg.
hmm.scpg( x = NULL, mc.par = list(initd = NULL, tpm = NULL, stationary = TRUE), scpg.par = list(rate = NULL, shape = NULL, scale = NULL, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation") )hmm.scpg( x = NULL, mc.par = list(initd = NULL, tpm = NULL, stationary = TRUE), scpg.par = list(rate = NULL, shape = NULL, scale = NULL, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation") )
x |
A vector of positive interevent times in time order, or
|
mc.par |
A named list with the parameters of the hidden Markov chain:
|
scpg.par |
A named list with the parameters of the observation process:
|
The model. The hidden state of the
th interevent time follows a homogeneous Markov chain with initial
distribution and transition probabilities
. State therefore lasts
a geometric number of observations, ,
. Given the state, has density
:
State 1 is the state of completeness: no event is missing and
is gamma with shape and scale .
States are states of incompleteness, in which
is the sum of complete interevent times,
being the number of missing events, with the density of
dscpg: gamma with fixed (class
hmm.gamma), SCPG with shifted Poisson with
parameter (hmm.scpg), or TSCPG with parameter
, which
changes around the inflection time of the last occurrence
time (hmm.tscpg).
The scale is common to all states because the sum of gamma
variables is gamma only when they share the scale; the shape may be common or
differ between states. The parameters are therefore ,
and , with and, for
, with fixed,
or .
The object. hmm.scpg checks the parameters and returns them
with x. With stationary = TRUE the initial distribution is
computed as the solution of and adds no parameters. The
object is the model and starting values for fit.hmm.scpg, the
generating model for sim.hmm.scpg, and, once fitted and with
the data attached, the input of vip.hmm.scpg and
sp.hmm.scpg.
A list with components x, mc.par and
scpg.par as above (initd computed when
stationary = TRUE), of class hmm.gamma,
hmm.scpg or hmm.tscpg according to rate.fix and
time.scpg.
# ========================================================= # An example of a 2-state HMM with an SCPG renewal process # ========================================================= # State 1 is the state of completeness: its interevent times are gamma with # shape alpha and scale beta. In the incomplete State 2 the number of # missing events N between two observed events is shifted Poisson with # parameter lambda_2, so on average 1 + lambda_2 = 4 events are missing, # and the observed interevent time is the sum of N + 1 such gamma # interevent times. The shape is common to both states and, with # shape.fix = FALSE, estimated; a separate shape for each state (a vector # of shapes) is also possible but is less well determined. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with SCPG distribution obj_hmm1 <- hmm.scpg(x = NULL, mc.par, scpg.par) print(obj_hmm1) # ======================================================== # An example of a 3-state HMM with an SCPG renewal process # ======================================================== # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 2 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.60, 0.30, 0.10, 0.45, 0.30, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(c(7, 3), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with SCPG distribution obj_hmm1_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) print(obj_hmm1_m3) # ========================================================== # An example of a 2-state HMM with a TSCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.3 at the start of the record towards K = 0.5, around # the inflection time P/R = 300 of the last occurrence time h_{t-1}. The # hidden chain is homogeneous, so only lambda_2(t) changes along the record. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 5 # M rate[3, ] <- 0.01 # R rate[4, ] <- 3 # P: inflection time P/R = 300 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with TSCPG distribution obj_hmm2 <- hmm.scpg(x = NULL, mc.par, scpg.par) class(obj_hmm2) # ======================================================== # An example of a 3-state HMM with a TSCPG renewal process # ======================================================== # Fitting this 3-state model takes about 30 seconds on a laptop (the # 2-state model above takes about 4 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.50, 0.30, 0.20, 0.25, 0.50, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(1, 1) # K rate[2, ] <- c(1.5, 2.5) # M rate[3, ] <- c(0.02, 0.015) # R rate[4, ] <- c(3, 3) # P: inflection times P/R = 150 and 200 shape <- 1 scale <- 1.7 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with TSCPG distribution obj_hmm2_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par)# ========================================================= # An example of a 2-state HMM with an SCPG renewal process # ========================================================= # State 1 is the state of completeness: its interevent times are gamma with # shape alpha and scale beta. In the incomplete State 2 the number of # missing events N between two observed events is shifted Poisson with # parameter lambda_2, so on average 1 + lambda_2 = 4 events are missing, # and the observed interevent time is the sum of N + 1 such gamma # interevent times. The shape is common to both states and, with # shape.fix = FALSE, estimated; a separate shape for each state (a vector # of shapes) is also possible but is less well determined. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with SCPG distribution obj_hmm1 <- hmm.scpg(x = NULL, mc.par, scpg.par) print(obj_hmm1) # ======================================================== # An example of a 3-state HMM with an SCPG renewal process # ======================================================== # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 2 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.60, 0.30, 0.10, 0.45, 0.30, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(c(7, 3), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with SCPG distribution obj_hmm1_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) print(obj_hmm1_m3) # ========================================================== # An example of a 2-state HMM with a TSCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.3 at the start of the record towards K = 0.5, around # the inflection time P/R = 300 of the last occurrence time h_{t-1}. The # hidden chain is homogeneous, so only lambda_2(t) changes along the record. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 5 # M rate[3, ] <- 0.01 # R rate[4, ] <- 3 # P: inflection time P/R = 300 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with TSCPG distribution obj_hmm2 <- hmm.scpg(x = NULL, mc.par, scpg.par) class(obj_hmm2) # ======================================================== # An example of a 3-state HMM with a TSCPG renewal process # ======================================================== # Fitting this 3-state model takes about 30 seconds on a laptop (the # 2-state model above takes about 4 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.50, 0.30, 0.20, 0.25, 0.50, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(1, 1) # K rate[2, ] <- c(1.5, 2.5) # M rate[3, ] <- c(0.02, 0.015) # R rate[4, ] <- c(3, 3) # P: inflection times P/R = 150 and 200 shape <- 1 scale <- 1.7 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with TSCPG distribution obj_hmm2_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par)
Creates a discrete time HSMM object with class hsmm.gamma,
hsmm.scpg, or hsmm.tscpg.
hsmm.scpg( x = NULL, smc.par = list(initd = NULL, tpm = NULL, dur = NULL, dur.lb = NA, dur.ub = NA, stationary = TRUE), scpg.par = list(rate = NULL, shape = NULL, scale = NULL, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation") )hsmm.scpg( x = NULL, smc.par = list(initd = NULL, tpm = NULL, dur = NULL, dur.lb = NA, dur.ub = NA, stationary = TRUE), scpg.par = list(rate = NULL, shape = NULL, scale = NULL, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation") )
x |
A vector of positive interevent times in time order, or
|
smc.par |
named list containing semi-Markov chain parameters:
|
scpg.par |
A named list with the parameters of the observation process:
|
A semi-Markov chain (SMC) does not follow implicit geometric state
durations; it is Markovian only at transition times, and the sojourn time
in each state is at least 1. An HMM with an underlying SMC is an HSMM.
The state sequence becomes two-dimensional,
, where
is the state at the th visit with
, its sojourn time, and transition times
. The components are:
Initial distribution: the process starts in state
with probability .
TPM with no self-transitions:
, .
The transition probability matrix tpm is required to have a zero
diagonal. In a semi-Markov chain the embedded chain governs only the
destination of a transition, the time spent in a state being governed by
the sojourn time distribution; a non-zero self-transition probability would
render the sojourn time unidentified (Guedon, 2003). For
the embedded chain is thereby determined completely and
contributes no parameters to the estimation.
Explicit state durations: Sojourn times follow a shifted
Poisson distribution with parameter ,
Since the last visited state is right-censored, its duration
distribution is replaced by the survival function
.
The distribution being shifted, every visit occupies at least one observation.
Joint state-dependent observation distribution: the
observations of the th visit are independent given the state,
The gamma, SCPG, and TSCPG variants use SMC parameters
together with the
corresponding observation parameters , see hmm.scpg.
hsmm.scpg constructs and validates a specification of the -state
HSMM defined above. The vector dur contains the sojourn
parameters of the shifted Poisson sojourn distribution
, , whose
expected sojourn time is observations.
The arguments dur.lb and dur.ub form no part of the model.
They delimit the interval within which each expected sojourn time is sought
by fit.hsmm.scpg, an expected sojourn time otherwise being
free to exceed the length of the record. Entries left as NA are
estimated on the logarithmic scale subject only to positivity.
The observation conventions are those of hmm.scpg: State 1
denotes completeness and carries the gamma renewal density, rate
describes the incompleteness states alone, and a single scale
parameter is shared across states. Observations occurring within one visit
are conditionally independent draws from the observation distribution of
the state occupied.
returns a list object with class
hsmm.scpg, hsmm.tscpg, or hsmm.gamma with the
above arguments as named components.
Guédon Y (2003). “Estimating hidden semi-Markov chains from discrete sequences.” Journal of Computational and Graphical Statistics, 12(3), 604-639. doi:10.1198/1061860032030.
# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3)# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3)
Creates a discrete time IHMM object with class "gamma.scpg",
ihmm.scpg, or ihmm.tscpg.
ihmm.scpg( x = NULL, imc.par = list(initd = NULL, ttpm = NULL, stationary = TRUE), scpg.par = list(rate = NULL, shape = NULL, scale = NULL, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation") )ihmm.scpg( x = NULL, imc.par = list(initd = NULL, ttpm = NULL, stationary = TRUE), scpg.par = list(rate = NULL, shape = NULL, scale = NULL, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation") )
x |
A vector of positive interevent times in time order, or
|
imc.par |
named list containing the first-order inhomogeneous Markov chain (IMC) parameters.
|
scpg.par |
A named list with the parameters of the observation process:
|
An IHMM is an HMM whose underlying MC has a time-dependent TPM
, defined by a multinomial logistic function with
State 1 (completeness) as the reference state. Because a record's recent
part has fewer missing events, transition probabilities into State 1
increase with time. For those into State 2 decrease; for
a transition probability into a State need not
be monotone (it can rise and then fall when is smaller than
another ), although its odds against State 1,
, always decrease.
The transition probabilities at time are functions of the last
occurrence time as follows:
where measures the rate of change and
is the log-odds at . The
location of the change is , the time at which
; for it is the inflection time of
, at which . For an
TPM, parameters are estimated, and the
matrix remains stochastic for all . State durations are implicitly
time-dependent geometric,
. The gamma, SCPG, and
TSCPG variants replace the homogeneous MC parameters with
.
ihmm.scpg constructs and validates a specification of the -state
IHMM defined above in which the transition probabilities
are multinomial logistic functions of the last occurrence time. These
probabilities are supplied not as a matrix but through the coefficients
that generate it.
The coefficients are held in ttpm, an
array. The first two margins index the departure state and the
arrival state , State 1 being the reference category
and carrying no coefficients; the third margin distinguishes the rate of
change from the intercept , so that
ttpm[i, j-1, 1] is and ttpm[i, j-1, 2] is
. The coefficients so arranged determine the
transition probability matrix at every time point, and the
parameterization is row stochastic for all by construction.
Since the transition probability matrix varies with time, stationarity
requires a convention. If stationary = TRUE, the initial
distribution is computed as the stationary distribution of the transition
probability matrix evaluated at time zero.
The remaining conventions are those of hmm.scpg: State 1
denotes completeness and carries the gamma renewal density, rate
describes the incompleteness states alone, and a single scale
parameter is shared across states. The observation process determines the
class of the returned object, on which fit.ihmm.scpg,
sim.ihmm.scpg, vip.ihmm.scpg and
sp.ihmm.scpg dispatch.
returns list object with class ihmm.scpg,
ihmm.tscpg, or
ihmm.gamma with arguments as named components.
# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3)# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3)
Creates a discrete time IHSMM object with class ihsmm.scpg,
ihsmm.tscpg, or ihsmm.gamma.
ihsmm.scpg( x = NULL, ismc.par = list(initd = NULL, tpm = NULL, tdur = NULL, tdur.lb = NA, tdur.ub = NA, stationary = TRUE), scpg.par = list(rate = NULL, shape = NULL, scale = NULL, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation") )ihsmm.scpg( x = NULL, ismc.par = list(initd = NULL, tpm = NULL, tdur = NULL, tdur.lb = NA, tdur.ub = NA, stationary = TRUE), scpg.par = list(rate = NULL, shape = NULL, scale = NULL, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = "direct.evaluation") )
x |
A vector of positive interevent times in time order, or
|
ismc.par |
named list containing inhomogeneous semi-Markov chain.
|
scpg.par |
A named list with the parameters of the observation process:
|
An IHSMM (Shahzadi et al., 2023) has an underlying inhomogeneous SMC
(ISMC) whose sojourn time distribution depends on time. Sojourn times in
state follow a shifted Poisson distribution with time-dependent
parameter as follows:
with the survival function used for the right-censored sojourn time of the
last visited state. Here, is the starting time of sojourn
in visited state . The expected sojourn time in state
is therefore . Given time inhomogeneity in record
completeness, is an increasing function of the last
occurrence time ,
and in states a decreasing function,
where and . The
gamma, SCPG, and TSCPG variants use ISMC parameters
together with
the corresponding observation parameters .
ihsmm.scpg constructs and validates a specification of the
-state IHSMM of Shahzadi et al. (2023, 2026), in which the expected
sojourn times are generalized logistic functions of the last occurrence time,
as defined above.
The duration parameters are held in tdur, a matrix
whose columns index the states and whose rows are, in order, ,
, and . Each is thereby
confined to the interval , and the expected sojourn
time to .
governs the rate of change, and the inflection time, at which
, is (
itself is the value of there, not a time). The
first three rows are required to be positive and the fourth is
unconstrained. The requirement in every state fixes the
direction of each curve in advance: the expected sojourn time in State 1
increases towards with elapsed time, and those in States
decrease towards . This imposes the assumption
that completeness improves along the record, and precludes the estimation
of a state whose direction is reversed. A homogeneous HSMM is recovered in
the limit in which is constant over the observed span.
As in hsmm.scpg, the transition probability matrix is
required to have a zero diagonal. The arguments tdur.lb and
tdur.ub delimit the intervals within which the duration parameters
are sought by fit.ihsmm.scpg rather than forming part of the
model; entries
left as NA are estimated on the logarithmic scale where positivity
is required and without transformation otherwise. Setting
stationary = TRUE computes the initial distribution as the
stationary distribution of the embedded chain. It is recommended that
stationary be specified explicitly, since omitting it from
ismc.par is not equivalent to the default shown in the function
signature.
returns a list object with class
ihsmm.scpg, ihsmm.tscpg, or ihsmm.gamma with
the above arguments as named components.
Shahzadi A, Wang T, Parry M, Bebbington M (2023). “Inhomogeneous hidden semi-Markov models for incompletely observed point processes.” Annals of Institute Statistical Mathematics, 75, 253-280. doi:10.1007/s10463-022-00843-5.
Shahzadi A, Wang T, Parry M, Bebbington M (2026). “Modelling time-inhomogeneous incomplete records of point processes using variants of hidden Markov models.” Advances in Data Analysis and Classification, 20, 663-691. doi:10.1007/s11634-025-00632-x.
# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3)# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3)
Evaluates the distribution function of the SCPG distribution, of its
time-dependent version (TSCPG), or of a gamma distribution with a fixed
number of missing events; see dscpg for the models.
pscpg( x, rate, shape, scale, rate.fix = FALSE, time.scpg = FALSE, lower.tail = TRUE, log.p = FALSE )pscpg( x, rate, shape, scale, rate.fix = FALSE, time.scpg = FALSE, lower.tail = TRUE, log.p = FALSE )
x |
A vector of positive, finite interevent times. For the TSCPG
( |
rate |
The number of missing events: for the SCPG, the Poisson mean
|
shape |
The gamma shape parameter |
scale |
The gamma scale parameter |
rate.fix |
Logical. If |
time.scpg |
Logical. If |
lower.tail |
Logical; if |
log.p |
Logical; if |
Given , the observed interevent time is the sum of
gamma interevent times, and is therefore gamma with shape
and scale . The SCPG distribution function is
thus a Poisson mixture of gamma distribution functions,
where is the gamma distribution function with shape
and scale . pscpg evaluates this sum directly,
without integrating the density. The Poisson terms that are kept are chosen
so that the omitted Poisson mass is below times the smaller
tail. That tail, or , is summed on the log
scale, and the other is obtained as its complement, so the two tails add to
one to machine accuracy and far-tail log probabilities stay finite.
With rate.fix = TRUE, is the gamma distribution function with
shape . With time.scpg = TRUE, the th value is
the probability for given the preceding observations, that is, the
SCPG probability at , which depends on
. For a record generated by the TSCPG
these values are independent and uniform on , and
qscpg applied to them in the same order returns the record.
A numeric vector of probabilities, or log probabilities when
log.p = TRUE, with the same length and names as x.
# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # Computing CDF of an SCPG distribution cdf_scpg <- pscpg(x_scpg, rate, shape, scale, time.scpg=FALSE) print(cdf_scpg) # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg) # Computing CDF of a TSCPG distribution cdf_tscpg <- pscpg(x_tscpg, t_rate, shape, scale, time.scpg=TRUE) print(cdf_tscpg)# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # Computing CDF of an SCPG distribution cdf_scpg <- pscpg(x_scpg, rate, shape, scale, time.scpg=FALSE) print(cdf_scpg) # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg) # Computing CDF of a TSCPG distribution cdf_tscpg <- pscpg(x_tscpg, t_rate, shape, scale, time.scpg=TRUE) print(cdf_tscpg)
Computes quantiles of the SCPG distribution, of its time-dependent version
(TSCPG), or of a gamma distribution with a fixed number of missing events;
see dscpg for the models.
qscpg( p, rate, shape, scale, rate.fix = FALSE, time.scpg = FALSE, lower.tail = TRUE, log.p = FALSE, mixture.rtol = 1e-12, tol = 1e-10, maxiter = 200L )qscpg( p, rate, shape, scale, rate.fix = FALSE, time.scpg = FALSE, lower.tail = TRUE, log.p = FALSE, mixture.rtol = 1e-12, tol = 1e-10, maxiter = 200L )
p |
A numeric vector of probabilities in |
rate |
The number of missing events: for the SCPG, the Poisson mean
|
shape |
The gamma shape parameter |
scale |
The gamma scale parameter |
rate.fix |
Logical. If |
time.scpg |
Logical. If |
lower.tail |
Logical; if |
log.p |
Logical; if |
mixture.rtol |
A number in |
tol |
The tolerance of |
maxiter |
The maximum number of |
The quantile is , where is the
distribution function of pscpg: for the SCPG, the Poisson
mixture of gamma distribution functions
There is no closed form, so is solved numerically. The
Poisson terms outside a window are omitted, with total probability below
mixture.rtol times the tail being inverted, and the equation is solved
for with uniroot, working with
the smaller of the two tails on the log scale so that extreme probabilities
keep full accuracy. With rate.fix = TRUE the quantile is that of the
gamma distribution with shape .
With time.scpg = TRUE the quantiles are computed in order, each one
at the Poisson mean set by the quantiles before it:
starting from ,
with as in dscpg. The order of p
therefore matters, and qscpg inverts pscpg applied to
a record in time order.
A numeric vector of quantiles with the same length and names as
p. gives 0 and gives
Inf. Without time.scpg, NA values of p give
NA. With time.scpg = TRUE, the quantiles after an NA
or an infinite quantile cannot be computed and are NA.
# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # Computing CDF of an SCPG distribution cdf_scpg <- pscpg(x_scpg, rate, shape, scale, time.scpg=FALSE) print(cdf_scpg) # Calculating quantiles of an SCPG distribution q1_scpg <- qscpg(cdf_scpg, rate, shape, scale, time.scpg=FALSE) print(q1_scpg) print(x_scpg) q2_scpg <- qscpg(seq(0.1, 0.9, 0.1), rate, shape, scale, time.scpg=FALSE) print(q2_scpg) # A very small lower-tail probability supplied on the log scale qscpg(-100, rate, shape , scale, log.p = TRUE) # Upper-tail quantile: P(X > q) = 1e-8 qscpg(log(1e-8), rate, shape, scale, lower.tail = FALSE, log.p = TRUE) # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg) # Computing CDF of a TSCPG distribution cdf_tscpg <- pscpg(x_tscpg, t_rate, shape, scale, time.scpg=TRUE) print(cdf_tscpg) # Quantiles for a TSCPG distribution qt1_scpg <- qscpg(cdf_tscpg, t_rate, shape, scale, time.scpg=TRUE) print(qt1_scpg) print(x_tscpg) qt2_scpg <- qscpg(seq(0.1, 0.5, 0.1), t_rate, shape, scale, time.scpg=TRUE) print(qt2_scpg)# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # Computing CDF of an SCPG distribution cdf_scpg <- pscpg(x_scpg, rate, shape, scale, time.scpg=FALSE) print(cdf_scpg) # Calculating quantiles of an SCPG distribution q1_scpg <- qscpg(cdf_scpg, rate, shape, scale, time.scpg=FALSE) print(q1_scpg) print(x_scpg) q2_scpg <- qscpg(seq(0.1, 0.9, 0.1), rate, shape, scale, time.scpg=FALSE) print(q2_scpg) # A very small lower-tail probability supplied on the log scale qscpg(-100, rate, shape , scale, log.p = TRUE) # Upper-tail quantile: P(X > q) = 1e-8 qscpg(log(1e-8), rate, shape, scale, lower.tail = FALSE, log.p = TRUE) # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg) # Computing CDF of a TSCPG distribution cdf_tscpg <- pscpg(x_tscpg, t_rate, shape, scale, time.scpg=TRUE) print(cdf_tscpg) # Quantiles for a TSCPG distribution qt1_scpg <- qscpg(cdf_tscpg, t_rate, shape, scale, time.scpg=TRUE) print(qt1_scpg) print(x_tscpg) qt2_scpg <- qscpg(seq(0.1, 0.5, 0.1), t_rate, shape, scale, time.scpg=TRUE) print(qt2_scpg)
Generates random numbers from an SCPG or a TSCPG distribution.
rscpg( nsim, rate, shape, scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, seed = NULL )rscpg( nsim, rate, shape, scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, seed = NULL )
nsim |
is the number of points to be simulated for random number generator. |
rate |
The number of missing events: for the SCPG, the Poisson mean
|
shape |
The gamma shape parameter |
scale |
The gamma scale parameter |
rate.fix |
Logical. If |
shape.fix |
Logical; used only by |
time.scpg |
Logical. If |
seed |
is seed for random number generator. Default is |
Simulation from the SCPG distribution follows a two-step process: first,
a random number is generated from a shifted Poisson distribution with
parameter ; next, random numbers
are generated from a gamma distribution
with the specified shape and scale parameters and summed to produce a
single draw . This procedure is repeated
independently to generate nsim observations, and an identical
procedure applies to the TSCPG distribution.
Under rate.fix = TRUE the counting stage is omitted. The number of
missing events being fixed, the additive property of the gamma distribution
gives each draw directly as a gamma variate with shape
and scale .
Under time.scpg = TRUE the draws are independent but not identically
distributed, the rate governing the th draw being
evaluated at the
occurrence time accumulated from the draws preceding it. Generation is
therefore recursive: an interevent time is drawn, the occurrence time
advanced, and the rate re-evaluated. The realization so obtained is an
ordered process in which the expected number of missing events declines
along the sequence, and its elements are to be retained in the order
returned. Specifying seed initializes the random number generator
and renders the realization reproducible.
returns a sequence of nsim observations from an SCPG or a
TSCPG distribution.
# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg)# =============================== # Example of an SCPG distribution # =============================== rate <- 3 shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from an SCPG distribution x_scpg <- rscpg(nsim=200, rate, shape, scale, seed=900) print(x_scpg) # =============================== # Example of a TSCPG distribution # =============================== # rate[1]=K, rate[2]=M, rate[3]=R, rate[4]=P: lambda(t) falls from about K+M # to K, # with inflection time P/R = 300 t_rate <- c(1, 2, 0.02, 6) shape <- 2 scale <- 0.5 rate.fix <- FALSE shape.fix <- FALSE # Simulating from a TSCPG distribution x_tscpg <- rscpg(nsim=200, t_rate, shape, scale, time.scpg=TRUE, seed=700) print(x_tscpg)
Simulates an incomplete record, and its hidden states, from an HMM of class
hmm.gamma, hmm.scpg or hmm.tscpg created by
hmm.scpg.
sim.hmm.scpg(hmmobj, nsim = 1, seed = NULL)sim.hmm.scpg(hmmobj, nsim = 1, seed = NULL)
hmmobj |
An object created by |
nsim |
The number of interevent times to simulate. |
seed |
Seed for the random number generator, or |
The record is generated in time order. The first state is drawn from the
initial distribution (the stationary distribution when
stationary = TRUE); at each step an interevent time is drawn for the
current state, as in rscpg: a gamma interevent time in State 1,
and in States the sum of gamma interevent
times with missing events. The next state is then drawn from the row
of the transition matrix for the current state. For the TSCPG, the Poisson
mean of each step uses the occurrence time
reached so far.
Only the observed interevent times are returned, so x is an
incomplete record of the kind the models describe; the missing events
themselves are not recorded. The hidden states are returned to assess
decoding and parameter recovery, as in the simulation studies of Shahzadi et
al. (2026).
An object of the same class as hmmobj: a list with the
simulated interevent times x, the hidden states states, the
number of transitions of the chain n_transitions (nsim - 1),
and mc.par and scpg.par of hmmobj. It can be passed
directly to fit.hmm.scpg.
Shahzadi A, Wang T, Parry M, Bebbington M (2026). “Modelling time-inhomogeneous incomplete records of point processes using variants of hidden Markov models.” Advances in Data Analysis and Classification, 20, 663-691. doi:10.1007/s11634-025-00632-x.
# ========================================================== # An example of a 2-state HMM with a TSCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.3 at the start of the record towards K = 0.5, around # the inflection time P/R = 300 of the last occurrence time h_{t-1}. The # hidden chain is homogeneous, so only lambda_2(t) changes along the record. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 5 # M rate[3, ] <- 0.01 # R rate[4, ] <- 3 # P: inflection time P/R = 300 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with TSCPG distribution obj_hmm2 <- hmm.scpg(x = NULL, mc.par, scpg.par) class(obj_hmm2) # Simulating a 2-state HMM with TSCPG distribution sim_hmm2 <- sim.hmm.scpg(obj_hmm2, nsim = 200, seed = 1) str(sim_hmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hmm2$x[-200]), h_T = sum(sim_hmm2$x)) # ======================================================== # An example of a 3-state HMM with a TSCPG renewal process # ======================================================== # Fitting this 3-state model takes about 30 seconds on a laptop (the # 2-state model above takes about 4 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.50, 0.30, 0.20, 0.25, 0.50, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(1, 1) # K rate[2, ] <- c(1.5, 2.5) # M rate[3, ] <- c(0.02, 0.015) # R rate[4, ] <- c(3, 3) # P: inflection times P/R = 150 and 200 shape <- 1 scale <- 1.7 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with TSCPG distribution obj_hmm2_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) # Simulating a 3-state HMM with TSCPG distribution sim_hmm2_m3 <- sim.hmm.scpg(obj_hmm2_m3, nsim=100, seed=9)# ========================================================== # An example of a 2-state HMM with a TSCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.3 at the start of the record towards K = 0.5, around # the inflection time P/R = 300 of the last occurrence time h_{t-1}. The # hidden chain is homogeneous, so only lambda_2(t) changes along the record. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 5 # M rate[3, ] <- 0.01 # R rate[4, ] <- 3 # P: inflection time P/R = 300 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with TSCPG distribution obj_hmm2 <- hmm.scpg(x = NULL, mc.par, scpg.par) class(obj_hmm2) # Simulating a 2-state HMM with TSCPG distribution sim_hmm2 <- sim.hmm.scpg(obj_hmm2, nsim = 200, seed = 1) str(sim_hmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hmm2$x[-200]), h_T = sum(sim_hmm2$x)) # ======================================================== # An example of a 3-state HMM with a TSCPG renewal process # ======================================================== # Fitting this 3-state model takes about 30 seconds on a laptop (the # 2-state model above takes about 4 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.50, 0.30, 0.20, 0.25, 0.50, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(1, 1) # K rate[2, ] <- c(1.5, 2.5) # M rate[3, ] <- c(0.02, 0.015) # R rate[4, ] <- c(3, 3) # P: inflection times P/R = 150 and 200 shape <- 1 scale <- 1.7 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with TSCPG distribution obj_hmm2_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) # Simulating a 3-state HMM with TSCPG distribution sim_hmm2_m3 <- sim.hmm.scpg(obj_hmm2_m3, nsim=100, seed=9)
Generates a sequence of observed process along with hidden state sequence with class
hsmm.gamma, hsmm.scpg and hsmm.tscpg as typically returned
by hsmm.scpg.
sim.hsmm.scpg(hsmmobj, nsim = 1, seed = NULL)sim.hsmm.scpg(hsmmobj, nsim = 1, seed = NULL)
hsmmobj |
is a model object with class |
nsim |
is the number of points to be simulated for random number generator. |
seed |
is seed for random number generator. Default is |
A semi-Markov chain is characterized by its realization occurring visit by visit,
as opposed to at each discrete time step, with explicit sojourn times. A state is drawn from the
initial
distribution; its sojourn time is drawn from the shifted Poisson
distribution , so that every
visit occupies at least one observation; the observations of that visit are
drawn from the state-dependent renewal process; and the succeeding state is
drawn from the row of the embedded transition probability matrix indexed by
the state just left. Since that matrix has a zero diagonal, consecutive
visits are necessarily to distinct states.
Generation terminates once nsim observations have been accumulated,
in general during a visit. The realization is thus right-censored in the
sense assumed by the likelihood evaluated in fit.hsmm.scpg,
which permits a simulation study to assess the censored likelihood as it is
applied in practice.
The number of observations and the number of visits constitute distinct
sample sizes. A state whose expected sojourn time is large relative to
nsim may be visited only a few times irrespective of the number of
observations generated, and it is the number of visits that determines the
precision with which the embedded chain can be recovered. Specifying
seed renders the realization reproducible.
The returned object is an hsmm.scpg with the same components as the input
arguments in addition to the simulated sequence for the observed process and states, which
is the corresponding sequence of states of the underlying semi-Markov chain.
This also provides the information about the number of transitions for SMC.
# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # Simulating a 2-state HSMM with SCPG distribution sim_hsmm1 <- sim.hsmm.scpg(obj_hsmm1, nsim = 150, seed = 1) str(sim_hsmm1[c("x", "states")]) # Number of visits to each state in the simulated path table(rle(sim_hsmm1$states)$values) # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # Simulating a 3-state HSMM with SCPG distribution sim_hsmm1_m3 <- sim.hsmm.scpg(obj_hsmm1_m3, nsim = 80, seed = 1) print(sim_hsmm1_m3) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # Simulating a 2-state HSMM with a TSCPG distribution sim_hsmm2 <- sim.hsmm.scpg(obj_hsmm2, nsim = 300, seed = 3) str(sim_hsmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2$x[-300]), h_T = sum(sim_hsmm2$x)) # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3) # Simulating a 3-state HSMM with a TSCPG distribution sim_hsmm2_m3 <- sim.hsmm.scpg(obj_hsmm2_m3, nsim = 400, seed = 3) str(sim_hsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rates are evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2_m3$x[-400]), h_T = sum(sim_hsmm2_m3$x)) # Number of visits to each state in the simulated path table(rle(sim_hsmm2_m3$states)$values)# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # Simulating a 2-state HSMM with SCPG distribution sim_hsmm1 <- sim.hsmm.scpg(obj_hsmm1, nsim = 150, seed = 1) str(sim_hsmm1[c("x", "states")]) # Number of visits to each state in the simulated path table(rle(sim_hsmm1$states)$values) # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # Simulating a 3-state HSMM with SCPG distribution sim_hsmm1_m3 <- sim.hsmm.scpg(obj_hsmm1_m3, nsim = 80, seed = 1) print(sim_hsmm1_m3) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # Simulating a 2-state HSMM with a TSCPG distribution sim_hsmm2 <- sim.hsmm.scpg(obj_hsmm2, nsim = 300, seed = 3) str(sim_hsmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2$x[-300]), h_T = sum(sim_hsmm2$x)) # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3) # Simulating a 3-state HSMM with a TSCPG distribution sim_hsmm2_m3 <- sim.hsmm.scpg(obj_hsmm2_m3, nsim = 400, seed = 3) str(sim_hsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rates are evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2_m3$x[-400]), h_T = sum(sim_hsmm2_m3$x)) # Number of visits to each state in the simulated path table(rle(sim_hsmm2_m3$states)$values)
Generates a sequence of observed process along with hidden state sequence with class
ihmm.gamma, ihmm.scpg and ihmm.tscpg as typically returned
by ihmm.scpg.
sim.ihmm.scpg(ihmmobj, nsim = 1, seed = NULL)sim.ihmm.scpg(ihmmobj, nsim = 1, seed = NULL)
ihmmobj |
a model object with class |
nsim |
The number of interevent times to simulate. |
seed |
Seed for the random number generator, or |
Realizations are generated as in sim.hmm.scpg, with the
difference that each state is drawn from the row of the transition
probability matrix evaluated at the occurrence time accumulated from the
preceding observations rather than from a fixed matrix. The hidden chain
and the observations are therefore generated jointly and in time order,
each state drawn advancing the occurrence time that determines the
transition probabilities governing the next. The initial state is drawn
from , or from the stationary distribution of the transition
probability matrix at time zero where the model is specified as
stationary.
The resulting realization exhibits the time inhomogeneity for which the
specification was introduced: the earlier portion of the record, in which
the transition probabilities into State 1 are small, is dominated by the
incompleteness states, while the later portion is increasingly confined to
State 1. Simulation therefore provides a direct means of assessing whether
a given set of coefficients and locates the
change within the intended span. Specifying seed renders the
realization reproducible.
The returned object is an ihmm.scpg with the same components as input arguments
in addition to the simulated sequence for the observed process and states
is the corresponding sequence of hidden states of inhomogeneous Markov chain.
This also provides the information about the number of transitions for IMC.
# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # Simulating a 2-state IHMM with SCPG distribution sim_ihmm1 <- sim.ihmm.scpg(obj_ihmm1, nsim = 200, seed = 1) str(sim_ihmm1[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm1$states, half = ifelse(seq_along(sim_ihmm1$states) <= 100, "first", "second")) # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # Simulating a 3-state IHMM with SCPG distribution sim_ihmm1_m3 <- sim.ihmm.scpg(obj_ihmm1_m3, nsim = 200, seed = 2) print(sim_ihmm1_m3) # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # Simulating a 2-state IHMM with a TSCPG distribution sim_ihmm2 <- sim.ihmm.scpg(obj_ihmm2, nsim = 200, seed = 2) str(sim_ihmm2[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm2$states, half = ifelse(seq_along(sim_ihmm2$states) <= 100, "first", "second")) # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3) # Simulating a 3-state IHMM with a TSCPG distribution sim_ihmm2_m3 <- sim.ihmm.scpg(obj_ihmm2_m3, nsim = 500, seed = 1) str(sim_ihmm2_m3[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into the incomplete states become less likely table(state = sim_ihmm2_m3$states, half = ifelse(seq_along(sim_ihmm2_m3$states) <= 250, "first", "second"))# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # Simulating a 2-state IHMM with SCPG distribution sim_ihmm1 <- sim.ihmm.scpg(obj_ihmm1, nsim = 200, seed = 1) str(sim_ihmm1[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm1$states, half = ifelse(seq_along(sim_ihmm1$states) <= 100, "first", "second")) # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # Simulating a 3-state IHMM with SCPG distribution sim_ihmm1_m3 <- sim.ihmm.scpg(obj_ihmm1_m3, nsim = 200, seed = 2) print(sim_ihmm1_m3) # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # Simulating a 2-state IHMM with a TSCPG distribution sim_ihmm2 <- sim.ihmm.scpg(obj_ihmm2, nsim = 200, seed = 2) str(sim_ihmm2[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm2$states, half = ifelse(seq_along(sim_ihmm2$states) <= 100, "first", "second")) # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3) # Simulating a 3-state IHMM with a TSCPG distribution sim_ihmm2_m3 <- sim.ihmm.scpg(obj_ihmm2_m3, nsim = 500, seed = 1) str(sim_ihmm2_m3[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into the incomplete states become less likely table(state = sim_ihmm2_m3$states, half = ifelse(seq_along(sim_ihmm2_m3$states) <= 250, "first", "second"))
Generates a sequence of observed process along with hidden state sequence
with class ihsmm.gamma, ihsmm.scpg and ihsmm.tscpg as typically returned
by ihsmm.scpg.
sim.ihsmm.scpg(ihsmmobj, nsim = 1, seed = NULL)sim.ihsmm.scpg(ihsmmobj, nsim = 1, seed = NULL)
ihsmmobj |
a model object with class |
nsim |
The number of interevent times to simulate. |
seed |
Seed for the random number generator, or |
Realizations are generated visit by visit as in
sim.hsmm.scpg, the succeeding state being drawn from the
zero-diagonal embedded transition probability matrix and the observations
of each visit from the state-dependent renewal process, with the difference
that the sojourn time of a visit is drawn from the shifted Poisson
distribution with parameter evaluated at the time
at which that visit commences. A given state is therefore governed by
different sojourn distributions according to the point of the record at
which it is entered.
Since the expected sojourn time in State 1 increases with elapsed time
while those in States decrease, realizations display a
characteristic drift: short and frequent visits to State 1 in the earlier
portion of the record, giving way to extended visits towards its end.
Simulation provides a direct means of assessing whether a given tdur
locates this drift within the intended span.
Generation terminates once nsim observations have been accumulated,
so that the sojourn in the last visited state is right-censored, in
accordance with the likelihood evaluated in fit.ihsmm.scpg.
Specifying seed renders the realization reproducible.
The returned object is an ihsmm.scpg with the same components
as input arguments in addition to the simulated sequence for the
observed process and states is the corresponding sequence of hidden
states of inhomogeneous Markov chain. This also provides the information
about the number of transitions of ISMC.
# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # Simulating a 2-state IHSMM with SCPG distribution sim_ihsmm1 <- sim.ihsmm.scpg(obj_ihsmm1, nsim = 150, seed = 3) str(sim_ihsmm1[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm1$states)$values) # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # Simulating a 3-state IHSMM with SCPG distribution sim_ihsmm1_m3 <- sim.ihsmm.scpg(obj_ihsmm1_m3, nsim = 150, seed = 1) print(sim_ihsmm1_m3) # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # Simulating a 2-state IHSMM with a TSCPG distribution sim_ihsmm2 <- sim.ihsmm.scpg(obj_ihsmm2, nsim = 200, seed = 1) str(sim_ihsmm2[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2$states)$values) # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3) # Simulating a 3-state IHSMM with a TSCPG distribution sim_ihsmm2_m3 <- sim.ihsmm.scpg(obj_ihsmm2_m3, nsim = 250, seed = 2) str(sim_ihsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the time-dependent components are evaluated # on [0, h_{T-1}] c(h_T1 = sum(sim_ihsmm2_m3$x[-250]), h_T = sum(sim_ihsmm2_m3$x)) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2_m3$states)$values)# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # Simulating a 2-state IHSMM with SCPG distribution sim_ihsmm1 <- sim.ihsmm.scpg(obj_ihsmm1, nsim = 150, seed = 3) str(sim_ihsmm1[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm1$states)$values) # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # Simulating a 3-state IHSMM with SCPG distribution sim_ihsmm1_m3 <- sim.ihsmm.scpg(obj_ihsmm1_m3, nsim = 150, seed = 1) print(sim_ihsmm1_m3) # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # Simulating a 2-state IHSMM with a TSCPG distribution sim_ihsmm2 <- sim.ihsmm.scpg(obj_ihsmm2, nsim = 200, seed = 1) str(sim_ihsmm2[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2$states)$values) # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3) # Simulating a 3-state IHSMM with a TSCPG distribution sim_ihsmm2_m3 <- sim.ihsmm.scpg(obj_ihsmm2_m3, nsim = 250, seed = 2) str(sim_ihsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the time-dependent components are evaluated # on [0, h_{T-1}] c(h_T1 = sum(sim_ihsmm2_m3$x[-250]), h_T = sum(sim_ihsmm2_m3$x)) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2_m3$states)$values)
Computes the probability of each hidden state at each time, given the whole
record, and the rescaled times used for residual analysis, for an HMM of
class hmm.gamma, hmm.scpg or hmm.tscpg.
sp.hmm.scpg(hmmobj)sp.hmm.scpg(hmmobj)
hmmobj |
An object created by |
Smoothed probabilities.
is computed by the
forward-backward algorithm (Baum et al., 1970),
with the forward variables of
fit.hmm.scpg and the backward variables
and
. Both are
rescaled at each step on the log scale. Choosing at each the state
with the largest (local decoding) can give a sequence that
the model does not allow; vip.hmm.scpg gives the most probable
sequence as a whole. The smoothed probabilities show how certain the state
assignment is at each time.
Residuals. If a point process model is correct, its integrated
intensity at the occurrence times, , forms a
Poisson process of unit rate (Berman, 1983; Ogata, 1988; Daley and
Vere-Jones, 2003, Theorem 7.4.I). Since the state is hidden, the rescaled
times are computed by weighting the integrated hazard of each state by the
smoothed probabilities,
where is the survival function in State . To check the fit,
plot the cumulative number of events minus the rescaled time, , against : for a well-fitting model it stays within the
Kolmogorov-Smirnov bands (95 per cent) and
(99 per cent) (Wang et al., 2012). Because the
weights use the whole record, the individual increments
are not exactly unit exponential even for the true
model, so they should not be tested one by one. The check assesses the fitted
model as a whole, not the decoded states.
A list with smoothed.prob, the matrix of
, and residuals, the rescaled times
.
Baum LE, Petrie T, Soules G, Weiss N (1970). “A maximization technique occurring in the statistical analysis of probabilistic functions of Markov chains.” The Annals of Mathematical Statistics, 41(1), 164-171. doi:10.1214/aoms/1177697196.
Berman M (1983). “Comment on “Likelihood analysis of point processes and its applications to seismological data” by Ogata.” Bulletin of the International Statistical Institute, 50, 412-418.
Ogata Y (1988). “Statistical models for earthquake occurrences and residual analysis for point processes.” Journal of the American Statistical Association, 83(401), 9-27.
Wang T, Bebbington MS, Harte D (2012). “Markov-modulated Hawkes process with stepwise decay.” Annals of the Institute of Statistical Mathematics, 64, 521-544. doi:10.1007/s10463-010-0320-7.
Daley DJ, Vere-Jones D (2003). An Introduction to the Theory of Point Processes. Springer, New York. doi:10.1007/b97277.
# ========================================================== # An example of a 2-state HMM with a TSCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.3 at the start of the record towards K = 0.5, around # the inflection time P/R = 300 of the last occurrence time h_{t-1}. The # hidden chain is homogeneous, so only lambda_2(t) changes along the record. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 5 # M rate[3, ] <- 0.01 # R rate[4, ] <- 3 # P: inflection time P/R = 300 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with TSCPG distribution obj_hmm2 <- hmm.scpg(x = NULL, mc.par, scpg.par) class(obj_hmm2) # Simulating a 2-state HMM with TSCPG distribution sim_hmm2 <- sim.hmm.scpg(obj_hmm2, nsim = 200, seed = 1) str(sim_hmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hmm2$x[-200]), h_T = sum(sim_hmm2$x)) # Fitting a 2-state HMM with TSCPG distributions # (the parameters of obj_hmm2 are the starting values) fit_hmm2 <- fit.hmm.scpg(sim_hmm2) # transition matrix (true rows 0.9, 0.1 and 0.2, 0.8) fit_hmm2$mc.par$tpm fit_hmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_hmm2$scpg.par$scale # true 1 fit_hmm2$logLik # Smoothed state probabilities and residuals for the fitted 2-state HMM # with TSCPG distribution fit_hmm2$x <- sim_hmm2$x sp_hmm2 <- sp.hmm.scpg(fit_hmm2) # Poisson mean lambda_2(t), fitted and true, at the last occurrence times # h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_hmm2 <- c(0, cumsum(sim_hmm2$x)[-200]) lam_hmm2 <- lambda_t(fit_hmm2$scpg.par$rate[, 1], h_hmm2) lam0_hmm2 <- lambda_t(obj_hmm2$scpg.par$rate[, 1], h_hmm2) gam_hmm2 <- sp_hmm2$smoothed.prob q_hmm2 <- cut(seq_along(h_hmm2), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # State 2 (row state.2). The true proportion (row p.true) is 1 in State 1 # and 1/(2 + lambda_2(t)) in State 2. p_t follows the true proportion. In an # HMM the transition probabilities do not depend on time, so the share of # State 1 varies only by chance; the proportion recorded in State 2 rises # from quarter to quarter as lambda_2(t) falls. p_hmm2 <- gam_hmm2[, 1] + gam_hmm2[, 2] / (2 + lam_hmm2) p0_hmm2 <- ifelse(sim_hmm2$states == 1, 1, 1 / (2 + lam0_hmm2)) rbind(p = tapply(p_hmm2, q_hmm2, mean), state.1 = tapply(gam_hmm2[, 1], q_hmm2, mean), state.2 = tapply(gam_hmm2[, 2] / (2 + lam_hmm2), q_hmm2, sum) / tapply(gam_hmm2[, 2], q_hmm2, sum), p.true = tapply(p0_hmm2, q_hmm2, mean)) # Plotting of residuals to check whether the fitted HMM with TSCPG renewal # process is a good fit dev.new() res_hmm2 <- sp_hmm2$residuals lres_hmm2 <- length(sp_hmm2$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hmm2, 1:lres_hmm2-res_hmm2, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hmm2, (1:lres_hmm2-sqrt(lres_hmm2)*1.36)-1:lres_hmm2, type="l", lty=2) lines(res_hmm2, (1:lres_hmm2+sqrt(lres_hmm2)*1.36)-1:lres_hmm2, type="l", lty=2) # 99% CI lines(res_hmm2, (1:lres_hmm2-sqrt(lres_hmm2)*1.63)-1:lres_hmm2, type="l", lty=3) lines(res_hmm2, (1:lres_hmm2+sqrt(lres_hmm2)*1.63)-1:lres_hmm2, type="l", lty=3) lines(res_hmm2, rep(0, lres_hmm2), col="red") par(oldpar) # ======================================================== # An example of a 3-state HMM with a TSCPG renewal process # ======================================================== # Fitting this 3-state model takes about 30 seconds on a laptop (the # 2-state model above takes about 4 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.50, 0.30, 0.20, 0.25, 0.50, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(1, 1) # K rate[2, ] <- c(1.5, 2.5) # M rate[3, ] <- c(0.02, 0.015) # R rate[4, ] <- c(3, 3) # P: inflection times P/R = 150 and 200 shape <- 1 scale <- 1.7 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with TSCPG distribution obj_hmm2_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) # Simulating a 3-state HMM with TSCPG distribution sim_hmm2_m3 <- sim.hmm.scpg(obj_hmm2_m3, nsim=100, seed=9) # Fitting a 3-state HMM with TSCPG distributions # The fit takes about 30 seconds, so it is wrapped in donttest. fit_hmm2_m3 <- fit.hmm.scpg(sim_hmm2_m3) print(fit_hmm2_m3) # Computing smoothed probabilities of fitted 3-state HMM with TSCPG # distribution fit_hmm2_m3$x=sim_hmm2_m3$x sp_hmm2_m3 <- sp.hmm.scpg(fit_hmm2_m3) print(sp_hmm2_m3) # Plotting of residuals to check whether the fitted HMM with TSCPG renewal # process is a good fit. dev.new() res_hmm2_m3 <- sp_hmm2_m3$residuals lres_hmm2_m3 <- length(sp_hmm2_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hmm2_m3, 1:lres_hmm2_m3-res_hmm2_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hmm2_m3, (1:lres_hmm2_m3-sqrt(lres_hmm2_m3)*1.36)-1:lres_hmm2_m3, type="l", lty=2) lines(res_hmm2_m3, (1:lres_hmm2_m3+sqrt(lres_hmm2_m3)*1.36)-1:lres_hmm2_m3, type="l", lty=2) # 99% CI lines(res_hmm2_m3, (1:lres_hmm2_m3-sqrt(lres_hmm2_m3)*1.63)-1:lres_hmm2_m3, type="l", lty=3) lines(res_hmm2_m3, (1:lres_hmm2_m3+sqrt(lres_hmm2_m3)*1.63)-1:lres_hmm2_m3, type="l", lty=3) lines(res_hmm2_m3, rep(0, lres_hmm2_m3), col="red") par(oldpar)# ========================================================== # An example of a 2-state HMM with a TSCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.3 at the start of the record towards K = 0.5, around # the inflection time P/R = 300 of the last occurrence time h_{t-1}. The # hidden chain is homogeneous, so only lambda_2(t) changes along the record. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 5 # M rate[3, ] <- 0.01 # R rate[4, ] <- 3 # P: inflection time P/R = 300 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with TSCPG distribution obj_hmm2 <- hmm.scpg(x = NULL, mc.par, scpg.par) class(obj_hmm2) # Simulating a 2-state HMM with TSCPG distribution sim_hmm2 <- sim.hmm.scpg(obj_hmm2, nsim = 200, seed = 1) str(sim_hmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hmm2$x[-200]), h_T = sum(sim_hmm2$x)) # Fitting a 2-state HMM with TSCPG distributions # (the parameters of obj_hmm2 are the starting values) fit_hmm2 <- fit.hmm.scpg(sim_hmm2) # transition matrix (true rows 0.9, 0.1 and 0.2, 0.8) fit_hmm2$mc.par$tpm fit_hmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_hmm2$scpg.par$scale # true 1 fit_hmm2$logLik # Smoothed state probabilities and residuals for the fitted 2-state HMM # with TSCPG distribution fit_hmm2$x <- sim_hmm2$x sp_hmm2 <- sp.hmm.scpg(fit_hmm2) # Poisson mean lambda_2(t), fitted and true, at the last occurrence times # h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_hmm2 <- c(0, cumsum(sim_hmm2$x)[-200]) lam_hmm2 <- lambda_t(fit_hmm2$scpg.par$rate[, 1], h_hmm2) lam0_hmm2 <- lambda_t(obj_hmm2$scpg.par$rate[, 1], h_hmm2) gam_hmm2 <- sp_hmm2$smoothed.prob q_hmm2 <- cut(seq_along(h_hmm2), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # State 2 (row state.2). The true proportion (row p.true) is 1 in State 1 # and 1/(2 + lambda_2(t)) in State 2. p_t follows the true proportion. In an # HMM the transition probabilities do not depend on time, so the share of # State 1 varies only by chance; the proportion recorded in State 2 rises # from quarter to quarter as lambda_2(t) falls. p_hmm2 <- gam_hmm2[, 1] + gam_hmm2[, 2] / (2 + lam_hmm2) p0_hmm2 <- ifelse(sim_hmm2$states == 1, 1, 1 / (2 + lam0_hmm2)) rbind(p = tapply(p_hmm2, q_hmm2, mean), state.1 = tapply(gam_hmm2[, 1], q_hmm2, mean), state.2 = tapply(gam_hmm2[, 2] / (2 + lam_hmm2), q_hmm2, sum) / tapply(gam_hmm2[, 2], q_hmm2, sum), p.true = tapply(p0_hmm2, q_hmm2, mean)) # Plotting of residuals to check whether the fitted HMM with TSCPG renewal # process is a good fit dev.new() res_hmm2 <- sp_hmm2$residuals lres_hmm2 <- length(sp_hmm2$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hmm2, 1:lres_hmm2-res_hmm2, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hmm2, (1:lres_hmm2-sqrt(lres_hmm2)*1.36)-1:lres_hmm2, type="l", lty=2) lines(res_hmm2, (1:lres_hmm2+sqrt(lres_hmm2)*1.36)-1:lres_hmm2, type="l", lty=2) # 99% CI lines(res_hmm2, (1:lres_hmm2-sqrt(lres_hmm2)*1.63)-1:lres_hmm2, type="l", lty=3) lines(res_hmm2, (1:lres_hmm2+sqrt(lres_hmm2)*1.63)-1:lres_hmm2, type="l", lty=3) lines(res_hmm2, rep(0, lres_hmm2), col="red") par(oldpar) # ======================================================== # An example of a 3-state HMM with a TSCPG renewal process # ======================================================== # Fitting this 3-state model takes about 30 seconds on a laptop (the # 2-state model above takes about 4 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.50, 0.30, 0.20, 0.25, 0.50, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(1, 1) # K rate[2, ] <- c(1.5, 2.5) # M rate[3, ] <- c(0.02, 0.015) # R rate[4, ] <- c(3, 3) # P: inflection times P/R = 150 and 200 shape <- 1 scale <- 1.7 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with TSCPG distribution obj_hmm2_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) # Simulating a 3-state HMM with TSCPG distribution sim_hmm2_m3 <- sim.hmm.scpg(obj_hmm2_m3, nsim=100, seed=9) # Fitting a 3-state HMM with TSCPG distributions # The fit takes about 30 seconds, so it is wrapped in donttest. fit_hmm2_m3 <- fit.hmm.scpg(sim_hmm2_m3) print(fit_hmm2_m3) # Computing smoothed probabilities of fitted 3-state HMM with TSCPG # distribution fit_hmm2_m3$x=sim_hmm2_m3$x sp_hmm2_m3 <- sp.hmm.scpg(fit_hmm2_m3) print(sp_hmm2_m3) # Plotting of residuals to check whether the fitted HMM with TSCPG renewal # process is a good fit. dev.new() res_hmm2_m3 <- sp_hmm2_m3$residuals lres_hmm2_m3 <- length(sp_hmm2_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hmm2_m3, 1:lres_hmm2_m3-res_hmm2_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hmm2_m3, (1:lres_hmm2_m3-sqrt(lres_hmm2_m3)*1.36)-1:lres_hmm2_m3, type="l", lty=2) lines(res_hmm2_m3, (1:lres_hmm2_m3+sqrt(lres_hmm2_m3)*1.36)-1:lres_hmm2_m3, type="l", lty=2) # 99% CI lines(res_hmm2_m3, (1:lres_hmm2_m3-sqrt(lres_hmm2_m3)*1.63)-1:lres_hmm2_m3, type="l", lty=3) lines(res_hmm2_m3, (1:lres_hmm2_m3+sqrt(lres_hmm2_m3)*1.63)-1:lres_hmm2_m3, type="l", lty=3) lines(res_hmm2_m3, rep(0, lres_hmm2_m3), col="red") par(oldpar)
Calculates the probability of being in State at time for an HSMM with class
hsmm.gamma, hsmm.scpg and hsmm.tscpg as typically returned
by hsmm.scpg.
sp.hsmm.scpg(hsmmobj)sp.hsmm.scpg(hsmmobj)
hsmmobj |
is a model object with class |
For a hidden semi-Markov model the smoothed probability
cannot be formed from
the forward and backward variables of an HMM, the hidden path being a
sequence of visits rather than of states. It is obtained by the
forward-backward algorithm, in which the forward variable
of fit.hsmm.scpg records that a visit to
State ends at time and the backward variable
the complementary conditional probability. Writing
and for the
corresponding quantities at the commencement of a visit, the smoothed
probability satisfies the backward recursion
with , the two subtracted terms
being the conditional probabilities that a visit to State ends at
and that one commences at . The shifted Poisson sojourn mass function
determines the number of visits completed within the record, while the corresponding survival
function addresses visits that are right-censored at .The
recursions are scaled at each time step.
The globally optimal sequence of visits, with their durations, is obtained
from vip.hsmm.scpg.
The residual process returned alongside the smoothed probabilities provides
the goodness-of-fit assessment of the fitted model as a point process
(Berman, 1983; Ogata, 1988; Wang et al., 2012, Shahzadi et al., 2023,2026), see
sp.hmm.scpg
returns an matrix for the smoothed probabilities and a numeric vector
of residuals from an HSMM with class hsmm.scpg.
Berman M (1983). “Comment on “Likelihood analysis of point processes and its applications to seismological data” by Ogata.” Bulletin of the International Statistical Institute, 50, 412-418.
Ogata Y (1988). “Statistical models for earthquake occurrences and residual analysis for point processes.” Journal of the American Statistical Association, 83(401), 9-27.
Wang T, Bebbington MS, Harte D (2012). “Markov-modulated Hawkes process with stepwise decay.” Annals of the Institute of Statistical Mathematics, 64, 521-544. doi:10.1007/s10463-010-0320-7.
Shahzadi A, Wang T, Parry M, Bebbington M (2023). “Inhomogeneous hidden semi-Markov models for incompletely observed point processes.” Annals of Institute Statistical Mathematics, 75, 253-280. doi:10.1007/s10463-022-00843-5.
Shahzadi A, Wang T, Parry M, Bebbington M (2026). “Modelling time-inhomogeneous incomplete records of point processes using variants of hidden Markov models.” Advances in Data Analysis and Classification, 20, 663-691. doi:10.1007/s11634-025-00632-x.
# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # Simulating a 2-state HSMM with SCPG distribution sim_hsmm1 <- sim.hsmm.scpg(obj_hsmm1, nsim = 150, seed = 1) str(sim_hsmm1[c("x", "states")]) # Number of visits to each state in the simulated path table(rle(sim_hsmm1$states)$values) # Fitting a 2-state HSMM with SCPG distributions # (the parameters of obj_hsmm1 are the starting values) fit_hsmm1 <- fit.hsmm.scpg(sim_hsmm1) fit_hsmm1$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm1$scpg.par$rate # lambda_2 (true 3) fit_hsmm1$scpg.par$shape # alpha (true 1.5) fit_hsmm1$scpg.par$scale # beta (true 1) fit_hsmm1$logLik # Smoothed probabilities for a 2-state HSMM with SCPG distribution fit_hsmm1$x <- sim_hsmm1$x # Computing smoothed probabilities and residuals sp_hsmm1 <- sp.hsmm.scpg(fit_hsmm1) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2), averaged over the # record and compared with the true proportion (1 in State 1 and # 1/(2 + lambda_2) in State 2) p_hsmm1 <- sp_hsmm1$smoothed.prob[, 1] + sp_hsmm1$smoothed.prob[, 2] / (2 + fit_hsmm1$scpg.par$rate[1, 1]) c(estimated = mean(p_hsmm1), true = mean(ifelse(sim_hsmm1$states == 1, 1, 1 / (2 + obj_hsmm1$scpg.par$rate[1, 1])))) # Plotting of residuals to check whether the fitted HSMM with SCPG renewal # process is a good fit. dev.new() res_hsmm1 <- sp_hsmm1$residuals lres_hsmm1 <- length(sp_hsmm1$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hsmm1, 1:lres_hsmm1-res_hsmm1, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hsmm1, (1:lres_hsmm1-sqrt(lres_hsmm1)*1.36)-1:lres_hsmm1, type="l", lty=2) lines(res_hsmm1, (1:lres_hsmm1+sqrt(lres_hsmm1)*1.36)-1:lres_hsmm1, type="l", lty=2) # 99% CI lines(res_hsmm1, (1:lres_hsmm1-sqrt(lres_hsmm1)*1.63)-1:lres_hsmm1, type="l", lty=3) lines(res_hsmm1, (1:lres_hsmm1+sqrt(lres_hsmm1)*1.63)-1:lres_hsmm1, type="l", lty=3) lines(res_hsmm1, rep(0, lres_hsmm1), col="red") par(oldpar) # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # Simulating a 3-state HSMM with SCPG distribution sim_hsmm1_m3 <- sim.hsmm.scpg(obj_hsmm1_m3, nsim = 80, seed = 1) print(sim_hsmm1_m3) # Fitting a 3-state HSMM with SCPG distributions # The fit takes about 15 seconds, so it is wrapped in donttest. fit_hsmm1_m3 <- fit.hsmm.scpg(sim_hsmm1_m3) print(fit_hsmm1_m3) # Smoothed probabilities for a 3-state HSMM with SCPG distribution fit_hsmm1_m3$x <- sim_hsmm1_m3$x # Computing smoothed probabilities and residuals sp_hsmm1_m3 <- sp.hsmm.scpg(fit_hsmm1_m3) # Plotting of residuals to check whether the fitted HSMM with SCPG renewal # process is a good fit. dev.new() res_hsmm1_m3 <- sp_hsmm1_m3$residuals lres_hsmm1_m3 <- length(sp_hsmm1_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hsmm1_m3, 1:lres_hsmm1_m3-res_hsmm1_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hsmm1_m3, (1:lres_hsmm1_m3-sqrt(lres_hsmm1_m3)*1.36)-1:lres_hsmm1_m3, type="l", lty=2) lines(res_hsmm1_m3, (1:lres_hsmm1_m3+sqrt(lres_hsmm1_m3)*1.36)-1:lres_hsmm1_m3, type="l", lty=2) # 99% CI lines(res_hsmm1_m3, (1:lres_hsmm1_m3-sqrt(lres_hsmm1_m3)*1.63)-1:lres_hsmm1_m3, type="l", lty=3) lines(res_hsmm1_m3, (1:lres_hsmm1_m3+sqrt(lres_hsmm1_m3)*1.63)-1:lres_hsmm1_m3, type="l", lty=3) lines(res_hsmm1_m3, rep(0, lres_hsmm1_m3), col="red") par(oldpar) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # Simulating a 2-state HSMM with a TSCPG distribution sim_hsmm2 <- sim.hsmm.scpg(obj_hsmm2, nsim = 300, seed = 3) str(sim_hsmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2$x[-300]), h_T = sum(sim_hsmm2$x)) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2 are the starting values) fit_hsmm2 <- fit.hsmm.scpg(sim_hsmm2) fit_hsmm2$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_hsmm2$scpg.par$scale # true 1 fit_hsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Smoothed state probabilities and residuals for the fitted 2-state HSMM # with TSCPG distribution fit_hsmm2$x <- sim_hsmm2$x sp_hsmm2 <- sp.hsmm.scpg(fit_hsmm2) # Poisson mean lambda_2(t), fitted and true, at the last occurrence times # h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_hsmm2 <- c(0, cumsum(sim_hsmm2$x)[-300]) lam_hsmm2 <- lambda_t(fit_hsmm2$scpg.par$rate[, 1], h_hsmm2) lam0_hsmm2 <- lambda_t(obj_hsmm2$scpg.par$rate[, 1], h_hsmm2) gam_hsmm2 <- sp_hsmm2$smoothed.prob q_hsmm2 <- cut(seq_along(h_hsmm2), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # State 2 (row state.2). The true proportion (row p.true) is 1 in State 1 # and 1/(2 + lambda_2(t)) in State 2. In an HSMM the sojourns do not depend # on time, so the share of State 1 varies only by chance; the proportion # recorded in State 2 rises as lambda_2(t) falls. p_hsmm2 <- gam_hsmm2[, 1] + gam_hsmm2[, 2] / (2 + lam_hsmm2) p0_hsmm2 <- ifelse(sim_hsmm2$states == 1, 1, 1 / (2 + lam0_hsmm2)) rbind(p = tapply(p_hsmm2, q_hsmm2, mean), state.1 = tapply(gam_hsmm2[, 1], q_hsmm2, mean), state.2 = tapply(gam_hsmm2[, 2] / (2 + lam_hsmm2), q_hsmm2, sum) / tapply(gam_hsmm2[, 2], q_hsmm2, sum), p.true = tapply(p0_hsmm2, q_hsmm2, mean)) # Plotting the residuals (cumulative number of events minus rescaled time) # with Kolmogorov-Smirnov bands, to check whether the fitted model is a good # fit dev.new() res_hsmm2 <- sp_hsmm2$residuals lres_hsmm2 <- length(sp_hsmm2$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hsmm2, 1:lres_hsmm2-res_hsmm2, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hsmm2, (1:lres_hsmm2-sqrt(lres_hsmm2)*1.36)-1:lres_hsmm2, type="l", lty=2) lines(res_hsmm2, (1:lres_hsmm2+sqrt(lres_hsmm2)*1.36)-1:lres_hsmm2, type="l", lty=2) # 99% CI lines(res_hsmm2, (1:lres_hsmm2-sqrt(lres_hsmm2)*1.63)-1:lres_hsmm2, type="l", lty=3) lines(res_hsmm2, (1:lres_hsmm2+sqrt(lres_hsmm2)*1.63)-1:lres_hsmm2, type="l", lty=3) lines(res_hsmm2, rep(0, lres_hsmm2), col="red") par(oldpar) # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3) # Simulating a 3-state HSMM with a TSCPG distribution sim_hsmm2_m3 <- sim.hsmm.scpg(obj_hsmm2_m3, nsim = 400, seed = 3) str(sim_hsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rates are evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2_m3$x[-400]), h_T = sum(sim_hsmm2_m3$x)) # Number of visits to each state in the simulated path table(rle(sim_hsmm2_m3$states)$values) # Fitting a 3-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2_m3 are the starting values). The fit # takes about 2 minutes, so it is wrapped in donttest. fit_hsmm2_m3 <- fit.hsmm.scpg(sim_hsmm2_m3) fit_hsmm2_m3$smc.par$tpm # transition matrix of the embedded chain # sojourn parameters mu_1, mu_2, mu_3 (true 4, 3, 3) fit_hsmm2_m3$smc.par$dur fit_hsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_hsmm2_m3$scpg.par$scale # true 0.5 fit_hsmm2_m3$logLik # Smoothed state probabilities and residuals for the fitted 3-state HSMM # with TSCPG distribution fit_hsmm2_m3$x <- sim_hsmm2_m3$x sp_hsmm2_m3 <- sp.hsmm.scpg(fit_hsmm2_m3) # Poisson means lambda_2(t) and lambda_3(t), fitted and true, at the last # occurrence times h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_hsmm2_m3 <- c(0, cumsum(sim_hsmm2_m3$x)[-400]) lam_hsmm2_m3 <- sapply(1:2, function(j) lambda_t(fit_hsmm2_m3$scpg.par$rate[, j], h_hsmm2_m3)) lam0_hsmm2_m3 <- sapply(1:2, function(j) lambda_t(obj_hsmm2_m3$scpg.par$rate[, j], h_hsmm2_m3)) gam_hsmm2_m3 <- sp_hsmm2_m3$smoothed.prob q_hsmm2_m3 <- cut(seq_along(h_hsmm2_m3), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + sum_j Pr(S_t = j | x) / (2 + lambda_j(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # States 2 and 3 (row states.2.3). The true proportion (row p.true) is 1 # in State 1 and 1/(2 + lambda_j(t)) in State j. In an HSMM the sojourns # do not depend on time, so the share of State 1 varies only by chance; # the proportion recorded in States 2 and 3 rises from quarter to quarter # as lambda_2(t) and lambda_3(t) fall. p_hsmm2_m3 <- gam_hsmm2_m3[, 1] + rowSums(gam_hsmm2_m3[, 2:3] / (2 + lam_hsmm2_m3)) s_hsmm2_m3 <- sim_hsmm2_m3$states p0_hsmm2_m3 <- ifelse(s_hsmm2_m3 == 1, 1, 1 / (2 + lam0_hsmm2_m3[cbind(seq_along(s_hsmm2_m3), pmax(s_hsmm2_m3 - 1, 1))])) rbind(p = tapply(p_hsmm2_m3, q_hsmm2_m3, mean), state.1 = tapply(gam_hsmm2_m3[, 1], q_hsmm2_m3, mean), states.2.3 = tapply(rowSums(gam_hsmm2_m3[, 2:3] / (2 + lam_hsmm2_m3)), q_hsmm2_m3, sum) / tapply(rowSums(gam_hsmm2_m3[, 2:3]), q_hsmm2_m3, sum), p.true = tapply(p0_hsmm2_m3, q_hsmm2_m3, mean)) # Plotting the residuals (cumulative number of events minus rescaled time) # with Kolmogorov-Smirnov bands, to check whether the fitted model is a good # fit dev.new() res_hsmm2_m3 <- sp_hsmm2_m3$residuals lres_hsmm2_m3 <- length(sp_hsmm2_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hsmm2_m3, 1:lres_hsmm2_m3-res_hsmm2_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hsmm2_m3, (1:lres_hsmm2_m3-sqrt(lres_hsmm2_m3)*1.36)-1:lres_hsmm2_m3, type="l", lty=2) lines(res_hsmm2_m3, (1:lres_hsmm2_m3+sqrt(lres_hsmm2_m3)*1.36)-1:lres_hsmm2_m3, type="l", lty=2) # 99% CI lines(res_hsmm2_m3, (1:lres_hsmm2_m3-sqrt(lres_hsmm2_m3)*1.63)-1:lres_hsmm2_m3, type="l", lty=3) lines(res_hsmm2_m3, (1:lres_hsmm2_m3+sqrt(lres_hsmm2_m3)*1.63)-1:lres_hsmm2_m3, type="l", lty=3) lines(res_hsmm2_m3, rep(0, lres_hsmm2_m3), col="red") par(oldpar)# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # Simulating a 2-state HSMM with SCPG distribution sim_hsmm1 <- sim.hsmm.scpg(obj_hsmm1, nsim = 150, seed = 1) str(sim_hsmm1[c("x", "states")]) # Number of visits to each state in the simulated path table(rle(sim_hsmm1$states)$values) # Fitting a 2-state HSMM with SCPG distributions # (the parameters of obj_hsmm1 are the starting values) fit_hsmm1 <- fit.hsmm.scpg(sim_hsmm1) fit_hsmm1$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm1$scpg.par$rate # lambda_2 (true 3) fit_hsmm1$scpg.par$shape # alpha (true 1.5) fit_hsmm1$scpg.par$scale # beta (true 1) fit_hsmm1$logLik # Smoothed probabilities for a 2-state HSMM with SCPG distribution fit_hsmm1$x <- sim_hsmm1$x # Computing smoothed probabilities and residuals sp_hsmm1 <- sp.hsmm.scpg(fit_hsmm1) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2), averaged over the # record and compared with the true proportion (1 in State 1 and # 1/(2 + lambda_2) in State 2) p_hsmm1 <- sp_hsmm1$smoothed.prob[, 1] + sp_hsmm1$smoothed.prob[, 2] / (2 + fit_hsmm1$scpg.par$rate[1, 1]) c(estimated = mean(p_hsmm1), true = mean(ifelse(sim_hsmm1$states == 1, 1, 1 / (2 + obj_hsmm1$scpg.par$rate[1, 1])))) # Plotting of residuals to check whether the fitted HSMM with SCPG renewal # process is a good fit. dev.new() res_hsmm1 <- sp_hsmm1$residuals lres_hsmm1 <- length(sp_hsmm1$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hsmm1, 1:lres_hsmm1-res_hsmm1, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hsmm1, (1:lres_hsmm1-sqrt(lres_hsmm1)*1.36)-1:lres_hsmm1, type="l", lty=2) lines(res_hsmm1, (1:lres_hsmm1+sqrt(lres_hsmm1)*1.36)-1:lres_hsmm1, type="l", lty=2) # 99% CI lines(res_hsmm1, (1:lres_hsmm1-sqrt(lres_hsmm1)*1.63)-1:lres_hsmm1, type="l", lty=3) lines(res_hsmm1, (1:lres_hsmm1+sqrt(lres_hsmm1)*1.63)-1:lres_hsmm1, type="l", lty=3) lines(res_hsmm1, rep(0, lres_hsmm1), col="red") par(oldpar) # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # Simulating a 3-state HSMM with SCPG distribution sim_hsmm1_m3 <- sim.hsmm.scpg(obj_hsmm1_m3, nsim = 80, seed = 1) print(sim_hsmm1_m3) # Fitting a 3-state HSMM with SCPG distributions # The fit takes about 15 seconds, so it is wrapped in donttest. fit_hsmm1_m3 <- fit.hsmm.scpg(sim_hsmm1_m3) print(fit_hsmm1_m3) # Smoothed probabilities for a 3-state HSMM with SCPG distribution fit_hsmm1_m3$x <- sim_hsmm1_m3$x # Computing smoothed probabilities and residuals sp_hsmm1_m3 <- sp.hsmm.scpg(fit_hsmm1_m3) # Plotting of residuals to check whether the fitted HSMM with SCPG renewal # process is a good fit. dev.new() res_hsmm1_m3 <- sp_hsmm1_m3$residuals lres_hsmm1_m3 <- length(sp_hsmm1_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hsmm1_m3, 1:lres_hsmm1_m3-res_hsmm1_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hsmm1_m3, (1:lres_hsmm1_m3-sqrt(lres_hsmm1_m3)*1.36)-1:lres_hsmm1_m3, type="l", lty=2) lines(res_hsmm1_m3, (1:lres_hsmm1_m3+sqrt(lres_hsmm1_m3)*1.36)-1:lres_hsmm1_m3, type="l", lty=2) # 99% CI lines(res_hsmm1_m3, (1:lres_hsmm1_m3-sqrt(lres_hsmm1_m3)*1.63)-1:lres_hsmm1_m3, type="l", lty=3) lines(res_hsmm1_m3, (1:lres_hsmm1_m3+sqrt(lres_hsmm1_m3)*1.63)-1:lres_hsmm1_m3, type="l", lty=3) lines(res_hsmm1_m3, rep(0, lres_hsmm1_m3), col="red") par(oldpar) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # Simulating a 2-state HSMM with a TSCPG distribution sim_hsmm2 <- sim.hsmm.scpg(obj_hsmm2, nsim = 300, seed = 3) str(sim_hsmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2$x[-300]), h_T = sum(sim_hsmm2$x)) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2 are the starting values) fit_hsmm2 <- fit.hsmm.scpg(sim_hsmm2) fit_hsmm2$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_hsmm2$scpg.par$scale # true 1 fit_hsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Smoothed state probabilities and residuals for the fitted 2-state HSMM # with TSCPG distribution fit_hsmm2$x <- sim_hsmm2$x sp_hsmm2 <- sp.hsmm.scpg(fit_hsmm2) # Poisson mean lambda_2(t), fitted and true, at the last occurrence times # h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_hsmm2 <- c(0, cumsum(sim_hsmm2$x)[-300]) lam_hsmm2 <- lambda_t(fit_hsmm2$scpg.par$rate[, 1], h_hsmm2) lam0_hsmm2 <- lambda_t(obj_hsmm2$scpg.par$rate[, 1], h_hsmm2) gam_hsmm2 <- sp_hsmm2$smoothed.prob q_hsmm2 <- cut(seq_along(h_hsmm2), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # State 2 (row state.2). The true proportion (row p.true) is 1 in State 1 # and 1/(2 + lambda_2(t)) in State 2. In an HSMM the sojourns do not depend # on time, so the share of State 1 varies only by chance; the proportion # recorded in State 2 rises as lambda_2(t) falls. p_hsmm2 <- gam_hsmm2[, 1] + gam_hsmm2[, 2] / (2 + lam_hsmm2) p0_hsmm2 <- ifelse(sim_hsmm2$states == 1, 1, 1 / (2 + lam0_hsmm2)) rbind(p = tapply(p_hsmm2, q_hsmm2, mean), state.1 = tapply(gam_hsmm2[, 1], q_hsmm2, mean), state.2 = tapply(gam_hsmm2[, 2] / (2 + lam_hsmm2), q_hsmm2, sum) / tapply(gam_hsmm2[, 2], q_hsmm2, sum), p.true = tapply(p0_hsmm2, q_hsmm2, mean)) # Plotting the residuals (cumulative number of events minus rescaled time) # with Kolmogorov-Smirnov bands, to check whether the fitted model is a good # fit dev.new() res_hsmm2 <- sp_hsmm2$residuals lres_hsmm2 <- length(sp_hsmm2$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hsmm2, 1:lres_hsmm2-res_hsmm2, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hsmm2, (1:lres_hsmm2-sqrt(lres_hsmm2)*1.36)-1:lres_hsmm2, type="l", lty=2) lines(res_hsmm2, (1:lres_hsmm2+sqrt(lres_hsmm2)*1.36)-1:lres_hsmm2, type="l", lty=2) # 99% CI lines(res_hsmm2, (1:lres_hsmm2-sqrt(lres_hsmm2)*1.63)-1:lres_hsmm2, type="l", lty=3) lines(res_hsmm2, (1:lres_hsmm2+sqrt(lres_hsmm2)*1.63)-1:lres_hsmm2, type="l", lty=3) lines(res_hsmm2, rep(0, lres_hsmm2), col="red") par(oldpar) # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3) # Simulating a 3-state HSMM with a TSCPG distribution sim_hsmm2_m3 <- sim.hsmm.scpg(obj_hsmm2_m3, nsim = 400, seed = 3) str(sim_hsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rates are evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2_m3$x[-400]), h_T = sum(sim_hsmm2_m3$x)) # Number of visits to each state in the simulated path table(rle(sim_hsmm2_m3$states)$values) # Fitting a 3-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2_m3 are the starting values). The fit # takes about 2 minutes, so it is wrapped in donttest. fit_hsmm2_m3 <- fit.hsmm.scpg(sim_hsmm2_m3) fit_hsmm2_m3$smc.par$tpm # transition matrix of the embedded chain # sojourn parameters mu_1, mu_2, mu_3 (true 4, 3, 3) fit_hsmm2_m3$smc.par$dur fit_hsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_hsmm2_m3$scpg.par$scale # true 0.5 fit_hsmm2_m3$logLik # Smoothed state probabilities and residuals for the fitted 3-state HSMM # with TSCPG distribution fit_hsmm2_m3$x <- sim_hsmm2_m3$x sp_hsmm2_m3 <- sp.hsmm.scpg(fit_hsmm2_m3) # Poisson means lambda_2(t) and lambda_3(t), fitted and true, at the last # occurrence times h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_hsmm2_m3 <- c(0, cumsum(sim_hsmm2_m3$x)[-400]) lam_hsmm2_m3 <- sapply(1:2, function(j) lambda_t(fit_hsmm2_m3$scpg.par$rate[, j], h_hsmm2_m3)) lam0_hsmm2_m3 <- sapply(1:2, function(j) lambda_t(obj_hsmm2_m3$scpg.par$rate[, j], h_hsmm2_m3)) gam_hsmm2_m3 <- sp_hsmm2_m3$smoothed.prob q_hsmm2_m3 <- cut(seq_along(h_hsmm2_m3), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + sum_j Pr(S_t = j | x) / (2 + lambda_j(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # States 2 and 3 (row states.2.3). The true proportion (row p.true) is 1 # in State 1 and 1/(2 + lambda_j(t)) in State j. In an HSMM the sojourns # do not depend on time, so the share of State 1 varies only by chance; # the proportion recorded in States 2 and 3 rises from quarter to quarter # as lambda_2(t) and lambda_3(t) fall. p_hsmm2_m3 <- gam_hsmm2_m3[, 1] + rowSums(gam_hsmm2_m3[, 2:3] / (2 + lam_hsmm2_m3)) s_hsmm2_m3 <- sim_hsmm2_m3$states p0_hsmm2_m3 <- ifelse(s_hsmm2_m3 == 1, 1, 1 / (2 + lam0_hsmm2_m3[cbind(seq_along(s_hsmm2_m3), pmax(s_hsmm2_m3 - 1, 1))])) rbind(p = tapply(p_hsmm2_m3, q_hsmm2_m3, mean), state.1 = tapply(gam_hsmm2_m3[, 1], q_hsmm2_m3, mean), states.2.3 = tapply(rowSums(gam_hsmm2_m3[, 2:3] / (2 + lam_hsmm2_m3)), q_hsmm2_m3, sum) / tapply(rowSums(gam_hsmm2_m3[, 2:3]), q_hsmm2_m3, sum), p.true = tapply(p0_hsmm2_m3, q_hsmm2_m3, mean)) # Plotting the residuals (cumulative number of events minus rescaled time) # with Kolmogorov-Smirnov bands, to check whether the fitted model is a good # fit dev.new() res_hsmm2_m3 <- sp_hsmm2_m3$residuals lres_hsmm2_m3 <- length(sp_hsmm2_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_hsmm2_m3, 1:lres_hsmm2_m3-res_hsmm2_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_hsmm2_m3, (1:lres_hsmm2_m3-sqrt(lres_hsmm2_m3)*1.36)-1:lres_hsmm2_m3, type="l", lty=2) lines(res_hsmm2_m3, (1:lres_hsmm2_m3+sqrt(lres_hsmm2_m3)*1.36)-1:lres_hsmm2_m3, type="l", lty=2) # 99% CI lines(res_hsmm2_m3, (1:lres_hsmm2_m3-sqrt(lres_hsmm2_m3)*1.63)-1:lres_hsmm2_m3, type="l", lty=3) lines(res_hsmm2_m3, (1:lres_hsmm2_m3+sqrt(lres_hsmm2_m3)*1.63)-1:lres_hsmm2_m3, type="l", lty=3) lines(res_hsmm2_m3, rep(0, lres_hsmm2_m3), col="red") par(oldpar)
Calculates the probability of being in State at time for an IHMM with class
ihmm.gamma, ihmm.scpg and ihmm.tscpg as typically returned
by ihmm.scpg.
sp.ihmm.scpg(ihmmobj)sp.ihmm.scpg(ihmmobj)
ihmmobj |
is a model object with class |
The smoothed probability
is obtained
by the forward-backward algorithm with the transition probabilities
replaced by their time-varying counterparts. With the forward variable
defined as in fit.ihmm.scpg and the
backward variable satisfying
the smoothed probability is
. Each step employs the
transition probability matrix reconstructed from the logistic coefficients
at the occurrence time accumulated to that point. Both recursions are
evaluated on the logarithmic scale with scaling at each time step.
Plotted against the occurrence times, the smoothed probability of State 1
provides the most direct evidence of the time inhomogeneity: under a
correctly specified model it increases along the record, and the interval
over which it rises estimates the period during which the record becomes
complete. As in the homogeneous case, the sequence of pointwise maximizers
need not be admissible under the model; the globally optimal sequence is
obtained from vip.ihmm.scpg.
The residual process returned alongside the smoothed probabilities provides
the goodness-of-fit assessment of the fitted model as a point process
(Berman, 1983; Ogata, 1988; Wang et al., 2012), see sp.hmm.scpg.
returns an matrix for the smoothed probabilities and a numeric vector
of residuals from an IHMM with class ihmm.scpg.
Berman M (1983). “Comment on “Likelihood analysis of point processes and its applications to seismological data” by Ogata.” Bulletin of the International Statistical Institute, 50, 412-418.
Ogata Y (1988). “Statistical models for earthquake occurrences and residual analysis for point processes.” Journal of the American Statistical Association, 83(401), 9-27.
Wang T, Bebbington MS, Harte D (2012). “Markov-modulated Hawkes process with stepwise decay.” Annals of the Institute of Statistical Mathematics, 64, 521-544. doi:10.1007/s10463-010-0320-7.
Daley DJ, Vere-Jones D (2003). An Introduction to the Theory of Point Processes. Springer, New York. doi:10.1007/b97277.
# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # Simulating a 2-state IHMM with SCPG distribution sim_ihmm1 <- sim.ihmm.scpg(obj_ihmm1, nsim = 200, seed = 1) str(sim_ihmm1[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm1$states, half = ifelse(seq_along(sim_ihmm1$states) <= 100, "first", "second")) # The fit takes about 6 s, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with SCPG distributions # (the parameters of obj_ihmm1 are the starting values) fit_ihmm1 <- fit.ihmm.scpg(sim_ihmm1) fit_ihmm1$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm1$scpg.par$rate # lambda_2 (true 3) fit_ihmm1$scpg.par$shape # true 1.5 fit_ihmm1$scpg.par$scale # true 1 fit_ihmm1$logLik # The fit takes about 6 s, so the code below is wrapped in donttest. # Smoothed probabilities for a 2-state IHMM with an SCPG distribution fit_ihmm1$x <- sim_ihmm1$x # Computing smoothed probabilities and residuals sp_ihmm1 <- sp.ihmm.scpg(fit_ihmm1) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2), averaged over the # four quarters of the record (row p) and compared with the true proportion # (row p.true: 1 in State 1 and 1/(2 + lambda_2) in State 2). With a # constant lambda_2 the rise comes from the transitions alone, which make # State 1 more frequent (row state.1). p_ihmm1 <- sp_ihmm1$smoothed.prob[, 1] + sp_ihmm1$smoothed.prob[, 2] / (2 + fit_ihmm1$scpg.par$rate[1, 1]) p0_ihmm1 <- ifelse(sim_ihmm1$states == 1, 1, 1 / (2 + obj_ihmm1$scpg.par$rate[1, 1])) q_ihmm1 <- cut(seq_along(p_ihmm1), 4) rbind(p = tapply(p_ihmm1, q_ihmm1, mean), state.1 = tapply(sp_ihmm1$smoothed.prob[, 1], q_ihmm1, mean), p.true = tapply(p0_ihmm1, q_ihmm1, mean)) # Plotting of residuals to check whether the fitted IHMM with SCPG renewal # process is a good fit. dev.new() res_ihmm1 <- sp_ihmm1$residuals lres_ihmm1 <- length(sp_ihmm1$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihmm1, 1:lres_ihmm1-res_ihmm1, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihmm1, (1:lres_ihmm1-sqrt(lres_ihmm1)*1.36)-1:lres_ihmm1, type="l", lty=2) lines(res_ihmm1, (1:lres_ihmm1+sqrt(lres_ihmm1)*1.36)-1:lres_ihmm1, type="l", lty=2) # 99% CI lines(res_ihmm1, (1:lres_ihmm1-sqrt(lres_ihmm1)*1.63)-1:lres_ihmm1, type="l", lty=3) lines(res_ihmm1, (1:lres_ihmm1+sqrt(lres_ihmm1)*1.63)-1:lres_ihmm1, type="l", lty=3) lines(res_ihmm1, rep(0, lres_ihmm1), col="red") par(oldpar) # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # Simulating a 3-state IHMM with SCPG distribution sim_ihmm1_m3 <- sim.ihmm.scpg(obj_ihmm1_m3, nsim = 200, seed = 2) print(sim_ihmm1_m3) # Fitting a 3-state IHMM with SCPG distributions # The fit takes about 1.5 minutes, so it is wrapped in donttest. fit_ihmm1_m3 <- fit.ihmm.scpg(sim_ihmm1_m3) print(fit_ihmm1_m3) # Smoothed probabilities for a 3-state IHMM with an SCPG distribution fit_ihmm1_m3$x=sim_ihmm1_m3$x # Computing smoothed probabilities and residuals sp_ihmm1_m3 <- sp.ihmm.scpg(fit_ihmm1_m3) # Plotting of residuals to check whether the fitted IHMM with SCPG renewal # process is a good fit. dev.new() res_ihmm1_m3 <- sp_ihmm1_m3$residuals lres_ihmm1_m3 <- length(sp_ihmm1_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihmm1_m3, 1:lres_ihmm1_m3-res_ihmm1_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihmm1_m3, (1:lres_ihmm1_m3-sqrt(lres_ihmm1_m3)*1.36)-1:lres_ihmm1_m3, type="l", lty=2) lines(res_ihmm1_m3, (1:lres_ihmm1_m3+sqrt(lres_ihmm1_m3)*1.36)-1:lres_ihmm1_m3, type="l", lty=2) # 99% CI lines(res_ihmm1_m3, (1:lres_ihmm1_m3-sqrt(lres_ihmm1_m3)*1.63)-1:lres_ihmm1_m3, type="l", lty=3) lines(res_ihmm1_m3, (1:lres_ihmm1_m3+sqrt(lres_ihmm1_m3)*1.63)-1:lres_ihmm1_m3, type="l", lty=3) lines(res_ihmm1_m3, rep(0, lres_ihmm1_m3), col="red") par(oldpar) # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # Simulating a 2-state IHMM with a TSCPG distribution sim_ihmm2 <- sim.ihmm.scpg(obj_ihmm2, nsim = 200, seed = 2) str(sim_ihmm2[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm2$states, half = ifelse(seq_along(sim_ihmm2$states) <= 100, "first", "second")) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2 are the starting values) fit_ihmm2 <- fit.ihmm.scpg(sim_ihmm2) fit_ihmm2$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_ihmm2$scpg.par$scale # true 1 fit_ihmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Smoothed state probabilities and residuals for the fitted 2-state IHMM # with TSCPG distribution fit_ihmm2$x <- sim_ihmm2$x sp_ihmm2 <- sp.ihmm.scpg(fit_ihmm2) # Poisson mean lambda_2(t), fitted and true, at the last occurrence times # h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_ihmm2 <- c(0, cumsum(sim_ihmm2$x)[-200]) lam_ihmm2 <- lambda_t(fit_ihmm2$scpg.par$rate[, 1], h_ihmm2) lam0_ihmm2 <- lambda_t(obj_ihmm2$scpg.par$rate[, 1], h_ihmm2) gam_ihmm2 <- sp_ihmm2$smoothed.prob q_ihmm2 <- cut(seq_along(h_ihmm2), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # State 2 (row state.2). The true proportion (row p.true) is 1 in State 1 # and 1/(2 + lambda_2(t)) in State 2. Both kinds of time dependence raise # p_t: the share of State 1 rises as the transitions into State 2 become # less likely, and the proportion recorded in State 2 rises as lambda_2(t) # falls. p_t rises as the true proportion does. p_ihmm2 <- gam_ihmm2[, 1] + gam_ihmm2[, 2] / (2 + lam_ihmm2) p0_ihmm2 <- ifelse(sim_ihmm2$states == 1, 1, 1 / (2 + lam0_ihmm2)) rbind(p = tapply(p_ihmm2, q_ihmm2, mean), state.1 = tapply(gam_ihmm2[, 1], q_ihmm2, mean), state.2 = tapply(gam_ihmm2[, 2] / (2 + lam_ihmm2), q_ihmm2, sum) / tapply(gam_ihmm2[, 2], q_ihmm2, sum), p.true = tapply(p0_ihmm2, q_ihmm2, mean)) # Plotting of residuals to check whether the fitted IHMM with TSCPG renewal # process is a good fit dev.new() res_ihmm2 <- sp_ihmm2$residuals lres_ihmm2 <- length(sp_ihmm2$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihmm2, 1:lres_ihmm2-res_ihmm2, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihmm2, (1:lres_ihmm2-sqrt(lres_ihmm2)*1.36)-1:lres_ihmm2, type="l", lty=2) lines(res_ihmm2, (1:lres_ihmm2+sqrt(lres_ihmm2)*1.36)-1:lres_ihmm2, type="l", lty=2) # 99% CI lines(res_ihmm2, (1:lres_ihmm2-sqrt(lres_ihmm2)*1.63)-1:lres_ihmm2, type="l", lty=3) lines(res_ihmm2, (1:lres_ihmm2+sqrt(lres_ihmm2)*1.63)-1:lres_ihmm2, type="l", lty=3) lines(res_ihmm2, rep(0, lres_ihmm2), col="red") par(oldpar) # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3) # Simulating a 3-state IHMM with a TSCPG distribution sim_ihmm2_m3 <- sim.ihmm.scpg(obj_ihmm2_m3, nsim = 500, seed = 1) str(sim_ihmm2_m3[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into the incomplete states become less likely table(state = sim_ihmm2_m3$states, half = ifelse(seq_along(sim_ihmm2_m3$states) <= 250, "first", "second")) # Fitting a 3-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2_m3 are the starting values). The fit # takes about 2.5 minutes, so it is wrapped in donttest. fit_ihmm2_m3 <- fit.ihmm.scpg(sim_ihmm2_m3) fit_ihmm2_m3$imc.par$ttpm[, , 1] # r_ij (rows i, columns j = 2, 3) fit_ihmm2_m3$imc.par$ttpm[, , 2] # w_ij fit_ihmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihmm2_m3$logLik # Smoothed state probabilities and residuals for the fitted 3-state IHMM # with TSCPG distribution fit_ihmm2_m3$x <- sim_ihmm2_m3$x sp_ihmm2_m3 <- sp.ihmm.scpg(fit_ihmm2_m3) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + sum_j Pr(S_t = j | x) / (2 + lambda_j(t)), # averaged over the four quarters of the record. It combines the two kinds # of time dependence (fewer visits to the incomplete states and fewer # missing events in them) in one summary of how completeness changes. h_ihmm2_m3 <- c(0, cumsum(sim_ihmm2_m3$x)[-500]) r_ihmm2_m3 <- fit_ihmm2_m3$scpg.par$rate lam_ihmm2_m3 <- sapply(1:2, function(j) r_ihmm2_m3[1, j] + r_ihmm2_m3[2, j] / (1 + exp(r_ihmm2_m3[3, j] * h_ihmm2_m3 - r_ihmm2_m3[4, j]))) p_ihmm2_m3 <- sp_ihmm2_m3$smoothed.prob[, 1] + rowSums(sp_ihmm2_m3$smoothed.prob[, 2:3] / (2 + lam_ihmm2_m3)) tapply(p_ihmm2_m3, cut(seq_along(p_ihmm2_m3), 4), mean) # Plotting of residuals to check whether the fitted IHMM with TSCPG renewal # process is a good fit dev.new() res_ihmm2_m3 <- sp_ihmm2_m3$residuals lres_ihmm2_m3 <- length(sp_ihmm2_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihmm2_m3, 1:lres_ihmm2_m3-res_ihmm2_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihmm2_m3, (1:lres_ihmm2_m3-sqrt(lres_ihmm2_m3)*1.36)-1:lres_ihmm2_m3, type="l", lty=2) lines(res_ihmm2_m3, (1:lres_ihmm2_m3+sqrt(lres_ihmm2_m3)*1.36)-1:lres_ihmm2_m3, type="l", lty=2) # 99% CI lines(res_ihmm2_m3, (1:lres_ihmm2_m3-sqrt(lres_ihmm2_m3)*1.63)-1:lres_ihmm2_m3, type="l", lty=3) lines(res_ihmm2_m3, (1:lres_ihmm2_m3+sqrt(lres_ihmm2_m3)*1.63)-1:lres_ihmm2_m3, type="l", lty=3) lines(res_ihmm2_m3, rep(0, lres_ihmm2_m3), col="red") par(oldpar)# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # Simulating a 2-state IHMM with SCPG distribution sim_ihmm1 <- sim.ihmm.scpg(obj_ihmm1, nsim = 200, seed = 1) str(sim_ihmm1[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm1$states, half = ifelse(seq_along(sim_ihmm1$states) <= 100, "first", "second")) # The fit takes about 6 s, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with SCPG distributions # (the parameters of obj_ihmm1 are the starting values) fit_ihmm1 <- fit.ihmm.scpg(sim_ihmm1) fit_ihmm1$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm1$scpg.par$rate # lambda_2 (true 3) fit_ihmm1$scpg.par$shape # true 1.5 fit_ihmm1$scpg.par$scale # true 1 fit_ihmm1$logLik # The fit takes about 6 s, so the code below is wrapped in donttest. # Smoothed probabilities for a 2-state IHMM with an SCPG distribution fit_ihmm1$x <- sim_ihmm1$x # Computing smoothed probabilities and residuals sp_ihmm1 <- sp.ihmm.scpg(fit_ihmm1) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2), averaged over the # four quarters of the record (row p) and compared with the true proportion # (row p.true: 1 in State 1 and 1/(2 + lambda_2) in State 2). With a # constant lambda_2 the rise comes from the transitions alone, which make # State 1 more frequent (row state.1). p_ihmm1 <- sp_ihmm1$smoothed.prob[, 1] + sp_ihmm1$smoothed.prob[, 2] / (2 + fit_ihmm1$scpg.par$rate[1, 1]) p0_ihmm1 <- ifelse(sim_ihmm1$states == 1, 1, 1 / (2 + obj_ihmm1$scpg.par$rate[1, 1])) q_ihmm1 <- cut(seq_along(p_ihmm1), 4) rbind(p = tapply(p_ihmm1, q_ihmm1, mean), state.1 = tapply(sp_ihmm1$smoothed.prob[, 1], q_ihmm1, mean), p.true = tapply(p0_ihmm1, q_ihmm1, mean)) # Plotting of residuals to check whether the fitted IHMM with SCPG renewal # process is a good fit. dev.new() res_ihmm1 <- sp_ihmm1$residuals lres_ihmm1 <- length(sp_ihmm1$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihmm1, 1:lres_ihmm1-res_ihmm1, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihmm1, (1:lres_ihmm1-sqrt(lres_ihmm1)*1.36)-1:lres_ihmm1, type="l", lty=2) lines(res_ihmm1, (1:lres_ihmm1+sqrt(lres_ihmm1)*1.36)-1:lres_ihmm1, type="l", lty=2) # 99% CI lines(res_ihmm1, (1:lres_ihmm1-sqrt(lres_ihmm1)*1.63)-1:lres_ihmm1, type="l", lty=3) lines(res_ihmm1, (1:lres_ihmm1+sqrt(lres_ihmm1)*1.63)-1:lres_ihmm1, type="l", lty=3) lines(res_ihmm1, rep(0, lres_ihmm1), col="red") par(oldpar) # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # Simulating a 3-state IHMM with SCPG distribution sim_ihmm1_m3 <- sim.ihmm.scpg(obj_ihmm1_m3, nsim = 200, seed = 2) print(sim_ihmm1_m3) # Fitting a 3-state IHMM with SCPG distributions # The fit takes about 1.5 minutes, so it is wrapped in donttest. fit_ihmm1_m3 <- fit.ihmm.scpg(sim_ihmm1_m3) print(fit_ihmm1_m3) # Smoothed probabilities for a 3-state IHMM with an SCPG distribution fit_ihmm1_m3$x=sim_ihmm1_m3$x # Computing smoothed probabilities and residuals sp_ihmm1_m3 <- sp.ihmm.scpg(fit_ihmm1_m3) # Plotting of residuals to check whether the fitted IHMM with SCPG renewal # process is a good fit. dev.new() res_ihmm1_m3 <- sp_ihmm1_m3$residuals lres_ihmm1_m3 <- length(sp_ihmm1_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihmm1_m3, 1:lres_ihmm1_m3-res_ihmm1_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihmm1_m3, (1:lres_ihmm1_m3-sqrt(lres_ihmm1_m3)*1.36)-1:lres_ihmm1_m3, type="l", lty=2) lines(res_ihmm1_m3, (1:lres_ihmm1_m3+sqrt(lres_ihmm1_m3)*1.36)-1:lres_ihmm1_m3, type="l", lty=2) # 99% CI lines(res_ihmm1_m3, (1:lres_ihmm1_m3-sqrt(lres_ihmm1_m3)*1.63)-1:lres_ihmm1_m3, type="l", lty=3) lines(res_ihmm1_m3, (1:lres_ihmm1_m3+sqrt(lres_ihmm1_m3)*1.63)-1:lres_ihmm1_m3, type="l", lty=3) lines(res_ihmm1_m3, rep(0, lres_ihmm1_m3), col="red") par(oldpar) # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # Simulating a 2-state IHMM with a TSCPG distribution sim_ihmm2 <- sim.ihmm.scpg(obj_ihmm2, nsim = 200, seed = 2) str(sim_ihmm2[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm2$states, half = ifelse(seq_along(sim_ihmm2$states) <= 100, "first", "second")) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2 are the starting values) fit_ihmm2 <- fit.ihmm.scpg(sim_ihmm2) fit_ihmm2$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_ihmm2$scpg.par$scale # true 1 fit_ihmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Smoothed state probabilities and residuals for the fitted 2-state IHMM # with TSCPG distribution fit_ihmm2$x <- sim_ihmm2$x sp_ihmm2 <- sp.ihmm.scpg(fit_ihmm2) # Poisson mean lambda_2(t), fitted and true, at the last occurrence times # h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_ihmm2 <- c(0, cumsum(sim_ihmm2$x)[-200]) lam_ihmm2 <- lambda_t(fit_ihmm2$scpg.par$rate[, 1], h_ihmm2) lam0_ihmm2 <- lambda_t(obj_ihmm2$scpg.par$rate[, 1], h_ihmm2) gam_ihmm2 <- sp_ihmm2$smoothed.prob q_ihmm2 <- cut(seq_along(h_ihmm2), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # State 2 (row state.2). The true proportion (row p.true) is 1 in State 1 # and 1/(2 + lambda_2(t)) in State 2. Both kinds of time dependence raise # p_t: the share of State 1 rises as the transitions into State 2 become # less likely, and the proportion recorded in State 2 rises as lambda_2(t) # falls. p_t rises as the true proportion does. p_ihmm2 <- gam_ihmm2[, 1] + gam_ihmm2[, 2] / (2 + lam_ihmm2) p0_ihmm2 <- ifelse(sim_ihmm2$states == 1, 1, 1 / (2 + lam0_ihmm2)) rbind(p = tapply(p_ihmm2, q_ihmm2, mean), state.1 = tapply(gam_ihmm2[, 1], q_ihmm2, mean), state.2 = tapply(gam_ihmm2[, 2] / (2 + lam_ihmm2), q_ihmm2, sum) / tapply(gam_ihmm2[, 2], q_ihmm2, sum), p.true = tapply(p0_ihmm2, q_ihmm2, mean)) # Plotting of residuals to check whether the fitted IHMM with TSCPG renewal # process is a good fit dev.new() res_ihmm2 <- sp_ihmm2$residuals lres_ihmm2 <- length(sp_ihmm2$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihmm2, 1:lres_ihmm2-res_ihmm2, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihmm2, (1:lres_ihmm2-sqrt(lres_ihmm2)*1.36)-1:lres_ihmm2, type="l", lty=2) lines(res_ihmm2, (1:lres_ihmm2+sqrt(lres_ihmm2)*1.36)-1:lres_ihmm2, type="l", lty=2) # 99% CI lines(res_ihmm2, (1:lres_ihmm2-sqrt(lres_ihmm2)*1.63)-1:lres_ihmm2, type="l", lty=3) lines(res_ihmm2, (1:lres_ihmm2+sqrt(lres_ihmm2)*1.63)-1:lres_ihmm2, type="l", lty=3) lines(res_ihmm2, rep(0, lres_ihmm2), col="red") par(oldpar) # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3) # Simulating a 3-state IHMM with a TSCPG distribution sim_ihmm2_m3 <- sim.ihmm.scpg(obj_ihmm2_m3, nsim = 500, seed = 1) str(sim_ihmm2_m3[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into the incomplete states become less likely table(state = sim_ihmm2_m3$states, half = ifelse(seq_along(sim_ihmm2_m3$states) <= 250, "first", "second")) # Fitting a 3-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2_m3 are the starting values). The fit # takes about 2.5 minutes, so it is wrapped in donttest. fit_ihmm2_m3 <- fit.ihmm.scpg(sim_ihmm2_m3) fit_ihmm2_m3$imc.par$ttpm[, , 1] # r_ij (rows i, columns j = 2, 3) fit_ihmm2_m3$imc.par$ttpm[, , 2] # w_ij fit_ihmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihmm2_m3$logLik # Smoothed state probabilities and residuals for the fitted 3-state IHMM # with TSCPG distribution fit_ihmm2_m3$x <- sim_ihmm2_m3$x sp_ihmm2_m3 <- sp.ihmm.scpg(fit_ihmm2_m3) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + sum_j Pr(S_t = j | x) / (2 + lambda_j(t)), # averaged over the four quarters of the record. It combines the two kinds # of time dependence (fewer visits to the incomplete states and fewer # missing events in them) in one summary of how completeness changes. h_ihmm2_m3 <- c(0, cumsum(sim_ihmm2_m3$x)[-500]) r_ihmm2_m3 <- fit_ihmm2_m3$scpg.par$rate lam_ihmm2_m3 <- sapply(1:2, function(j) r_ihmm2_m3[1, j] + r_ihmm2_m3[2, j] / (1 + exp(r_ihmm2_m3[3, j] * h_ihmm2_m3 - r_ihmm2_m3[4, j]))) p_ihmm2_m3 <- sp_ihmm2_m3$smoothed.prob[, 1] + rowSums(sp_ihmm2_m3$smoothed.prob[, 2:3] / (2 + lam_ihmm2_m3)) tapply(p_ihmm2_m3, cut(seq_along(p_ihmm2_m3), 4), mean) # Plotting of residuals to check whether the fitted IHMM with TSCPG renewal # process is a good fit dev.new() res_ihmm2_m3 <- sp_ihmm2_m3$residuals lres_ihmm2_m3 <- length(sp_ihmm2_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihmm2_m3, 1:lres_ihmm2_m3-res_ihmm2_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihmm2_m3, (1:lres_ihmm2_m3-sqrt(lres_ihmm2_m3)*1.36)-1:lres_ihmm2_m3, type="l", lty=2) lines(res_ihmm2_m3, (1:lres_ihmm2_m3+sqrt(lres_ihmm2_m3)*1.36)-1:lres_ihmm2_m3, type="l", lty=2) # 99% CI lines(res_ihmm2_m3, (1:lres_ihmm2_m3-sqrt(lres_ihmm2_m3)*1.63)-1:lres_ihmm2_m3, type="l", lty=3) lines(res_ihmm2_m3, (1:lres_ihmm2_m3+sqrt(lres_ihmm2_m3)*1.63)-1:lres_ihmm2_m3, type="l", lty=3) lines(res_ihmm2_m3, rep(0, lres_ihmm2_m3), col="red") par(oldpar)
Calculates the probability of being in State at time for an
IHSMM with class ihsmm.gamma, ihsmm.scpg and ihsmm.tscpg as typically returned
by ihsmm.scpg.
sp.ihsmm.scpg(ihsmmobj)sp.ihsmm.scpg(ihsmmobj)
ihsmmobj |
is a model object with class |
The smoothed probability
is obtained by the
extension of the forward-backward algorithm of Guedon (2003) given by
Shahzadi et al. (2023). With and
recording respectively that a visit to State ends at time
and the conditional probability of the remaining observations, and with
and the corresponding
quantities at the commencement of a visit, the smoothed probability
satisfies the backward recursion
with . The sojourn mass and
survival functions are evaluated at each admissible commencement time from
the sojourn parameter prevailing there, so that visits
beginning at different points of the record are weighted differently. The
recursions are scaled at each time step.
Plotted against the occurrence times, the smoothed probabilities exhibit
the drift for which the inhomogeneous specification was introduced: the
probability of State 1 consolidates into progressively longer intervals as
the record approaches the present, while the incompleteness states are
confined to its earlier portion. The globally optimal sequence of visits is
obtained from vip.ihsmm.scpg.
returns an matrix for the smoothed probabilities and a numeric vector
of residuals from an IHSMM with class ihsmm.scpg.
Guédon Y (2003). “Estimating hidden semi-Markov chains from discrete sequences.” Journal of Computational and Graphical Statistics, 12(3), 604-639. doi:10.1198/1061860032030.
Shahzadi A, Wang T, Parry M, Bebbington M (2023). “Inhomogeneous hidden semi-Markov models for incompletely observed point processes.” Annals of Institute Statistical Mathematics, 75, 253-280. doi:10.1007/s10463-022-00843-5.
Daley DJ, Vere-Jones D (2003). An Introduction to the Theory of Point Processes. Springer, New York. doi:10.1007/b97277.
# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # Simulating a 2-state IHSMM with SCPG distribution sim_ihsmm1 <- sim.ihsmm.scpg(obj_ihsmm1, nsim = 150, seed = 3) str(sim_ihsmm1[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm1$states)$values) # The fit takes about 30 s, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with SCPG distributions # (the parameters of obj_ihsmm1 are the starting values) fit_ihsmm1 <- fit.ihsmm.scpg(sim_ihsmm1) fit_ihsmm1$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm1$scpg.par$rate # lambda_2 (true 3) fit_ihsmm1$scpg.par$shape # true 1.5 fit_ihsmm1$scpg.par$scale # true 1 fit_ihsmm1$logLik # The fit takes about 30 s, so the code below is wrapped in donttest. # Smoothed probabilities and residuals for a 2-state IHSMM with SCPG # distribution fit_ihsmm1$x <- sim_ihsmm1$x sp_ihsmm1 <- sp.ihsmm.scpg(fit_ihsmm1) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2), averaged over the # four quarters of the record (row p) and compared with the true proportion # (row p.true: 1 in State 1 and 1/(2 + lambda_2) in State 2). With a # constant lambda_2 the rise comes from the sojourns alone: the visits to # State 1 become longer and those to State 2 shorter (row state.1). p_ihsmm1 <- sp_ihsmm1$smoothed.prob[, 1] + sp_ihsmm1$smoothed.prob[, 2] / (2 + fit_ihsmm1$scpg.par$rate[1, 1]) p0_ihsmm1 <- ifelse(sim_ihsmm1$states == 1, 1, 1 / (2 + obj_ihsmm1$scpg.par$rate[1, 1])) q_ihsmm1 <- cut(seq_along(p_ihsmm1), 4) rbind(p = tapply(p_ihsmm1, q_ihsmm1, mean), state.1 = tapply(sp_ihsmm1$smoothed.prob[, 1], q_ihsmm1, mean), p.true = tapply(p0_ihsmm1, q_ihsmm1, mean)) # Plotting of residuals to check whether the fitted IHSMM with SCPG renewal # process is a good fit. dev.new() res_ihsmm1 <- sp_ihsmm1$residuals lres_ihsmm1 <- length(sp_ihsmm1$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihsmm1, 1:lres_ihsmm1-res_ihsmm1, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihsmm1, (1:lres_ihsmm1-sqrt(lres_ihsmm1)*1.36)-1:lres_ihsmm1, type="l", lty=2) lines(res_ihsmm1, (1:lres_ihsmm1+sqrt(lres_ihsmm1)*1.36)-1:lres_ihsmm1, type="l", lty=2) # 99% CI lines(res_ihsmm1, (1:lres_ihsmm1-sqrt(lres_ihsmm1)*1.63)-1:lres_ihsmm1, type="l", lty=3) lines(res_ihsmm1, (1:lres_ihsmm1+sqrt(lres_ihsmm1)*1.63)-1:lres_ihsmm1, type="l", lty=3) lines(res_ihsmm1, rep(0, lres_ihsmm1), col="red") par(oldpar) # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # Simulating a 3-state IHSMM with SCPG distribution sim_ihsmm1_m3 <- sim.ihsmm.scpg(obj_ihsmm1_m3, nsim = 150, seed = 1) print(sim_ihsmm1_m3) # Fitting a 3-state IHSMM with SCPG distributions # The fit takes about 2 minutes, so it is wrapped in donttest. fit_ihsmm1_m3 <- fit.ihsmm.scpg(sim_ihsmm1_m3) print(fit_ihsmm1_m3) # Computing smoothed probabilities and residuals fit_ihsmm1_m3$x <- sim_ihsmm1_m3$x sp_ihsmm1_m3 <- sp.ihsmm.scpg(fit_ihsmm1_m3) # Plotting of residuals to check whether the fitted IHSMM with SCPG renewal # process is a good fit. dev.new() res_ihsmm1_m3 <- sp_ihsmm1_m3$residuals lres_ihsmm1_m3 <- length(sp_ihsmm1_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihsmm1_m3, 1:lres_ihsmm1_m3-res_ihsmm1_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihsmm1_m3, (1:lres_ihsmm1_m3-sqrt(lres_ihsmm1_m3)*1.36)-1:lres_ihsmm1_m3, type="l", lty=2) lines(res_ihsmm1_m3, (1:lres_ihsmm1_m3+sqrt(lres_ihsmm1_m3)*1.36)-1:lres_ihsmm1_m3, type="l", lty=2) # 99% CI lines(res_ihsmm1_m3, (1:lres_ihsmm1_m3-sqrt(lres_ihsmm1_m3)*1.63)-1:lres_ihsmm1_m3, type="l", lty=3) lines(res_ihsmm1_m3, (1:lres_ihsmm1_m3+sqrt(lres_ihsmm1_m3)*1.63)-1:lres_ihsmm1_m3, type="l", lty=3) lines(res_ihsmm1_m3, rep(0, lres_ihsmm1_m3), col="red") par(oldpar) # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # Simulating a 2-state IHSMM with a TSCPG distribution sim_ihsmm2 <- sim.ihsmm.scpg(obj_ihsmm2, nsim = 200, seed = 1) str(sim_ihsmm2[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2$states)$values) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2 are the starting values) fit_ihsmm2 <- fit.ihsmm.scpg(sim_ihsmm2) fit_ihsmm2$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_ihsmm2$scpg.par$scale # true 1 fit_ihsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Smoothed state probabilities and residuals for the fitted 2-state IHSMM # with TSCPG distribution fit_ihsmm2$x <- sim_ihsmm2$x sp_ihsmm2 <- sp.ihsmm.scpg(fit_ihsmm2) # Poisson mean lambda_2(t), fitted and true, at the last occurrence times # h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_ihsmm2 <- c(0, cumsum(sim_ihsmm2$x)[-200]) lam_ihsmm2 <- lambda_t(fit_ihsmm2$scpg.par$rate[, 1], h_ihsmm2) lam0_ihsmm2 <- lambda_t(obj_ihsmm2$scpg.par$rate[, 1], h_ihsmm2) gam_ihsmm2 <- sp_ihsmm2$smoothed.prob q_ihsmm2 <- cut(seq_along(h_ihsmm2), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # State 2 (row state.2). The true proportion (row p.true) is 1 in State 1 # and 1/(2 + lambda_2(t)) in State 2. Both kinds of time dependence raise # p_t: the visits to State 1 become longer and those to State 2 shorter, # and fewer events are missed in State 2. p_ihsmm2 <- gam_ihsmm2[, 1] + gam_ihsmm2[, 2] / (2 + lam_ihsmm2) p0_ihsmm2 <- ifelse(sim_ihsmm2$states == 1, 1, 1 / (2 + lam0_ihsmm2)) rbind(p = tapply(p_ihsmm2, q_ihsmm2, mean), state.1 = tapply(gam_ihsmm2[, 1], q_ihsmm2, mean), state.2 = tapply(gam_ihsmm2[, 2] / (2 + lam_ihsmm2), q_ihsmm2, sum) / tapply(gam_ihsmm2[, 2], q_ihsmm2, sum), p.true = tapply(p0_ihsmm2, q_ihsmm2, mean)) # Plotting the residuals (cumulative number of events minus rescaled time) # with Kolmogorov-Smirnov bands, to check whether the fitted model is a good # fit dev.new() res_ihsmm2 <- sp_ihsmm2$residuals lres_ihsmm2 <- length(sp_ihsmm2$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihsmm2, 1:lres_ihsmm2-res_ihsmm2, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihsmm2, (1:lres_ihsmm2-sqrt(lres_ihsmm2)*1.36)-1:lres_ihsmm2, type="l", lty=2) lines(res_ihsmm2, (1:lres_ihsmm2+sqrt(lres_ihsmm2)*1.36)-1:lres_ihsmm2, type="l", lty=2) # 99% CI lines(res_ihsmm2, (1:lres_ihsmm2-sqrt(lres_ihsmm2)*1.63)-1:lres_ihsmm2, type="l", lty=3) lines(res_ihsmm2, (1:lres_ihsmm2+sqrt(lres_ihsmm2)*1.63)-1:lres_ihsmm2, type="l", lty=3) lines(res_ihsmm2, rep(0, lres_ihsmm2), col="red") par(oldpar) # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3) # Simulating a 3-state IHSMM with a TSCPG distribution sim_ihsmm2_m3 <- sim.ihsmm.scpg(obj_ihsmm2_m3, nsim = 250, seed = 2) str(sim_ihsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the time-dependent components are evaluated # on [0, h_{T-1}] c(h_T1 = sum(sim_ihsmm2_m3$x[-250]), h_T = sum(sim_ihsmm2_m3$x)) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2_m3$states)$values) # Fitting a 3-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2_m3 are the starting values). The fit # takes about 8 minutes, so it is wrapped in donttest. fit_ihsmm2_m3 <- fit.ihsmm.scpg(sim_ihsmm2_m3) fit_ihsmm2_m3$ismc.par$tpm # transition matrix of the embedded chain fit_ihsmm2_m3$ismc.par$tdur # A, B, C, D of mu_1(t), mu_2(t) and mu_3(t) fit_ihsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihsmm2_m3$scpg.par$scale # true 0.5 fit_ihsmm2_m3$logLik # Smoothed state probabilities and residuals for the fitted 3-state IHSMM # with TSCPG distribution fit_ihsmm2_m3$x <- sim_ihsmm2_m3$x sp_ihsmm2_m3 <- sp.ihsmm.scpg(fit_ihsmm2_m3) # Poisson means lambda_2(t) and lambda_3(t), fitted and true, at the last # occurrence times h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_ihsmm2_m3 <- c(0, cumsum(sim_ihsmm2_m3$x)[-250]) lam_ihsmm2_m3 <- sapply(1:2, function(j) lambda_t(fit_ihsmm2_m3$scpg.par$rate[, j], h_ihsmm2_m3)) lam0_ihsmm2_m3 <- sapply(1:2, function(j) lambda_t(obj_ihsmm2_m3$scpg.par$rate[, j], h_ihsmm2_m3)) gam_ihsmm2_m3 <- sp_ihsmm2_m3$smoothed.prob q_ihsmm2_m3 <- cut(seq_along(h_ihsmm2_m3), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + sum_j Pr(S_t = j | x) / (2 + lambda_j(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # States 2 and 3 (row states.2.3). The true proportion (row p.true) is 1 # in State 1 and 1/(2 + lambda_j(t)) in State j. Here p_t follows the true # proportion, and most of its rise comes from the sojourns: the visits to # the complete State 1 become longer and those to States 2 and 3 shorter, # so the share of State 1 rises steeply, while the proportion recorded in # States 2 and 3 changes less. p_ihsmm2_m3 <- gam_ihsmm2_m3[, 1] + rowSums(gam_ihsmm2_m3[, 2:3] / (2 + lam_ihsmm2_m3)) s_ihsmm2_m3 <- sim_ihsmm2_m3$states p0_ihsmm2_m3 <- ifelse(s_ihsmm2_m3 == 1, 1, 1 / (2 + lam0_ihsmm2_m3[cbind(seq_along(s_ihsmm2_m3), pmax(s_ihsmm2_m3 - 1, 1))])) rbind(p = tapply(p_ihsmm2_m3, q_ihsmm2_m3, mean), state.1 = tapply(gam_ihsmm2_m3[, 1], q_ihsmm2_m3, mean), states.2.3 = tapply(rowSums(gam_ihsmm2_m3[, 2:3] / (2 + lam_ihsmm2_m3)), q_ihsmm2_m3, sum) / tapply(rowSums(gam_ihsmm2_m3[, 2:3]), q_ihsmm2_m3, sum), p.true = tapply(p0_ihsmm2_m3, q_ihsmm2_m3, mean)) # Plotting the residuals (cumulative number of events minus rescaled time) # with Kolmogorov-Smirnov bands, to check whether the fitted model is a good # fit dev.new() res_ihsmm2_m3 <- sp_ihsmm2_m3$residuals lres_ihsmm2_m3 <- length(sp_ihsmm2_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihsmm2_m3, 1:lres_ihsmm2_m3-res_ihsmm2_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihsmm2_m3, (1:lres_ihsmm2_m3-sqrt(lres_ihsmm2_m3)*1.36)-1:lres_ihsmm2_m3, type="l", lty=2) lines(res_ihsmm2_m3, (1:lres_ihsmm2_m3+sqrt(lres_ihsmm2_m3)*1.36)-1:lres_ihsmm2_m3, type="l", lty=2) # 99% CI lines(res_ihsmm2_m3, (1:lres_ihsmm2_m3-sqrt(lres_ihsmm2_m3)*1.63)-1:lres_ihsmm2_m3, type="l", lty=3) lines(res_ihsmm2_m3, (1:lres_ihsmm2_m3+sqrt(lres_ihsmm2_m3)*1.63)-1:lres_ihsmm2_m3, type="l", lty=3) lines(res_ihsmm2_m3, rep(0, lres_ihsmm2_m3), col="red") par(oldpar)# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # Simulating a 2-state IHSMM with SCPG distribution sim_ihsmm1 <- sim.ihsmm.scpg(obj_ihsmm1, nsim = 150, seed = 3) str(sim_ihsmm1[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm1$states)$values) # The fit takes about 30 s, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with SCPG distributions # (the parameters of obj_ihsmm1 are the starting values) fit_ihsmm1 <- fit.ihsmm.scpg(sim_ihsmm1) fit_ihsmm1$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm1$scpg.par$rate # lambda_2 (true 3) fit_ihsmm1$scpg.par$shape # true 1.5 fit_ihsmm1$scpg.par$scale # true 1 fit_ihsmm1$logLik # The fit takes about 30 s, so the code below is wrapped in donttest. # Smoothed probabilities and residuals for a 2-state IHSMM with SCPG # distribution fit_ihsmm1$x <- sim_ihsmm1$x sp_ihsmm1 <- sp.ihsmm.scpg(fit_ihsmm1) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2), averaged over the # four quarters of the record (row p) and compared with the true proportion # (row p.true: 1 in State 1 and 1/(2 + lambda_2) in State 2). With a # constant lambda_2 the rise comes from the sojourns alone: the visits to # State 1 become longer and those to State 2 shorter (row state.1). p_ihsmm1 <- sp_ihsmm1$smoothed.prob[, 1] + sp_ihsmm1$smoothed.prob[, 2] / (2 + fit_ihsmm1$scpg.par$rate[1, 1]) p0_ihsmm1 <- ifelse(sim_ihsmm1$states == 1, 1, 1 / (2 + obj_ihsmm1$scpg.par$rate[1, 1])) q_ihsmm1 <- cut(seq_along(p_ihsmm1), 4) rbind(p = tapply(p_ihsmm1, q_ihsmm1, mean), state.1 = tapply(sp_ihsmm1$smoothed.prob[, 1], q_ihsmm1, mean), p.true = tapply(p0_ihsmm1, q_ihsmm1, mean)) # Plotting of residuals to check whether the fitted IHSMM with SCPG renewal # process is a good fit. dev.new() res_ihsmm1 <- sp_ihsmm1$residuals lres_ihsmm1 <- length(sp_ihsmm1$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihsmm1, 1:lres_ihsmm1-res_ihsmm1, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihsmm1, (1:lres_ihsmm1-sqrt(lres_ihsmm1)*1.36)-1:lres_ihsmm1, type="l", lty=2) lines(res_ihsmm1, (1:lres_ihsmm1+sqrt(lres_ihsmm1)*1.36)-1:lres_ihsmm1, type="l", lty=2) # 99% CI lines(res_ihsmm1, (1:lres_ihsmm1-sqrt(lres_ihsmm1)*1.63)-1:lres_ihsmm1, type="l", lty=3) lines(res_ihsmm1, (1:lres_ihsmm1+sqrt(lres_ihsmm1)*1.63)-1:lres_ihsmm1, type="l", lty=3) lines(res_ihsmm1, rep(0, lres_ihsmm1), col="red") par(oldpar) # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # Simulating a 3-state IHSMM with SCPG distribution sim_ihsmm1_m3 <- sim.ihsmm.scpg(obj_ihsmm1_m3, nsim = 150, seed = 1) print(sim_ihsmm1_m3) # Fitting a 3-state IHSMM with SCPG distributions # The fit takes about 2 minutes, so it is wrapped in donttest. fit_ihsmm1_m3 <- fit.ihsmm.scpg(sim_ihsmm1_m3) print(fit_ihsmm1_m3) # Computing smoothed probabilities and residuals fit_ihsmm1_m3$x <- sim_ihsmm1_m3$x sp_ihsmm1_m3 <- sp.ihsmm.scpg(fit_ihsmm1_m3) # Plotting of residuals to check whether the fitted IHSMM with SCPG renewal # process is a good fit. dev.new() res_ihsmm1_m3 <- sp_ihsmm1_m3$residuals lres_ihsmm1_m3 <- length(sp_ihsmm1_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihsmm1_m3, 1:lres_ihsmm1_m3-res_ihsmm1_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihsmm1_m3, (1:lres_ihsmm1_m3-sqrt(lres_ihsmm1_m3)*1.36)-1:lres_ihsmm1_m3, type="l", lty=2) lines(res_ihsmm1_m3, (1:lres_ihsmm1_m3+sqrt(lres_ihsmm1_m3)*1.36)-1:lres_ihsmm1_m3, type="l", lty=2) # 99% CI lines(res_ihsmm1_m3, (1:lres_ihsmm1_m3-sqrt(lres_ihsmm1_m3)*1.63)-1:lres_ihsmm1_m3, type="l", lty=3) lines(res_ihsmm1_m3, (1:lres_ihsmm1_m3+sqrt(lres_ihsmm1_m3)*1.63)-1:lres_ihsmm1_m3, type="l", lty=3) lines(res_ihsmm1_m3, rep(0, lres_ihsmm1_m3), col="red") par(oldpar) # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # Simulating a 2-state IHSMM with a TSCPG distribution sim_ihsmm2 <- sim.ihsmm.scpg(obj_ihsmm2, nsim = 200, seed = 1) str(sim_ihsmm2[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2$states)$values) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2 are the starting values) fit_ihsmm2 <- fit.ihsmm.scpg(sim_ihsmm2) fit_ihsmm2$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_ihsmm2$scpg.par$scale # true 1 fit_ihsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # Smoothed state probabilities and residuals for the fitted 2-state IHSMM # with TSCPG distribution fit_ihsmm2$x <- sim_ihsmm2$x sp_ihsmm2 <- sp.ihsmm.scpg(fit_ihsmm2) # Poisson mean lambda_2(t), fitted and true, at the last occurrence times # h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_ihsmm2 <- c(0, cumsum(sim_ihsmm2$x)[-200]) lam_ihsmm2 <- lambda_t(fit_ihsmm2$scpg.par$rate[, 1], h_ihsmm2) lam0_ihsmm2 <- lambda_t(obj_ihsmm2$scpg.par$rate[, 1], h_ihsmm2) gam_ihsmm2 <- sp_ihsmm2$smoothed.prob q_ihsmm2 <- cut(seq_along(h_ihsmm2), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + Pr(S_t = 2 | x) / (2 + lambda_2(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # State 2 (row state.2). The true proportion (row p.true) is 1 in State 1 # and 1/(2 + lambda_2(t)) in State 2. Both kinds of time dependence raise # p_t: the visits to State 1 become longer and those to State 2 shorter, # and fewer events are missed in State 2. p_ihsmm2 <- gam_ihsmm2[, 1] + gam_ihsmm2[, 2] / (2 + lam_ihsmm2) p0_ihsmm2 <- ifelse(sim_ihsmm2$states == 1, 1, 1 / (2 + lam0_ihsmm2)) rbind(p = tapply(p_ihsmm2, q_ihsmm2, mean), state.1 = tapply(gam_ihsmm2[, 1], q_ihsmm2, mean), state.2 = tapply(gam_ihsmm2[, 2] / (2 + lam_ihsmm2), q_ihsmm2, sum) / tapply(gam_ihsmm2[, 2], q_ihsmm2, sum), p.true = tapply(p0_ihsmm2, q_ihsmm2, mean)) # Plotting the residuals (cumulative number of events minus rescaled time) # with Kolmogorov-Smirnov bands, to check whether the fitted model is a good # fit dev.new() res_ihsmm2 <- sp_ihsmm2$residuals lres_ihsmm2 <- length(sp_ihsmm2$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihsmm2, 1:lres_ihsmm2-res_ihsmm2, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihsmm2, (1:lres_ihsmm2-sqrt(lres_ihsmm2)*1.36)-1:lres_ihsmm2, type="l", lty=2) lines(res_ihsmm2, (1:lres_ihsmm2+sqrt(lres_ihsmm2)*1.36)-1:lres_ihsmm2, type="l", lty=2) # 99% CI lines(res_ihsmm2, (1:lres_ihsmm2-sqrt(lres_ihsmm2)*1.63)-1:lres_ihsmm2, type="l", lty=3) lines(res_ihsmm2, (1:lres_ihsmm2+sqrt(lres_ihsmm2)*1.63)-1:lres_ihsmm2, type="l", lty=3) lines(res_ihsmm2, rep(0, lres_ihsmm2), col="red") par(oldpar) # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3) # Simulating a 3-state IHSMM with a TSCPG distribution sim_ihsmm2_m3 <- sim.ihsmm.scpg(obj_ihsmm2_m3, nsim = 250, seed = 2) str(sim_ihsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the time-dependent components are evaluated # on [0, h_{T-1}] c(h_T1 = sum(sim_ihsmm2_m3$x[-250]), h_T = sum(sim_ihsmm2_m3$x)) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2_m3$states)$values) # Fitting a 3-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2_m3 are the starting values). The fit # takes about 8 minutes, so it is wrapped in donttest. fit_ihsmm2_m3 <- fit.ihsmm.scpg(sim_ihsmm2_m3) fit_ihsmm2_m3$ismc.par$tpm # transition matrix of the embedded chain fit_ihsmm2_m3$ismc.par$tdur # A, B, C, D of mu_1(t), mu_2(t) and mu_3(t) fit_ihsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihsmm2_m3$scpg.par$scale # true 0.5 fit_ihsmm2_m3$logLik # Smoothed state probabilities and residuals for the fitted 3-state IHSMM # with TSCPG distribution fit_ihsmm2_m3$x <- sim_ihsmm2_m3$x sp_ihsmm2_m3 <- sp.ihsmm.scpg(fit_ihsmm2_m3) # Poisson means lambda_2(t) and lambda_3(t), fitted and true, at the last # occurrence times h_{t-1}, and the four quarters of the record lambda_t <- function(r, h) r[1] + r[2] / (1 + exp(r[3] * h - r[4])) h_ihsmm2_m3 <- c(0, cumsum(sim_ihsmm2_m3$x)[-250]) lam_ihsmm2_m3 <- sapply(1:2, function(j) lambda_t(fit_ihsmm2_m3$scpg.par$rate[, j], h_ihsmm2_m3)) lam0_ihsmm2_m3 <- sapply(1:2, function(j) lambda_t(obj_ihsmm2_m3$scpg.par$rate[, j], h_ihsmm2_m3)) gam_ihsmm2_m3 <- sp_ihsmm2_m3$smoothed.prob q_ihsmm2_m3 <- cut(seq_along(h_ihsmm2_m3), 4) # Proportion of events recorded around each observation, # p_t = Pr(S_t = 1 | x) + sum_j Pr(S_t = j | x) / (2 + lambda_j(t)), # averaged over each quarter (row p), with its two parts: the share of # State 1 (row state.1) and the proportion recorded while the chain is in # States 2 and 3 (row states.2.3). The true proportion (row p.true) is 1 # in State 1 and 1/(2 + lambda_j(t)) in State j. Here p_t follows the true # proportion, and most of its rise comes from the sojourns: the visits to # the complete State 1 become longer and those to States 2 and 3 shorter, # so the share of State 1 rises steeply, while the proportion recorded in # States 2 and 3 changes less. p_ihsmm2_m3 <- gam_ihsmm2_m3[, 1] + rowSums(gam_ihsmm2_m3[, 2:3] / (2 + lam_ihsmm2_m3)) s_ihsmm2_m3 <- sim_ihsmm2_m3$states p0_ihsmm2_m3 <- ifelse(s_ihsmm2_m3 == 1, 1, 1 / (2 + lam0_ihsmm2_m3[cbind(seq_along(s_ihsmm2_m3), pmax(s_ihsmm2_m3 - 1, 1))])) rbind(p = tapply(p_ihsmm2_m3, q_ihsmm2_m3, mean), state.1 = tapply(gam_ihsmm2_m3[, 1], q_ihsmm2_m3, mean), states.2.3 = tapply(rowSums(gam_ihsmm2_m3[, 2:3] / (2 + lam_ihsmm2_m3)), q_ihsmm2_m3, sum) / tapply(rowSums(gam_ihsmm2_m3[, 2:3]), q_ihsmm2_m3, sum), p.true = tapply(p0_ihsmm2_m3, q_ihsmm2_m3, mean)) # Plotting the residuals (cumulative number of events minus rescaled time) # with Kolmogorov-Smirnov bands, to check whether the fitted model is a good # fit dev.new() res_ihsmm2_m3 <- sp_ihsmm2_m3$residuals lres_ihsmm2_m3 <- length(sp_ihsmm2_m3$residuals) oldpar <- par(mgp=c(2.6, 0.8, 0), mar=c(4, 4.5, 0.5, 0.5), cex.lab=1.4, cex.axis=1.2) plot(res_ihsmm2_m3, 1:lres_ihsmm2_m3-res_ihsmm2_m3, type="l", xlab="Transformed times", ylab="Transformed cumsum", ylim=c(-50, 50)) # 95% CI lines(res_ihsmm2_m3, (1:lres_ihsmm2_m3-sqrt(lres_ihsmm2_m3)*1.36)-1:lres_ihsmm2_m3, type="l", lty=2) lines(res_ihsmm2_m3, (1:lres_ihsmm2_m3+sqrt(lres_ihsmm2_m3)*1.36)-1:lres_ihsmm2_m3, type="l", lty=2) # 99% CI lines(res_ihsmm2_m3, (1:lres_ihsmm2_m3-sqrt(lres_ihsmm2_m3)*1.63)-1:lres_ihsmm2_m3, type="l", lty=3) lines(res_ihsmm2_m3, (1:lres_ihsmm2_m3+sqrt(lres_ihsmm2_m3)*1.63)-1:lres_ihsmm2_m3, type="l", lty=3) lines(res_ihsmm2_m3, rep(0, lres_ihsmm2_m3), col="red") par(oldpar)
Calculates the Viterbi path for an HMM with class hmm.gamma, hmm.scpg and
hmm.tscpg as typically returned by hmm.scpg.
vip.hmm.scpg(hmmobj)vip.hmm.scpg(hmmobj)
hmmobj |
An object created by |
Global decoding determines the single most probable hidden state sequence given the observations,
the denominator being constant in . This differs from
the local decoding obtained from the smoothed probabilities of
sp.hmm.scpg, which maximizes at each time separately; the
globally optimal sequence is always admissible under the model, whereas the
sequence of pointwise maximizers need not be.
The maximization is performed by the Viterbi algorithm (Viterbi, 1967),
which replaces the summation of the forward recursion by a maximization.
Defining
,
and the optimal sequence is recovered by backtracking from
through
. The recursion
is evaluated on the logarithmic scale, products becoming sums and
underflow being thereby avoided.
Since State 1 denotes completeness and States successive
degrees of incompleteness, the decoded sequence is interpreted as an
estimate of which portions of the record are complete and of the number of
events missing elsewhere.
An integer vector of length with the most probable state for
each interevent time.
Viterbi AJ (1967). “Error bounds for convolutional codes and an asymptotically optimum decoding algorithm.” IEEE Transactions on Information Theory, 13(2), 260-269.
# ========================================================= # An example of a 2-state HMM with an SCPG renewal process # ========================================================= # State 1 is the state of completeness: its interevent times are gamma with # shape alpha and scale beta. In the incomplete State 2 the number of # missing events N between two observed events is shifted Poisson with # parameter lambda_2, so on average 1 + lambda_2 = 4 events are missing, # and the observed interevent time is the sum of N + 1 such gamma # interevent times. The shape is common to both states and, with # shape.fix = FALSE, estimated; a separate shape for each state (a vector # of shapes) is also possible but is less well determined. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with SCPG distribution obj_hmm1 <- hmm.scpg(x = NULL, mc.par, scpg.par) print(obj_hmm1) # Simulating a 2-state HMM with SCPG distribution sim_hmm1 <- sim.hmm.scpg(obj_hmm1, nsim = 200, seed = 8) str(sim_hmm1[c("x", "states")]) # Observations in each state table(sim_hmm1$states) # Fitting a 2-state HMM with SCPG distributions # (the parameters of obj_hmm1 are the starting values) fit_hmm1 <- fit.hmm.scpg(sim_hmm1) # transition matrix (true rows 0.9, 0.1 and 0.2, 0.8) fit_hmm1$mc.par$tpm fit_hmm1$scpg.par$rate # lambda_2 (true 3) fit_hmm1$scpg.par$shape # alpha (true 1.5) fit_hmm1$scpg.par$scale # beta (true 1) fit_hmm1$logLik # The Viterbi path of the fitted 2-state HMM with SCPG distribution, # compared with the simulated states fit_hmm1$x <- sim_hmm1$x vip_hmm1 <- vip.hmm.scpg(fit_hmm1) table(true = sim_hmm1$states, decoded = vip_hmm1) # Plotting of the Viterbi path for the fitted model dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_hmm1$x), sim_hmm1$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for a 2-state HMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_hmm1$x), vip_hmm1, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:2, labels=1:2) mtext("Viterbi path for a 2-state HMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar) # ======================================================== # An example of a 3-state HMM with an SCPG renewal process # ======================================================== # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 2 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.60, 0.30, 0.10, 0.45, 0.30, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(c(7, 3), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with SCPG distribution obj_hmm1_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) print(obj_hmm1_m3) # Simulating a 3-state HMM with SCPG distribution sim_hmm1_m3 <- sim.hmm.scpg(obj_hmm1_m3, nsim = 200, seed = 2) print(sim_hmm1_m3) # Fitting a 3-state HMM with SCPG distributions # The fit takes about 1.5 minutes, so it is wrapped in donttest. fit_hmm1_m3 <- fit.hmm.scpg(sim_hmm1_m3) print(fit_hmm1_m3) # The Viterbi path of fitted 3-state HMM with SCPG distribution fit_hmm1_m3$x <- sim_hmm1_m3$x vip_hmm1_m3 <- vip.hmm.scpg(fit_hmm1_m3) print(vip_hmm1_m3) # Plotting of the Viterbi path for the fitted model dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_hmm1_m3$x), sim_hmm1_m3$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for a 3-state HMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_hmm1_m3$x), vip_hmm1_m3, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:3, labels=1:3) mtext("Viterbi path for a 3-state HMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar)# ========================================================= # An example of a 2-state HMM with an SCPG renewal process # ========================================================= # State 1 is the state of completeness: its interevent times are gamma with # shape alpha and scale beta. In the incomplete State 2 the number of # missing events N between two observed events is shifted Poisson with # parameter lambda_2, so on average 1 + lambda_2 = 4 events are missing, # and the observed interevent time is the sum of N + 1 such gamma # interevent times. The shape is common to both states and, with # shape.fix = FALSE, estimated; a separate shape for each state (a vector # of shapes) is also possible but is less well determined. m <- 2 tpm <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE) mc.par <- list(initd = NULL, tpm = tpm, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object for 2-state HMM with SCPG distribution obj_hmm1 <- hmm.scpg(x = NULL, mc.par, scpg.par) print(obj_hmm1) # Simulating a 2-state HMM with SCPG distribution sim_hmm1 <- sim.hmm.scpg(obj_hmm1, nsim = 200, seed = 8) str(sim_hmm1[c("x", "states")]) # Observations in each state table(sim_hmm1$states) # Fitting a 2-state HMM with SCPG distributions # (the parameters of obj_hmm1 are the starting values) fit_hmm1 <- fit.hmm.scpg(sim_hmm1) # transition matrix (true rows 0.9, 0.1 and 0.2, 0.8) fit_hmm1$mc.par$tpm fit_hmm1$scpg.par$rate # lambda_2 (true 3) fit_hmm1$scpg.par$shape # alpha (true 1.5) fit_hmm1$scpg.par$scale # beta (true 1) fit_hmm1$logLik # The Viterbi path of the fitted 2-state HMM with SCPG distribution, # compared with the simulated states fit_hmm1$x <- sim_hmm1$x vip_hmm1 <- vip.hmm.scpg(fit_hmm1) table(true = sim_hmm1$states, decoded = vip_hmm1) # Plotting of the Viterbi path for the fitted model dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_hmm1$x), sim_hmm1$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for a 2-state HMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_hmm1$x), vip_hmm1, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:2, labels=1:2) mtext("Viterbi path for a 2-state HMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar) # ======================================================== # An example of a 3-state HMM with an SCPG renewal process # ======================================================== # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 2 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(1/3, 1/3, 1/3) tpm <- matrix(c(0.2, 0.65, 0.15, 0.60, 0.30, 0.10, 0.45, 0.30, 0.25), nrow = 3, byrow = TRUE) mc.par <- list(initd=NULL, tpm=tpm, stationary=TRUE) rate <- matrix(c(7, 3), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object for 3-state HMM with SCPG distribution obj_hmm1_m3 <- hmm.scpg(x = NULL, mc.par, scpg.par) print(obj_hmm1_m3) # Simulating a 3-state HMM with SCPG distribution sim_hmm1_m3 <- sim.hmm.scpg(obj_hmm1_m3, nsim = 200, seed = 2) print(sim_hmm1_m3) # Fitting a 3-state HMM with SCPG distributions # The fit takes about 1.5 minutes, so it is wrapped in donttest. fit_hmm1_m3 <- fit.hmm.scpg(sim_hmm1_m3) print(fit_hmm1_m3) # The Viterbi path of fitted 3-state HMM with SCPG distribution fit_hmm1_m3$x <- sim_hmm1_m3$x vip_hmm1_m3 <- vip.hmm.scpg(fit_hmm1_m3) print(vip_hmm1_m3) # Plotting of the Viterbi path for the fitted model dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_hmm1_m3$x), sim_hmm1_m3$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for a 3-state HMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_hmm1_m3$x), vip_hmm1_m3, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:3, labels=1:3) mtext("Viterbi path for a 3-state HMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar)
Calculates the Viterbi path for an HMM with class hsmm.gamma, hsmm.scpg
and hsmm.tscpg as typically returned by hsmm.scpg.
vip.hsmm.scpg(hsmmobj)vip.hsmm.scpg(hsmmobj)
hsmmobj |
is a model object with class |
In a hidden semi-Markov model the hidden path is a sequence of visits, each with an associated sojourn time, so that global decoding maximizes over states and durations jointly. Following Guedon (2003) and Yu (2010), define
the maximum probability of a path in which a visit to State of
length ends at time . For ,
with initial condition for . At the sojourn in
the last visited state is right-censored and the sojourn mass function
is replaced by the survival function , so that the
decoded path is optimal under the same right-censored likelihood as is
maximized by fit.hsmm.scpg. The maximizing predecessor and
its duration are recorded in and
the path recovered by backtracking from
. The recursion is evaluated on the
logarithmic scale.
The decoded path is returned as a sequence of visits rather than as one
state per observation, each row giving the index of the last observation
of a visit (column "t-d"), the state occupied ("j"), and its
duration ("d"); the rows run backwards from the end of the record,
and the visit of a row covers observations t-d - d + 1 to
t-d. Consecutive rows necessarily occupy distinct states, the
embedded chain admitting no self-transitions.
returns the most probable state sequence responsible for the observed sequence using the
Viterbi algorithm
with a fitted HSMM with class hsmm.scpg.
Guédon Y (2003). “Estimating hidden semi-Markov chains from discrete sequences.” Journal of Computational and Graphical Statistics, 12(3), 604-639. doi:10.1198/1061860032030.
Yu SZ (2010). “Hidden semi-Markov models.” Artificial Intelligence, 174, 215-243. doi:10.1016/j.artint.2009.11.011.
# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # Simulating a 2-state HSMM with SCPG distribution sim_hsmm1 <- sim.hsmm.scpg(obj_hsmm1, nsim = 150, seed = 1) str(sim_hsmm1[c("x", "states")]) # Number of visits to each state in the simulated path table(rle(sim_hsmm1$states)$values) # Fitting a 2-state HSMM with SCPG distributions # (the parameters of obj_hsmm1 are the starting values) fit_hsmm1 <- fit.hsmm.scpg(sim_hsmm1) fit_hsmm1$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm1$scpg.par$rate # lambda_2 (true 3) fit_hsmm1$scpg.par$shape # alpha (true 1.5) fit_hsmm1$scpg.par$scale # beta (true 1) fit_hsmm1$logLik # The fit takes about 6 s, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state HSMM with SCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_hsmm1$x <- sim_hsmm1$x vip_hsmm1 <- vip.hsmm.scpg(fit_hsmm1) head(vip_hsmm1) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_hsmm1 <- integer(length(sim_hsmm1$x)) for (r in seq_len(nrow(vip_hsmm1))) { last <- vip_hsmm1[r, 1] path_hsmm1[(last - vip_hsmm1[r, 3] + 1):last] <- vip_hsmm1[r, 2] } table(true = sim_hsmm1$states, decoded = path_hsmm1) # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # Simulating a 3-state HSMM with SCPG distribution sim_hsmm1_m3 <- sim.hsmm.scpg(obj_hsmm1_m3, nsim = 80, seed = 1) print(sim_hsmm1_m3) # Fitting a 3-state HSMM with SCPG distributions # The fit takes about 15 seconds, so it is wrapped in donttest. fit_hsmm1_m3 <- fit.hsmm.scpg(sim_hsmm1_m3) print(fit_hsmm1_m3) # The Viterbi path of fitted 3-state HSMM with SCPG distribution fit_hsmm1_m3$x <- sim_hsmm1_m3$x vip_hsmm1_m3 <- vip.hsmm.scpg(fit_hsmm1_m3) print(vip_hsmm1_m3) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # Simulating a 2-state HSMM with a TSCPG distribution sim_hsmm2 <- sim.hsmm.scpg(obj_hsmm2, nsim = 300, seed = 3) str(sim_hsmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2$x[-300]), h_T = sum(sim_hsmm2$x)) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2 are the starting values) fit_hsmm2 <- fit.hsmm.scpg(sim_hsmm2) fit_hsmm2$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_hsmm2$scpg.par$scale # true 1 fit_hsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state HSMM with TSCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_hsmm2$x <- sim_hsmm2$x vip_hsmm2 <- vip.hsmm.scpg(fit_hsmm2) head(vip_hsmm2) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_hsmm2 <- integer(length(sim_hsmm2$x)) for (r in seq_len(nrow(vip_hsmm2))) { last <- vip_hsmm2[r, 1] path_hsmm2[(last - vip_hsmm2[r, 3] + 1):last] <- vip_hsmm2[r, 2] } table(true = sim_hsmm2$states, decoded = path_hsmm2) # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3) # Simulating a 3-state HSMM with a TSCPG distribution sim_hsmm2_m3 <- sim.hsmm.scpg(obj_hsmm2_m3, nsim = 400, seed = 3) str(sim_hsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rates are evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2_m3$x[-400]), h_T = sum(sim_hsmm2_m3$x)) # Number of visits to each state in the simulated path table(rle(sim_hsmm2_m3$states)$values) # Fitting a 3-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2_m3 are the starting values). The fit # takes about 2 minutes, so it is wrapped in donttest. fit_hsmm2_m3 <- fit.hsmm.scpg(sim_hsmm2_m3) fit_hsmm2_m3$smc.par$tpm # transition matrix of the embedded chain # sojourn parameters mu_1, mu_2, mu_3 (true 4, 3, 3) fit_hsmm2_m3$smc.par$dur fit_hsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_hsmm2_m3$scpg.par$scale # true 0.5 fit_hsmm2_m3$logLik # The Viterbi path of the fitted 3-state HSMM with TSCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_hsmm2_m3$x <- sim_hsmm2_m3$x vip_hsmm2_m3 <- vip.hsmm.scpg(fit_hsmm2_m3) head(vip_hsmm2_m3) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_hsmm2_m3 <- integer(length(sim_hsmm2_m3$x)) for (r in seq_len(nrow(vip_hsmm2_m3))) { last <- vip_hsmm2_m3[r, 1] path_hsmm2_m3[(last - vip_hsmm2_m3[r, 3] + 1):last] <- vip_hsmm2_m3[r, 2] } table(true = sim_hsmm2_m3$states, decoded = path_hsmm2_m3)# ========================================================== # An example of a 2-state HSMM with an SCPG renewal process # ========================================================== # State 1 is the state of completeness (gamma interevent times with shape # alpha); in the incomplete State 2 the number N of events missing between # two observed events is shifted Poisson with parameter lambda_2, so the # observed events are N + 1 such gamma interevent times apart. The sojourns # are shifted Poisson with # parameters dur (expected sojourns 1 + dur = 5 and 4 observations). With # m = 2 the zero-diagonal transition matrix is fixed: the chain alternates # between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(3, nrow = 1, ncol = m - 1) # lambda_2 shape <- 1.5 # common shape alpha scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = FALSE, time.scpg = FALSE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with SCPG distribution obj_hsmm1 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm1) # Simulating a 2-state HSMM with SCPG distribution sim_hsmm1 <- sim.hsmm.scpg(obj_hsmm1, nsim = 150, seed = 1) str(sim_hsmm1[c("x", "states")]) # Number of visits to each state in the simulated path table(rle(sim_hsmm1$states)$values) # Fitting a 2-state HSMM with SCPG distributions # (the parameters of obj_hsmm1 are the starting values) fit_hsmm1 <- fit.hsmm.scpg(sim_hsmm1) fit_hsmm1$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm1$scpg.par$rate # lambda_2 (true 3) fit_hsmm1$scpg.par$shape # alpha (true 1.5) fit_hsmm1$scpg.par$scale # beta (true 1) fit_hsmm1$logLik # The fit takes about 6 s, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state HSMM with SCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_hsmm1$x <- sim_hsmm1$x vip_hsmm1 <- vip.hsmm.scpg(fit_hsmm1) head(vip_hsmm1) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_hsmm1 <- integer(length(sim_hsmm1$x)) for (r in seq_len(nrow(vip_hsmm1))) { last <- vip_hsmm1[r, 1] path_hsmm1[(last - vip_hsmm1[r, 3] + 1):last] <- vip_hsmm1[r, 2] } table(true = sim_hsmm1$states, decoded = path_hsmm1) # ========================================================= # An example of a 3-state HSMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 15 seconds on a laptop (the # 2-state model above takes about 1 second), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.3, 0.7, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd=NULL, tpm=tpm, dur=c(3, 5, 2), dur.lb=NA, dur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state HSMM with SCPG distribution obj_hsmm1_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) # Simulating a 3-state HSMM with SCPG distribution sim_hsmm1_m3 <- sim.hsmm.scpg(obj_hsmm1_m3, nsim = 80, seed = 1) print(sim_hsmm1_m3) # Fitting a 3-state HSMM with SCPG distributions # The fit takes about 15 seconds, so it is wrapped in donttest. fit_hsmm1_m3 <- fit.hsmm.scpg(sim_hsmm1_m3) print(fit_hsmm1_m3) # The Viterbi path of fitted 3-state HSMM with SCPG distribution fit_hsmm1_m3$x <- sim_hsmm1_m3$x vip_hsmm1_m3 <- vip.hsmm.scpg(fit_hsmm1_m3) print(vip_hsmm1_m3) # =========================================================== # An example of a 2-state HSMM with a TSCPG renewal process # =========================================================== # State 1 is the state of completeness (gamma interevent times). In the # incomplete State 2 the number of missing events N between two observed # events is shifted Poisson with parameter lambda_2(t), where # lambda_2(t) = K + M / (1 + exp(R * h_{t-1} - P)) # falls from about 5.8 at the start of the record towards K = 0.5, around # the inflection time P/R = 400 of the last occurrence time h_{t-1}. The # sojourns are shifted Poisson with parameters dur (expected sojourns # 1 + dur = 5 and 4 observations). With m = 2 the zero-diagonal transition # matrix is fixed: the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state HSMM with TSCPG distribution obj_hsmm2 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2) # Simulating a 2-state HSMM with a TSCPG distribution sim_hsmm2 <- sim.hsmm.scpg(obj_hsmm2, nsim = 300, seed = 3) str(sim_hsmm2[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rate is evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2$x[-300]), h_T = sum(sim_hsmm2$x)) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2 are the starting values) fit_hsmm2 <- fit.hsmm.scpg(sim_hsmm2) fit_hsmm2$smc.par$dur # sojourn parameters mu_1, mu_2 (true 4, 3) fit_hsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_hsmm2$scpg.par$scale # true 1 fit_hsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state HSMM with TSCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_hsmm2$x <- sim_hsmm2$x vip_hsmm2 <- vip.hsmm.scpg(fit_hsmm2) head(vip_hsmm2) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_hsmm2 <- integer(length(sim_hsmm2$x)) for (r in seq_len(nrow(vip_hsmm2))) { last <- vip_hsmm2[r, 1] path_hsmm2[(last - vip_hsmm2[r, 3] + 1):last] <- vip_hsmm2[r, 2] } table(true = sim_hsmm2$states, decoded = path_hsmm2) # =========================================================== # An example of a 3-state HSMM with a TSCPG renewal process # =========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 7 seconds), so the examples that fit # it are wrapped in donttest. # State 1 is the state of completeness (gamma interevent times). In the # incomplete States 2 and 3 the number of missing events N between two # observed events is shifted Poisson with parameter lambda_j(t), where # lambda_j(t) = K_j + M_j / (1 + exp(R_j * h_{t-1} - P_j)) # falls around the inflection time P_j/R_j of the last occurrence time # h_{t-1}: lambda_2(t) from about 3.4 towards 0.5 around 600, and # lambda_3(t) from about 10 towards 4 around 900. The sojourns are shifted # Poisson with parameters dur (expected sojourns 1 + dur = 5, 4 and 4 # observations), and the zero-diagonal transition matrix gives the next # state of each visit. The shape 2 makes the interevent times of the three # states less overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) smc.par <- list(initd = NULL, tpm = tpm, dur = c(4, 3, 3), dur.lb = NA, dur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3.6, 5.4) # P: inflection times P/R = 600 and 900 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state HSMM with TSCPG distribution obj_hsmm2_m3 <- hsmm.scpg(x = NULL, smc.par, scpg.par) class(obj_hsmm2_m3) # Simulating a 3-state HSMM with a TSCPG distribution sim_hsmm2_m3 <- sim.hsmm.scpg(obj_hsmm2_m3, nsim = 400, seed = 3) str(sim_hsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the TSCPG rates are evaluated on [0, h_{T-1}] c(h_T1 = sum(sim_hsmm2_m3$x[-400]), h_T = sum(sim_hsmm2_m3$x)) # Number of visits to each state in the simulated path table(rle(sim_hsmm2_m3$states)$values) # Fitting a 3-state HSMM with a TSCPG distribution # (the parameters of obj_hsmm2_m3 are the starting values). The fit # takes about 2 minutes, so it is wrapped in donttest. fit_hsmm2_m3 <- fit.hsmm.scpg(sim_hsmm2_m3) fit_hsmm2_m3$smc.par$tpm # transition matrix of the embedded chain # sojourn parameters mu_1, mu_2, mu_3 (true 4, 3, 3) fit_hsmm2_m3$smc.par$dur fit_hsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_hsmm2_m3$scpg.par$scale # true 0.5 fit_hsmm2_m3$logLik # The Viterbi path of the fitted 3-state HSMM with TSCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_hsmm2_m3$x <- sim_hsmm2_m3$x vip_hsmm2_m3 <- vip.hsmm.scpg(fit_hsmm2_m3) head(vip_hsmm2_m3) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_hsmm2_m3 <- integer(length(sim_hsmm2_m3$x)) for (r in seq_len(nrow(vip_hsmm2_m3))) { last <- vip_hsmm2_m3[r, 1] path_hsmm2_m3[(last - vip_hsmm2_m3[r, 3] + 1):last] <- vip_hsmm2_m3[r, 2] } table(true = sim_hsmm2_m3$states, decoded = path_hsmm2_m3)
Calculates the Viterbi path for an IHMM with class ihmm.gamma, ihmm.scpg and
ihmm.tscpg as typically returned by ihmm.scpg.
vip.ihmm.scpg(ihmmobj)vip.ihmm.scpg(ihmmobj)
ihmmobj |
is a model object with class |
Global decoding of an IHMM determines the most probable hidden state sequence,
by the Viterbi algorithm (Viterbi, 1967) with the transition probabilities
replaced by their time-varying counterparts. Defining
,
and the optimal sequence is recovered by backtracking from
, each step employing the transition
probability matrix belonging to that time. The recursion is evaluated on
the logarithmic scale.
Because the time-varying transition probabilities into State 1 increase with elapsed time, the decoded sequence of a correctly specified model ordinarily leaves the incompleteness states at some point and remains in State 1 thereafter. The occurrence time at which this change takes place estimates the point from which the record may be treated as complete, and is the principal quantity of interest in the applications reported by Shahzadi et al. (2026).
returns the most probable state sequence responsible for the observed sequence using the
Viterbi algorithm with a fitted IHMM with class ihmm.scpg.
Viterbi AJ (1967). “Error bounds for convolutional codes and an asymptotically optimum decoding algorithm.” IEEE Transactions on Information Theory, 13(2), 260-269.
Shahzadi A, Wang T, Parry M, Bebbington M (2026). “Modelling time-inhomogeneous incomplete records of point processes using variants of hidden Markov models.” Advances in Data Analysis and Classification, 20, 663-691. doi:10.1007/s11634-025-00632-x.
# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # Simulating a 2-state IHMM with SCPG distribution sim_ihmm1 <- sim.ihmm.scpg(obj_ihmm1, nsim = 200, seed = 1) str(sim_ihmm1[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm1$states, half = ifelse(seq_along(sim_ihmm1$states) <= 100, "first", "second")) # The fit takes about 6 s, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with SCPG distributions # (the parameters of obj_ihmm1 are the starting values) fit_ihmm1 <- fit.ihmm.scpg(sim_ihmm1) fit_ihmm1$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm1$scpg.par$rate # lambda_2 (true 3) fit_ihmm1$scpg.par$shape # true 1.5 fit_ihmm1$scpg.par$scale # true 1 fit_ihmm1$logLik # The fit takes about 6 s, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state IHMM with SCPG distribution, # compared with the simulated states fit_ihmm1$x <- sim_ihmm1$x vip_ihmm1 <- vip.ihmm.scpg(fit_ihmm1) table(true = sim_ihmm1$states, decoded = vip_ihmm1) # Plotting of the Viterbi path with observed data dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_ihmm1$x), sim_ihmm1$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for IHMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_ihmm1$x), vip_ihmm1, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:2, labels=1:2) mtext("Viterbi path for IHMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar) # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # Simulating a 3-state IHMM with SCPG distribution sim_ihmm1_m3 <- sim.ihmm.scpg(obj_ihmm1_m3, nsim = 200, seed = 2) print(sim_ihmm1_m3) # Fitting a 3-state IHMM with SCPG distributions # The fit takes about 1.5 minutes, so it is wrapped in donttest. fit_ihmm1_m3 <- fit.ihmm.scpg(sim_ihmm1_m3) print(fit_ihmm1_m3) # The Viterbi path of fitted 3-state IHMM with SCPG distribution fit_ihmm1_m3$x=sim_ihmm1_m3$x vip_ihmm1_m3 <- vip.ihmm.scpg(fit_ihmm1_m3) print(vip_ihmm1_m3) # Plotting of the Viterbi path with observed data dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_ihmm1_m3$x), sim_ihmm1_m3$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for IHMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_ihmm1_m3$x), vip_ihmm1_m3, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:3, labels=1:3) mtext("Viterbi path for IHMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar) # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # Simulating a 2-state IHMM with a TSCPG distribution sim_ihmm2 <- sim.ihmm.scpg(obj_ihmm2, nsim = 200, seed = 2) str(sim_ihmm2[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm2$states, half = ifelse(seq_along(sim_ihmm2$states) <= 100, "first", "second")) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2 are the starting values) fit_ihmm2 <- fit.ihmm.scpg(sim_ihmm2) fit_ihmm2$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_ihmm2$scpg.par$scale # true 1 fit_ihmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state IHMM with TSCPG distribution fit_ihmm2$x <- sim_ihmm2$x vip_ihmm2 <- vip.ihmm.scpg(fit_ihmm2) table(true = sim_ihmm2$states, decoded = vip_ihmm2) # Plotting of the Viterbi path with observed data dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_ihmm2$x), sim_ihmm2$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for IHMM with TSCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_ihmm2$x), vip_ihmm2, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:2, labels=1:2) mtext("Viterbi path for IHMM with TSCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar) # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3) # Simulating a 3-state IHMM with a TSCPG distribution sim_ihmm2_m3 <- sim.ihmm.scpg(obj_ihmm2_m3, nsim = 500, seed = 1) str(sim_ihmm2_m3[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into the incomplete states become less likely table(state = sim_ihmm2_m3$states, half = ifelse(seq_along(sim_ihmm2_m3$states) <= 250, "first", "second")) # Fitting a 3-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2_m3 are the starting values). The fit # takes about 2.5 minutes, so it is wrapped in donttest. fit_ihmm2_m3 <- fit.ihmm.scpg(sim_ihmm2_m3) fit_ihmm2_m3$imc.par$ttpm[, , 1] # r_ij (rows i, columns j = 2, 3) fit_ihmm2_m3$imc.par$ttpm[, , 2] # w_ij fit_ihmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihmm2_m3$logLik # The Viterbi path of the fitted 3-state IHMM with TSCPG distribution fit_ihmm2_m3$x <- sim_ihmm2_m3$x vip_ihmm2_m3 <- vip.ihmm.scpg(fit_ihmm2_m3) table(true = sim_ihmm2_m3$states, decoded = vip_ihmm2_m3) # Plotting of the Viterbi path with observed data dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_ihmm2_m3$x), sim_ihmm2_m3$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for IHMM with TSCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_ihmm2_m3$x), vip_ihmm2_m3, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:3, labels=1:3) mtext("Viterbi path for IHMM with TSCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar)# ========================================================== # An example of a 2-state IHMM with an SCPG renewal process # ========================================================== # The transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease along the record: the log-odds of moving from state i to # State 2 rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at # the crossing time w_i2 / r_i2 (250 for a_12(t) and 500 for a_22(t)). In # State 2 the number N of events missing between two observed events is # shifted Poisson with parameter lambda_2. The chain starts mostly in State 2 # (initd = (0.2, 0.8)), # since the early part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.004, 0.006) # rates of change r_12, r_22 ttpm[, , 2] <- c(1, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with SCPG distribution obj_ihmm1 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm1) # Simulating a 2-state IHMM with SCPG distribution sim_ihmm1 <- sim.ihmm.scpg(obj_ihmm1, nsim = 200, seed = 1) str(sim_ihmm1[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm1$states, half = ifelse(seq_along(sim_ihmm1$states) <= 100, "first", "second")) # The fit takes about 6 s, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with SCPG distributions # (the parameters of obj_ihmm1 are the starting values) fit_ihmm1 <- fit.ihmm.scpg(sim_ihmm1) fit_ihmm1$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm1$scpg.par$rate # lambda_2 (true 3) fit_ihmm1$scpg.par$shape # true 1.5 fit_ihmm1$scpg.par$scale # true 1 fit_ihmm1$logLik # The fit takes about 6 s, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state IHMM with SCPG distribution, # compared with the simulated states fit_ihmm1$x <- sim_ihmm1$x vip_ihmm1 <- vip.ihmm.scpg(fit_ihmm1) table(true = sim_ihmm1$states, decoded = vip_ihmm1) # Plotting of the Viterbi path with observed data dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_ihmm1$x), sim_ihmm1$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for IHMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_ihmm1$x), vip_ihmm1, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:2, labels=1:2) mtext("Viterbi path for IHMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar) # ========================================================= # An example of a 3-state IHMM with an SCPG renewal process # ========================================================= # Fitting this 3-state model takes about 1.5 minutes on a laptop (the # 2-state model above takes about 6 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 initd <- c(0.45, 0.25, 0.30) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.0008, 0.0010, 0.0006, 0.0006, 0.0008, 0.0010), nrow = m, ncol = m-1) # intercepts w_ij; a_ij(t) = a_i1(t) at h = w_ij/r_ij, between 2000 and 3000 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(2500, 2000, 3000, 2000, 3000, 2500), nrow = m, ncol = m-1) stationary <- FALSE imc.par <- list(initd=initd, ttpm=ttpm, stationary=stationary) rate <- matrix(c(7, 2), nrow = 1, ncol = m-1) shape <- 1.7 scale <- 3.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with SCPG distribution obj_ihmm1_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) # Simulating a 3-state IHMM with SCPG distribution sim_ihmm1_m3 <- sim.ihmm.scpg(obj_ihmm1_m3, nsim = 200, seed = 2) print(sim_ihmm1_m3) # Fitting a 3-state IHMM with SCPG distributions # The fit takes about 1.5 minutes, so it is wrapped in donttest. fit_ihmm1_m3 <- fit.ihmm.scpg(sim_ihmm1_m3) print(fit_ihmm1_m3) # The Viterbi path of fitted 3-state IHMM with SCPG distribution fit_ihmm1_m3$x=sim_ihmm1_m3$x vip_ihmm1_m3 <- vip.ihmm.scpg(fit_ihmm1_m3) print(vip_ihmm1_m3) # Plotting of the Viterbi path with observed data dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_ihmm1_m3$x), sim_ihmm1_m3$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for IHMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_ihmm1_m3$x), vip_ihmm1_m3, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:3, labels=1:3) mtext("Viterbi path for IHMM with SCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar) # ========================================================== # An example of a 2-state IHMM with a TSCPG renewal process # ========================================================== # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_12(t) and a_22(t) into the incomplete # State 2 decrease: the log-odds of moving from state i to State 2 # rather than to State 1 is w_i2 - r_i2 * h_{t-1}, which is zero at the # crossing time w_i2 / r_i2 (about 304 for a_12(t) and 600 for a_22(t)); # - the Poisson mean lambda_2(t) of the TSCPG falls from about 5.4 at the # start of the record towards K = 0.5, around the inflection time # P/R = 400. # The chain starts mostly in State 2 (initd = (0.2, 0.8)), since the early # part of a record is usually the least complete. m <- 2 initd <- c(0.2, 0.8) ttpm <- array(NA, dim = c(m, m-1, 2)) ttpm[, , 1] <- c(0.0028, 0.005) # rates of change r_12, r_22 ttpm[, , 2] <- c(0.85, 3) # intercepts w_12, w_22 imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(c(0.5, 5, 0.01, 4), nrow = 4) # K, M, R, P: P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHMM with TSCPG distribution obj_ihmm2 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2) # Simulating a 2-state IHMM with a TSCPG distribution sim_ihmm2 <- sim.ihmm.scpg(obj_ihmm2, nsim = 200, seed = 2) str(sim_ihmm2[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into State 2 become less likely table(state = sim_ihmm2$states, half = ifelse(seq_along(sim_ihmm2$states) <= 100, "first", "second")) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2 are the starting values) fit_ihmm2 <- fit.ihmm.scpg(sim_ihmm2) fit_ihmm2$imc.par$ttpm[, 1, ] # r_i2 (first column) and w_i2 (second) fit_ihmm2$scpg.par$rate[, 1] # K, M, R, P of lambda_2(t) fit_ihmm2$scpg.par$scale # true 1 fit_ihmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state IHMM with TSCPG distribution fit_ihmm2$x <- sim_ihmm2$x vip_ihmm2 <- vip.ihmm.scpg(fit_ihmm2) table(true = sim_ihmm2$states, decoded = vip_ihmm2) # Plotting of the Viterbi path with observed data dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_ihmm2$x), sim_ihmm2$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for IHMM with TSCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_ihmm2$x), vip_ihmm2, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:2, labels=1:2) mtext("Viterbi path for IHMM with TSCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar) # ========================================================= # An example of a 3-state IHMM with a TSCPG renewal process # ========================================================= # Fitting this 3-state model takes about 2.5 minutes on a laptop (the # 2-state model above takes about 8 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along the # record (see the Details of ?fit.ihmm.scpg): # - the transition probabilities a_ij(t): moves into the incomplete # States 2 and 3 become less likely as time goes on. The log-odds of # moving from state i to state j rather than to State 1 is # w_ij - r_ij * h_{t-1}, which is zero at the crossing time w_ij / r_ij; # - the Poisson means lambda_j(t) of the TSCPG: in the incomplete states # fewer events are missed after the inflection times P_j / R_j. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1, so that the states are easier to tell apart. m <- 3 initd <- c(0.4, 0.3, 0.3) ttpm <- array(NA, dim = c(m, m-1, 2)) # rates of change r_ij (rows i = 1, 2, 3; columns j = 2, 3) ttpm[, , 1] <- matrix(c(0.006, 0.006, 0.006, 0.006, 0.006, 0.006), nrow = m, ncol = m-1) # intercepts w_ij; crossing times w_ij/r_ij between 400 and 600 ttpm[, , 2] <- ttpm[, , 1] * matrix(c(500, 600, 500, 400, 500, 600), nrow = m, ncol = m-1) imc.par <- list(initd=initd, ttpm=ttpm, stationary=FALSE) rate <- matrix(NA, nrow = 4, ncol = m-1) rate[1, ] <- c(0.5, 4) # K: lambda_2(t) falls from about 3.4 towards rate[2, ] <- c(3, 6) # M: 0.5, lambda_3(t) from about 10 towards 4 rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(3, 4.2) # P: inflection times P/R = 500 and 700 shape <- 2 scale <- 0.5 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=TRUE, time.scpg=TRUE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHMM with TSCPG distribution obj_ihmm2_m3 <- ihmm.scpg(x = NULL, imc.par, scpg.par) class(obj_ihmm2_m3) # Simulating a 3-state IHMM with a TSCPG distribution sim_ihmm2_m3 <- sim.ihmm.scpg(obj_ihmm2_m3, nsim = 500, seed = 1) str(sim_ihmm2_m3[c("x", "states")]) # Observations in each state: State 1 becomes more frequent as the # transitions into the incomplete states become less likely table(state = sim_ihmm2_m3$states, half = ifelse(seq_along(sim_ihmm2_m3$states) <= 250, "first", "second")) # Fitting a 3-state IHMM with a TSCPG distribution # (the parameters of obj_ihmm2_m3 are the starting values). The fit # takes about 2.5 minutes, so it is wrapped in donttest. fit_ihmm2_m3 <- fit.ihmm.scpg(sim_ihmm2_m3) fit_ihmm2_m3$imc.par$ttpm[, , 1] # r_ij (rows i, columns j = 2, 3) fit_ihmm2_m3$imc.par$ttpm[, , 2] # w_ij fit_ihmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihmm2_m3$logLik # The Viterbi path of the fitted 3-state IHMM with TSCPG distribution fit_ihmm2_m3$x <- sim_ihmm2_m3$x vip_ihmm2_m3 <- vip.ihmm.scpg(fit_ihmm2_m3) table(true = sim_ihmm2_m3$states, decoded = vip_ihmm2_m3) # Plotting of the Viterbi path with observed data dev.new() oldpar <- par(mfrow=c(2, 1), cex.lab = 1.3, cex.axis = 1.2, mgp=c(2.3,0.8,0)) par(mar=c(0, 4.0, 2, 3)) # bottom margin is 0. plot(cumsum(sim_ihmm2_m3$x), sim_ihmm2_m3$x, type="l", ylab = "Interevent times" , xaxt="n") mtext("Simulated data for IHMM with TSCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(mar=c(3.5, 4.0, 0, 3)) # top is 0. plot(cumsum(sim_ihmm2_m3$x), vip_ihmm2_m3, type="s", yaxt="n", xlab="Occurrence Time", ylab="States") axis(2, at=1:3, labels=1:3) mtext("Viterbi path for IHMM with TSCPG", side = 4, line = 0.8, cex = 1.1, las = 0) par(oldpar)
Calculates the Viterbi path for an IHSMM with class ihsmm.gamma, ihsmm.scpg
and ihsmm.tscpg as typically returned by ihsmm.scpg.
vip.ihsmm.scpg(ihsmmobj)vip.ihsmm.scpg(ihsmmobj)
ihsmmobj |
is a model object with class |
Global decoding of an IHSMM maximizes over sequences of visits and their
durations jointly, following the algorithm of Shahzadi et al. (2023), which
extends that of Guedon (2003) and Yu (2010) to time-dependent sojourn
distributions. With the maximum probability of a path
in which a visit to State of length ends at time ,
for , where is the shifted Poisson
sojourn mass function with parameter , and with
initial condition for . At the sojourn in
the last visited state is right-censored and is
replaced by the corresponding survival function, so that the decoded path
is optimal under the same right-censored likelihood as is maximized by
fit.ihsmm.scpg. The maximizing predecessor and its duration
are recorded in and the path
recovered by backtracking from . The
recursion is evaluated on the logarithmic scale.
Each row of the result gives the index of the last observation of a visit
(column "t-d"), the state occupied ("j"), and its duration
("d"); the rows run backwards from the end of the record, and the
visit of a row covers observations t-d - d + 1 to t-d. Since the expected sojourn time in State 1
increases with elapsed time while those in the incompleteness states
decrease, the decoded path of a correctly specified model exhibits visits
to State 1 of increasing length towards the end of the record, the
incompleteness states being confined to its earlier portion. The occurrence
time from which State 1 is no longer interrupted estimates the point at
which the record becomes complete, and is the principal quantity reported
in the applications of Shahzadi et al. (2023).
returns the most probable state sequence responsible for the observed
sequence using the Viterbi algorithm
with a fitted IHSMM with class ihsmm.scpg.
Shahzadi A, Wang T, Parry M, Bebbington M (2023). “Inhomogeneous hidden semi-Markov models for incompletely observed point processes.” Annals of Institute Statistical Mathematics, 75, 253-280. doi:10.1007/s10463-022-00843-5.
Guédon Y (2003). “Estimating hidden semi-Markov chains from discrete sequences.” Journal of Computational and Graphical Statistics, 12(3), 604-639. doi:10.1198/1061860032030.
Yu SZ (2010). “Hidden semi-Markov models.” Artificial Intelligence, 174, 215-243. doi:10.1016/j.artint.2009.11.011.
# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # Simulating a 2-state IHSMM with SCPG distribution sim_ihsmm1 <- sim.ihsmm.scpg(obj_ihsmm1, nsim = 150, seed = 3) str(sim_ihsmm1[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm1$states)$values) # The fit takes about 30 s, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with SCPG distributions # (the parameters of obj_ihsmm1 are the starting values) fit_ihsmm1 <- fit.ihsmm.scpg(sim_ihsmm1) fit_ihsmm1$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm1$scpg.par$rate # lambda_2 (true 3) fit_ihsmm1$scpg.par$shape # true 1.5 fit_ihsmm1$scpg.par$scale # true 1 fit_ihsmm1$logLik # The fit takes about 30 s, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state IHSMM with SCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_ihsmm1$x <- sim_ihsmm1$x vip_ihsmm1 <- vip.ihsmm.scpg(fit_ihsmm1) head(vip_ihsmm1) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_ihsmm1 <- integer(length(sim_ihsmm1$x)) for (r in seq_len(nrow(vip_ihsmm1))) { last <- vip_ihsmm1[r, 1] path_ihsmm1[(last - vip_ihsmm1[r, 3] + 1):last] <- vip_ihsmm1[r, 2] } table(true = sim_ihsmm1$states, decoded = path_ihsmm1) # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # Simulating a 3-state IHSMM with SCPG distribution sim_ihsmm1_m3 <- sim.ihsmm.scpg(obj_ihsmm1_m3, nsim = 150, seed = 1) print(sim_ihsmm1_m3) # Fitting a 3-state IHSMM with SCPG distributions # The fit takes about 2 minutes, so it is wrapped in donttest. fit_ihsmm1_m3 <- fit.ihsmm.scpg(sim_ihsmm1_m3) print(fit_ihsmm1_m3) # The Viterbi path of fitted 3-state IHSMM with SCPG distribution fit_ihsmm1_m3$x <- sim_ihsmm1_m3$x vip_ihsmm1_m3 <- vip.ihsmm.scpg(fit_ihsmm1_m3) print(vip_ihsmm1_m3) # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # Simulating a 2-state IHSMM with a TSCPG distribution sim_ihsmm2 <- sim.ihsmm.scpg(obj_ihsmm2, nsim = 200, seed = 1) str(sim_ihsmm2[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2$states)$values) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2 are the starting values) fit_ihsmm2 <- fit.ihsmm.scpg(sim_ihsmm2) fit_ihsmm2$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_ihsmm2$scpg.par$scale # true 1 fit_ihsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state IHSMM with TSCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_ihsmm2$x <- sim_ihsmm2$x vip_ihsmm2 <- vip.ihsmm.scpg(fit_ihsmm2) head(vip_ihsmm2) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_ihsmm2 <- integer(length(sim_ihsmm2$x)) for (r in seq_len(nrow(vip_ihsmm2))) { last <- vip_ihsmm2[r, 1] path_ihsmm2[(last - vip_ihsmm2[r, 3] + 1):last] <- vip_ihsmm2[r, 2] } table(true = sim_ihsmm2$states, decoded = path_ihsmm2) # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3) # Simulating a 3-state IHSMM with a TSCPG distribution sim_ihsmm2_m3 <- sim.ihsmm.scpg(obj_ihsmm2_m3, nsim = 250, seed = 2) str(sim_ihsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the time-dependent components are evaluated # on [0, h_{T-1}] c(h_T1 = sum(sim_ihsmm2_m3$x[-250]), h_T = sum(sim_ihsmm2_m3$x)) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2_m3$states)$values) # Fitting a 3-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2_m3 are the starting values). The fit # takes about 8 minutes, so it is wrapped in donttest. fit_ihsmm2_m3 <- fit.ihsmm.scpg(sim_ihsmm2_m3) fit_ihsmm2_m3$ismc.par$tpm # transition matrix of the embedded chain fit_ihsmm2_m3$ismc.par$tdur # A, B, C, D of mu_1(t), mu_2(t) and mu_3(t) fit_ihsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihsmm2_m3$scpg.par$scale # true 0.5 fit_ihsmm2_m3$logLik # The Viterbi path of the fitted 3-state IHSMM with TSCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_ihsmm2_m3$x <- sim_ihsmm2_m3$x vip_ihsmm2_m3 <- vip.ihsmm.scpg(fit_ihsmm2_m3) head(vip_ihsmm2_m3) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_ihsmm2_m3 <- integer(length(sim_ihsmm2_m3$x)) for (r in seq_len(nrow(vip_ihsmm2_m3))) { last <- vip_ihsmm2_m3[r, 1] path_ihsmm2_m3[(last - vip_ihsmm2_m3[r, 3] + 1):last] <- vip_ihsmm2_m3[r, 2] } table(true = sim_ihsmm2_m3$states, decoded = path_ihsmm2_m3)# =========================================================== # An example of a 2-state IHSMM with an SCPG renewal process # =========================================================== # The sojourn parameters mu_j(t) depend on the time at which a visit # commences (rows A, B, C, D of tdur): the expected sojourn 1 + mu_1(t) in # the complete State 1 increases, and that in the incomplete State 2 # decreases, between the levels 1 + A_j = 1.5 and 1 + A_j + B_j = 5.5 # observations, around the inflection time D_j/C_j = 500. In State 2, # the number N of events missing between two observed events is shifted # Poisson with parameter lambda_2. # With m = 2 the chain alternates between the two states. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, # A 4, 4, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(3, nrow = 1, ncol = m-1) # lambda_2 shape <- 1.5 scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 2-state IHSMM with SCPG distribution obj_ihsmm1 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm1) # Simulating a 2-state IHSMM with SCPG distribution sim_ihsmm1 <- sim.ihsmm.scpg(obj_ihsmm1, nsim = 150, seed = 3) str(sim_ihsmm1[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm1$states)$values) # The fit takes about 30 s, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with SCPG distributions # (the parameters of obj_ihsmm1 are the starting values) fit_ihsmm1 <- fit.ihsmm.scpg(sim_ihsmm1) fit_ihsmm1$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm1$scpg.par$rate # lambda_2 (true 3) fit_ihsmm1$scpg.par$shape # true 1.5 fit_ihsmm1$scpg.par$scale # true 1 fit_ihsmm1$logLik # The fit takes about 30 s, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state IHSMM with SCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_ihsmm1$x <- sim_ihsmm1$x vip_ihsmm1 <- vip.ihsmm.scpg(fit_ihsmm1) head(vip_ihsmm1) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_ihsmm1 <- integer(length(sim_ihsmm1$x)) for (r in seq_len(nrow(vip_ihsmm1))) { last <- vip_ihsmm1[r, 1] path_ihsmm1[(last - vip_ihsmm1[r, 3] + 1):last] <- vip_ihsmm1[r, 2] } table(true = sim_ihsmm1$states, decoded = path_ihsmm1) # ========================================================== # An example of a 3-state IHSMM with an SCPG renewal process # ========================================================== # Fitting this 3-state model takes about 2 minutes on a laptop (the # 2-state model above takes about 30 seconds), so the examples that fit # it are wrapped in donttest. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.5, 0.5, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.3, 0.3, 0.3, # A 1.5, 2, 1.5, # B 0.005, 0.005, 0.005, # C 3, 3, 3 # D: inflection times D/C = 600 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd=NULL, tpm=tpm, tdur=tdur, tdur.lb=NA, tdur.ub=NA, stationary=TRUE) rate <- matrix(c(8, 5), nrow = 1, ncol = m-1) shape <- c(2, 1, 1.7) scale <- 1 scpg.par <- list(rate=rate, shape=shape, scale=scale, rate.fix=FALSE, shape.fix=FALSE, time.scpg=FALSE, WBsum.method='direct.evaluation') # Defining an object of 3-state IHSMM with SCPG distribution obj_ihsmm1_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) # Simulating a 3-state IHSMM with SCPG distribution sim_ihsmm1_m3 <- sim.ihsmm.scpg(obj_ihsmm1_m3, nsim = 150, seed = 1) print(sim_ihsmm1_m3) # Fitting a 3-state IHSMM with SCPG distributions # The fit takes about 2 minutes, so it is wrapped in donttest. fit_ihsmm1_m3 <- fit.ihsmm.scpg(sim_ihsmm1_m3) print(fit_ihsmm1_m3) # The Viterbi path of fitted 3-state IHSMM with SCPG distribution fit_ihsmm1_m3$x <- sim_ihsmm1_m3$x vip_ihsmm1_m3 <- vip.ihsmm.scpg(fit_ihsmm1_m3) print(vip_ihsmm1_m3) # ============================================================ # An example of a 2-state IHSMM with a TSCPG renewal process # ============================================================ # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur): the expected # sojourn 1 + mu_1(t) in the complete State 1 increases, and that in the # incomplete State 2 decreases, between the levels 1 + A_j = 2 and # 1 + A_j + B_j = 8 observations, around the inflection time # D_j/C_j = 500; # - the Poisson mean lambda_2(t) of the TSCPG (rows K, M, R, P of rate) # falls from about 5.8 at the start of the record towards K = 0.5, # around the inflection time P/R = 400. m <- 2 tpm <- matrix(c(0, 1, 1, 0), nrow = 2, byrow = TRUE) tdur <- matrix(c( 1, 1, # A 6, 6, # B 0.005, 0.005, # C 2.5, 2.5 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- 0.5 # K rate[2, ] <- 6 # M rate[3, ] <- 0.005 # R rate[4, ] <- 2 # P: inflection time P/R = 400 shape <- 1 scale <- 1 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 2-state IHSMM with TSCPG distribution obj_ihsmm2 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2) # Simulating a 2-state IHSMM with a TSCPG distribution sim_ihsmm2 <- sim.ihsmm.scpg(obj_ihsmm2, nsim = 200, seed = 1) str(sim_ihsmm2[c("x", "states")]) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2$states)$values) # The fit takes several seconds, so the code below is wrapped in donttest. # Fitting a 2-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2 are the starting values) fit_ihsmm2 <- fit.ihsmm.scpg(sim_ihsmm2) fit_ihsmm2$ismc.par$tdur # A, B, C, D of mu_1(t) and mu_2(t) fit_ihsmm2$scpg.par$rate # K, M, R, P of lambda_2(t) fit_ihsmm2$scpg.par$scale # true 1 fit_ihsmm2$logLik # The fit takes several seconds, so the code below is wrapped in donttest. # The Viterbi path of the fitted 2-state IHSMM with TSCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_ihsmm2$x <- sim_ihsmm2$x vip_ihsmm2 <- vip.ihsmm.scpg(fit_ihsmm2) head(vip_ihsmm2) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_ihsmm2 <- integer(length(sim_ihsmm2$x)) for (r in seq_len(nrow(vip_ihsmm2))) { last <- vip_ihsmm2[r, 1] path_ihsmm2[(last - vip_ihsmm2[r, 3] + 1):last] <- vip_ihsmm2[r, 2] } table(true = sim_ihsmm2$states, decoded = path_ihsmm2) # ============================================================ # An example of a 3-state IHSMM with a TSCPG renewal process # ============================================================ # Fitting this 3-state model takes about 8 minutes on a laptop (the # 2-state model above takes about 50 seconds), so the examples that fit # it are wrapped in donttest. # Two kinds of time dependence describe how completeness improves along # the record (see the Details of ?fit.ihsmm.scpg): # - the sojourn parameters mu_j(t) (rows A, B, C, D of tdur), with # inflection times D_j/C_j = 500: the expected sojourn 1 + mu_1(t) in the # complete State 1 increases from about 2.1 towards 6.5 observations, # and those in the incomplete States 2 and 3 decrease from about 5.9 # towards 1.5; # - the Poisson means lambda_j(t) of the TSCPG (rows K, M, R, P of rate): # lambda_2(t) falls from about 3.3 towards 0.5 around 400, and # lambda_3(t) from about 9.8 towards 4 around 600. # The zero-diagonal transition matrix gives the next state of each visit. # The shape 2 makes the interevent times of the three states less # overlapping than with shape 1. m <- 3 tpm <- matrix(c(0, 0.6, 0.4, 0.5, 0, 0.5, 0.6, 0.4, 0), nrow = 3, byrow = TRUE) tdur <- matrix(c( 0.5, 0.5, 0.5, # A 5, 5, 5, # B 0.004, 0.004, 0.004, # C 2, 2, 2 # D: inflection times D/C = 500 ), nrow = 4, byrow = TRUE) ismc.par <- list(initd = NULL, tpm = tpm, tdur = tdur, tdur.lb = NA, tdur.ub = NA, stationary = TRUE) rate <- matrix(NA, nrow = 4, ncol = m - 1) rate[1, ] <- c(0.5, 4) # K rate[2, ] <- c(3, 6) # M rate[3, ] <- c(0.006, 0.006) # R rate[4, ] <- c(2.4, 3.6) # P: inflection times P/R = 400 and 600 shape <- 2 scale <- 0.5 scpg.par <- list(rate = rate, shape = shape, scale = scale, rate.fix = FALSE, shape.fix = TRUE, time.scpg = TRUE, WBsum.method = 'direct.evaluation') # Defining an object of 3-state IHSMM with TSCPG distribution obj_ihsmm2_m3 <- ihsmm.scpg(x = NULL, ismc.par, scpg.par) class(obj_ihsmm2_m3) # Simulating a 3-state IHSMM with a TSCPG distribution sim_ihsmm2_m3 <- sim.ihsmm.scpg(obj_ihsmm2_m3, nsim = 250, seed = 2) str(sim_ihsmm2_m3[c("x", "states")]) # The record covers [0, h_T]; the time-dependent components are evaluated # on [0, h_{T-1}] c(h_T1 = sum(sim_ihsmm2_m3$x[-250]), h_T = sum(sim_ihsmm2_m3$x)) # The duration parameters are informed by the visits, one sojourn each: # number of visits to each state in the simulated path table(rle(sim_ihsmm2_m3$states)$values) # Fitting a 3-state IHSMM with a TSCPG distribution # (the parameters of obj_ihsmm2_m3 are the starting values). The fit # takes about 8 minutes, so it is wrapped in donttest. fit_ihsmm2_m3 <- fit.ihsmm.scpg(sim_ihsmm2_m3) fit_ihsmm2_m3$ismc.par$tpm # transition matrix of the embedded chain fit_ihsmm2_m3$ismc.par$tdur # A, B, C, D of mu_1(t), mu_2(t) and mu_3(t) fit_ihsmm2_m3$scpg.par$rate # K, M, R, P of lambda_2(t) and lambda_3(t) fit_ihsmm2_m3$scpg.par$scale # true 0.5 fit_ihsmm2_m3$logLik # The Viterbi path of the fitted 3-state IHSMM with TSCPG distribution. # Each row describes one decoded visit: the index of its last observation, # its state and its duration (rows run from the end of the record). fit_ihsmm2_m3$x <- sim_ihsmm2_m3$x vip_ihsmm2_m3 <- vip.ihsmm.scpg(fit_ihsmm2_m3) head(vip_ihsmm2_m3) # Expanding the visits into one state per observation and comparing the # decoded states with the simulated ones path_ihsmm2_m3 <- integer(length(sim_ihsmm2_m3$x)) for (r in seq_len(nrow(vip_ihsmm2_m3))) { last <- vip_ihsmm2_m3[r, 1] path_ihsmm2_m3[(last - vip_ihsmm2_m3[r, 3] + 1):last] <- vip_ihsmm2_m3[r, 2] } table(true = sim_ihsmm2_m3$states, decoded = path_ihsmm2_m3)
Evaluates the series
which appears in the SCPG and TSCPG densities of dscpg.
WBsum( x, alpha, WBsum.method = c("direct.evaluation", "direct.asymptotic", "asymptotic.expansion"), tol = 1e-12, max.direct.terms = 2000L, log = FALSE )WBsum( x, alpha, WBsum.method = c("direct.evaluation", "direct.asymptotic", "asymptotic.expansion"), tol = 1e-12, max.direct.terms = 2000L, log = FALSE )
x |
A vector of finite non-negative numbers (the argument |
alpha |
A single finite positive number, the gamma shape |
WBsum.method |
The method, one of
see Details. |
tol |
Relative tolerance. For the direct sum it is a rigorous bound on
the omitted terms; for the asymptotic expansion it is compared with an
empirical error estimate. Values below |
max.direct.terms |
Used only by
|
log |
Logical; if |
The series. is a
special case of Wright's generalized Bessel function (Wright, 1935; Paris,
2017). In the SCPG density . For
every term is positive, so there is no cancellation, and there
is a single largest term, near
(at when is small), and fall away on both sides of it.
The terms, divided by their sum, are the probabilities of the
possible numbers of missing events (minus one) given the observation, so
is about the most probable number of missing events. The number
of terms that contribute grows only like (about
terms exceed times the largest one when
).
The three methods.
"direct.evaluation"sums the series outwards in both
directions from its largest term, as Dunn and Smyth (2005) do for the
Tweedie densities. The terms decrease geometrically on each side, so
the omitted terms are bounded, and summation stops when both bounds
are below tol times the sum. The result is accurate to
tol apart from rounding, which limits the accuracy of
to a small multiple of , with
the machine epsilon (at most about
for up to ). The time
per value is about 0.02 s at , 0.2 s at
and about 2 s at . If any value has
, the call is refused with an error before any sum is
computed.
"asymptotic.expansion"uses the large-argument expansion of
Paris (2010, 2016) in , with ten coefficients
and, for , the
pairs of exponentially small terms; at the exact
identity is used instead. It is
tried only when and accepted only when its error estimate
is below tol; otherwise it stops with an error. With the default
tol it is accepted from about = 72 ( = 0.5),
117 (0.75), 810 (1.5), (2),
(3) and (5), that is,
from between about 29 and 117. Its error estimate is empirical,
not a rigorous bound: just above these points the observed error was up
to about 1.3 times tol.
"direct.asymptotic"chooses between the two for each value.
It predicts the number of direct-series terms as
, a window of about
nine standard deviations on each side of the largest term. If this is
at most max.direct.terms, the direct sum is used; otherwise the
asymptotic expansion is tried, and if it is not accepted the direct sum
is used after all. With the default max.direct.terms = 2000 the
expansion is therefore used when ,
far above the points where it becomes accurate, and the time per value
stays below about 0.01 s. The values agree with those of the direct
sum to within tol, or within the rounding error of the direct
sum (a small multiple of ) if that is larger.
The script verify_WBsum.R in the examples directory of the
package reproduces these numbers; run it in the console with
f <- system.file("examples", "verify_WBsum.R",
package = "HMMscpg")
source(f, echo = TRUE)
When dscpg needs "direct.asymptotic" is explained
there. For every method is evaluated exactly, and
log = TRUE avoids overflow of itself; dscpg
always works with .
The values of , or of when
log = TRUE.
Wright EM (1935). “The asymptotic expansion of the generalized hypergeometric function.” Journal of the London Mathematical Society, 10(4), 286–293.
Paris RB (2017). “The asymptotics of the generalized Bessel function.” Mathematica Aeterna, 7(4), 381–406. doi:10.48550/arXiv.1711.03006.
Dunn PK, Smyth GK (2005). “Series evaluation of Tweedie exponential dispersion model densities.” Stat Comput, 15(4), 267–280. doi:10.1007/s11222-005-4070-y.
Paris RB (2010). “Exponentially small expansions in the asymptotics of the Wright function.” Journal of Computational and Applied Mathematics, 234(2), 488–504.
Paris RB, Vinogradov V (2016). “Asymptotic and structural properties of special cases of the Wright function arising in probability theory.” Lithuanian Mathematical Journal, 56(3), 377–409.