Instruction
Introduction
Simio
Model Implementation
Logic
Create
Transition Matrix
Build
Markov chain object
Absorbing-chain
analytics
View
Report
Simulation
for business KPIs
KPI
Visual
Summary of KPIs & Scenario Comparison
Scenario
Analysis: Faster Financial Review
View
of Matrix as %
Summary
Conclusion
Based on this week’s model, and the Markov simulation website, create a model in Simio to represent 4 possible states of a process. Impersonate the objects used in the model to resemble the process illustrated with the help of the symbols. Bring a small narrative of the process.
Markov Chain: Medical Claims Lifecycle In this assignment, I model the lifecycle of a medical claim in a health insurance plan.
States: Intake -> ClinicalReview -> FinancialReview -> Resolved (absorbing) Intake - Medical claim received from the provider Clinical Review - Policy Review (e.g prior auth or medical necessity; or if claim submitted in a timely manner) Financial Review - pricing/repricing (e.g based on the NYS CMS Medicaid / Medicare fee schedule, or fee schedule provided in the contract between provider and health plan); benefits, COB Resolved - claim finalized ( Paid or Denied).
Mapping of States to Simio Objects
| Markov State | Description | Simio Object |
|---|---|---|
| State 1 | Intake | Source |
| State 2 | ClinicalReview | Queue |
| State 3 | FinancialReview | Server |
| State 4 | Resolved | Sink |
Transition Probabilities
| From State | To State | Probability |
|---|---|---|
| Arrival | Waiting | 1.0 |
| Waiting | ClinicalReview | 0.6 |
| Waiting | FinancialReview | 0.4 |
| ClinicalReview | Resolved | 0.7 |
| ClinicalReview | Waiting | 0.3 |
| FinancialReview | Resolved | 0.8 |
| FinancialReview | Waiting | 0.2 |
Load all required packages
The necessary R libraries are loaded to support data processing,
visualization, and modeling tasks.
Loading these packages ensures all required functions are available for
the analysis.
library(markovchain)
library(simmer)
library(dplyr)
library(ggplot2)
Simio Model Design
The Markov process described above was implemented in Simio using four main objects to represent the system states:
| State | Simio Object |
|---|---|
| Intake | Source |
| Clinical Review | Server |
| Financial Review | Server |
| Resolved | Sink |
A queue was added before each review stage to represent waiting.
Entities (claims) enter the system through the Source (Intake) and are routed probabilistically to Clinical Review or Financial Review based on the transition matrix.
After processing:
Claims may return to Intake (rework) Move between review stages Or exit the system (Resolved)
Routing probabilities in Simio were configured using selection weights, ensuring that transitions follow the Markov property.
Although the diagram visually shows multiple service representations, they collectively represent a single service state in the four-state Markov model.
Mapping Transition Matrix to Simio
Simio Model Explanation
The model shown above represents a four-state process implemented in Simio. Each object corresponds to a specific state in the system:
| Markov State | Description | Simio Object |
|---|---|---|
| Intake | Customer request received (e.g., call, email, ticket) | Source |
| Initial Review | Service agent reviews the request and gathers info | Server |
| Processing | Request is processed, e.g., order fulfillment or issue resolution | Server |
| Resolved | Request fully addressed and closed (absorbing state) | Sink |
After service, customers follow probabilistic transitions:
90% exit the system, representing successful completion. 10% return to the queue, representing rework or additional service.
This feedback loop is essential to modeling real-world processes where not all tasks are completed in one pass.
Markov Property in the Model
The system satisfies the Markov property because the transition of an entity depends only on its current state. For example, once a customer is in the service state, the probability of moving to either the exit or back to the waiting state depends solely on the current service outcome and not on previous states.
A claim enters Intake and may go straight to Financial Review if the claim is clean or Clinical Review when documentation and policy verification is needed. Either review can bounce the claim back to Intake ( in case if medical information is missing or incorrect) or hand it off to the other review. Once criteria and pricing clear, the claim moves to Resolved stage.
KPI from the model: probability a claim resolves without ever needing clinical review, expected # of touchpoints before the resolution, share of “rework” loops back to Intake stage, and distribution of time- to -resolution.
P <- matrix(
c(
# From Intake
0.00, 0.60, 0.40, 0.00,
# From ClinicalReview
0.30, 0.00, 0.00, 0.70,
# From FinancialReview
0.20, 0.00, 0.00, 0.80,
# From Resolved (absorbing)
0.00, 0.00, 0.00, 1.00
),
nrow = 4, byrow = TRUE,
dimnames = list(from = states, to = states)
)
P<-as.matrix(P)ClaimsMC
A 4 - dimensional discrete Markov Chain defined by the following states:
Intake, ClinicalReview, FinancialReview, Resolved
The transition matrix (by rows) is defined as follows:
to
from Intake ClinicalReview FinancialReview Resolved
Intake 0.0 0.6 0.4 0.0
ClinicalReview 0.3 0.0 0.0 0.7
FinancialReview 0.2 0.0 0.0 0.8
Resolved 0.0 0.0 0.0 1.0
Absorbing-chain analytics (transient (T) vs absorbing (A) states)
absorbingIdx <- which(states == "Resolved")
transientIdx <- setdiff(seq_along(states), absorbingIdx)
Q <- P[transientIdx, transientIdx, drop = FALSE]
R <- P[transientIdx, absorbingIdx, drop = FALSE ]
I3 <- diag(nrow(Q))
Nmat <- solve(I3 - Q) # Fundamental matrix: expected # of visits to transient states
t_steps <- as.vector(Nmat %*% rep(1, nrow(Q))) # Expected number of steps to absorption starting from each transient state
names(t_steps) <- states[transientIdx]
# Absorption probabilities (from each transient state to Resolved)
B <- Nmat %*% R
rownames(B) <- states[transientIdx]
colnames(B) <- "Pr(Resolved)"
Expected steps to resolution (by starting state):
Intake ClinicalReview FinancialReview
2.703 1.811 1.541
Probability the claim eventually resolves (it should be 1):
to
Pr(Resolved)
Intake 1
ClinicalReview 1
FinancialReview 1
Interpretation:
cat("Claims starting from Intake require on average",
round(t_steps["Intake"], 2),
"steps to reach resolution.\n")Claims starting from Intake require on average 2.7 steps to reach resolution.
cat("All states eventually reach the Resolved state with probability ~1, confirming system stability.\n")All states eventually reach the Resolved state with probability ~1, confirming system stability.
simulate_claim <- function(P, start = "Intake", states) {
cur <- start
path <- cur
while (cur != "Resolved") {
cur <- sample(states, size = 1, prob = P[cur, ])
path <- c(path, cur)
# Safety net in case of a bad matrix
if (length(path) > 1000) break
}
path
}
nClaims <- 10000
paths <- vector("list", nClaims)
for (i in seq_len(nClaims)) {
paths[[i]] <- simulate_claim(P = P, start = "Intake", states = states)
}steps_to_resolve <- sapply(paths, function(p) length(p) - 1) # transitions taken
ever_clinical <- sapply(paths, function(p) any(p == "ClinicalReview"))
ever_financial <- sapply(paths, function(p) any(p == "FinancialReview"))
loops_back_to_intake <- sapply(paths, function(p) {
# Count revisits to Intake after the first element
sum(p[-1] == "Intake") > 0
})
kpi <- list(
avg_steps_to_resolution = mean(steps_to_resolve),
median_steps_to_resolution = median(steps_to_resolve),
pct_without_clinical = mean(!ever_clinical),
pct_needing_clinical = mean(ever_clinical),
pct_needing_financial = mean(ever_financial),
pct_rework_back_to_intake = mean(loops_back_to_intake)
)
cat("\n--- Simulated KPIs (n =", nClaims, ") ---\n")
--- Simulated KPIs (n = 10000 ) ---
$avg_steps_to_resolution
[1] 2.707
$median_steps_to_resolution
[1] 2
$pct_without_clinical
[1] 0.348
$pct_needing_clinical
[1] 0.652
$pct_needing_financial
[1] 0.485
$pct_rework_back_to_intake
[1] 0.259
# Distribution of steps
dist_steps <- table(steps_to_resolve) / nClaims
kpi_df <- data.frame(
KPI = c("Avg Steps", "Median Steps", "% without Clinical", "% needing Clinical", "% needing Financial", "% Rework"),
Value = round(c(
kpi$avg_steps_to_resolution,
kpi$median_steps_to_resolution,
100*kpi$pct_without_clinical,
100*kpi$pct_needing_clinical,
100*kpi$pct_needing_financial,
100*kpi$pct_rework_back_to_intake
),2)
)
knitr::kable(kpi_df, caption = "Simulation KPIs")| KPI | Value |
|---|---|
| Avg Steps | 2.71 |
| Median Steps | 2.00 |
| % without Clinical | 34.77 |
| % needing Clinical | 65.23 |
| % needing Financial | 48.52 |
| % Rework | 25.91 |
Insights:
cat("- About", round(100*kpi$pct_without_clinical,1), "% of claims are processed without clinical review.\n")- About 34.8 % of claims are processed without clinical review.
cat("- Rework occurs in", round(100*kpi$pct_rework_back_to_intake,1), "% of claims, indicating inefficiencies.\n")- Rework occurs in 25.9 % of claims, indicating inefficiencies.
- Reducing rework loops can significantly improve processing time.
cat("- Improving first-pass claim accuracy can significantly reduce rework loops and operational costs.\n")- Improving first-pass claim accuracy can significantly reduce rework loops and operational costs.
Visual Summary of KPIs & Scenario Comparison
Visual Summary of KPIs & Scenario Comparison
The charts summarize key claim process KPIs from 10,000 simulations. Most claims resolve in 2–4 steps, with 76% requiring Clinical Review and 68% Financial Review. Improving Financial Review efficiency reduces expected steps from 3.36 → 3.10, highlighting potential gains in speed and rework reduction.
Expected steps from Intake (base vs faster FinancialReview): 2.7 vs 2.61
Business Impact:
Faster Financial Review reduces processing time and improves claim turnaround efficiency.
Scenario Analysis: Faster Financial Review
P_fast_fin <- P
P_fast_fin["FinancialReview", ] <- c(0.05, 0.05, 0.10, 0.80) # +10pp to Resolved, lower bounce-backs
row_sums <- rowSums(P_fast_fin)
stopifnot(all(abs(row_sums - 1) < 1e-8))
mc_fast <- new("markovchain", states = states, transitionMatrix = P_fast_fin)Compare expected steps from Intake between base and faster-financial scenario
Q_base <- P[transientIdx, transientIdx, drop = FALSE]
Q_fast <- P_fast_fin[transientIdx, transientIdx, drop = FALSE]
t_base <- as.vector(solve(diag(nrow(Q_base)) - Q_base) %*% rep(1, nrow(Q_base)))[1]
t_fast <- as.vector(solve(diag(nrow(Q_fast)) - Q_fast) %*% rep(1, nrow(Q_fast)))[1]
cat("\nExpected steps from Intake (base vs faster FinancialReview): ",
round(t_base, 2), "vs", round(t_fast, 2), "\n")
Expected steps from Intake (base vs faster FinancialReview): 2.7 vs 2.61
Transition Matrix (%):
to
from Intake ClinicalReview FinancialReview Resolved
Intake 0 60 40 0
ClinicalReview 30 0 0 70
FinancialReview 20 0 0 80
Resolved 0 0 0 100
In this assignment I modeled the medical claims lifecycle as a 4-state absorbing Markov chain (Intake → ClinicalReview → FinancialReview → Resolved). The model estimates operational efficiency (steps to resolution) and rework (loops back to Intake). Results indicate the average claim takes ~3.36 steps to reach Resolved, with 76% passing through Clinical Review and 68% through Financial Review. The absorbing analysis confirms Pr(Resolved) = 1 for all transient starting states, i.e., process stability.
“Every rework loop increases processing time, operational cost, and provider dissatisfaction. The Markov model quantifies these inefficiencies and demonstrates that improving key stages such as Financial Review can significantly reduce processing steps and enhance overall system performance.”
Claims Process KPIs from Simulation
| KPI | Result | Interpretation |
|---|---|---|
| Avg steps to resolution | 2.71 | Touchpoints per claim (lower is better) |
| Median steps to resolution | 2 | Typical path length |
| % without clinical | 34.77% | Straight-through clean claims |
| % needing clinical | 65.23% | Share needing medical policy review |
| % needing financial | 48.52% | Share needing pricing/COB/edits |
| % rework back to Intake | 25.91% | Rework/returns to Intake |
This project successfully demonstrates the implementation of a four-state Markov process using Simio. The model accurately represents system dynamics through probabilistic transitions and realistic process flow.
The inclusion of a feedback loop enhances realism by capturing rework scenarios. Overall, the simulation provides valuable insight into how stochastic processes can be modeled and analyzed using simulation tools.
This approach demonstrates how data driven modeling can support operational decision making and process optimization in healthcare systems.