DATA 604 - Week 9 Assignment

Bikash Bhowmik —- 11 Apr 2026

Column

Column

Instructions

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.

Introduction

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 Server
State 3 FinancialReview Server
State 4 Resolved Sink

Transition Probabilities

From State To State Probability
Intake ClinicalReview 0.60
Intake FinancialReview 0.40
ClinicalReview Resolved 0.70
ClinicalReview Intake 0.30
FinancialReview Resolved 0.80
FinancialReview Intake 0.20
Resolved Resolved 1.00

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 Implementation

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.

knitr::include_graphics("simio_model.png")

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.

Logic

A claim enters the Intake stage and is routed to either Clinical Review or Financial Review based on completeness and validation requirements. 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.

set.seed(123)

set.seed(42)
states <- c("Intake", "ClinicalReview", "FinancialReview", "Resolved")

Create Transition Matrix

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)

Build Markov chain object

mc <- new("markovchain", states = states, transitionMatrix = P, name = "ClaimsMC")
mc
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)"

View Report

cat("\nExpected steps to resolution (by starting state):\n")

Expected steps to resolution (by starting state):
print(round(t_steps, 3))
         Intake  ClinicalReview FinancialReview 
          2.703           1.811           1.541 
cat("\nProbability the claim eventually resolves (it should be 1):\n")

Probability the claim eventually resolves (it should be 1):
print(round(B, 4))
                 to
                  Pr(Resolved)
  Intake                     1
  ClinicalReview             1
  FinancialReview            1
cat("\nInterpretation:\n")

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.

Simulation for business KPIs

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)
}

Process Narrative

The process represents a medical claims workflow modeled using four states: Intake, Clinical Review, Financial Review, and Resolved. Claims enter the system through the Intake state, where they are initially received and assessed. Based on predefined probabilities, some claims are simple and move directly to the Resolved state, while others require further evaluation and are routed to Clinical Review or Financial Review for further processing..

In the Clinical Review state, claims are examined for medical necessity and policy compliance. After this evaluation, a portion of claims are resolved, while others proceed to Financial Review for cost validation and payment processing. In the Financial Review state, claims are checked for pricing accuracy, coverage, and coordination of benefits. Most claims are resolved at this stage; however, a small percentage may require rework and are sent back to Intake, creating a feedback loop in the process.

The process terminates when claims reach the Resolved state, which acts as an absorbing state in the system. All transitions between states are governed by fixed probabilities, reflecting a Markov process where the next state depends only on the current state.

KPI

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 ) ---
print(lapply(kpi, function(x) if(is.numeric(x)) round(x, 3) else x))
$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")
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
cat("\nInsights:\n")

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.
cat("- Reducing rework loops can significantly improve processing time.\n")
- 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 65.2% requiring Clinical Review and 48.5% Financial Review. Improving Financial Review efficiency reduces expected steps from 2.7 → 2.6, 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 

View of Matrix as %

percent <- function(x) sprintf("%.1f%%", 100 * x)
cat("\nTransition Matrix (%):\n")

Transition Matrix (%):
P_percent <- round(P*100, 1)
colnames(P_percent) <- states
rownames(P_percent) <- states
P_percent
                 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

Summary

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 ~2.7 steps to reach Resolved, with 65.2% passing through Clinical Review and 48.5% 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

Conclusion

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.