Step-by-Step Case Study: Supply Chain Risk Analysis Using Bayesian Networks in Python

Managing risks in supply chains is a critical engineering challenge, especially for complex logistical and strategic networks. This case study illustrates a step-by-step approach to analyzing supply chain risks via network modeling using Bayesian Networks. Leveraging both supervised and unsupervised learning capabilities, this approach provides actionable insights for enhancing network resilience.

Understanding the Problem

Supply chain networks consist of interconnected suppliers, manufacturers, distribution centers, and retailers. Disruptions at any node or connection can cascade, affecting the entire system’s performance. The goal of this analysis is to model probabilistic dependencies in the network, assess risk propagation, and identify vulnerabilities.

Step 1: Defining Objectives and Data Collection

The objective is to use Bayesian Networks to model conditional dependencies within the supply chain and assess risk impact to improve network resilience.

Sample Dataset (excerpt):

NodeFailure_RateDelay_ImpactSupplied_ByDisruption_Risk
Supplier_A0.05HighNoneLow
Supplier_B0.10MediumSupplier_AMedium
Manufacturer0.07HighSupplier_BHigh
Distributor0.03LowManufacturerMedium
Retailer0.02LowDistributorLow

Failure_Rate indicates probability of failure at the node. Delay_Impact denotes severity of delays. Supplied_By defines network edges.

Step 2: Data Preparation

Encode categorical variables (e.g., Delay_Impact, Disruption_Risk) into numeric form and clean dataset. Python’s pandas is used for dataset handling.

Step 3: Constructing the Bayesian Network Structure

Using the ‘Supplied_By’ relationships, create directed edges representing dependencies:

  • Supplier_A → Supplier_B

  • Supplier_B → Manufacturer

  • Manufacturer → Distributor

  • Distributor → Retailer

Step 4: Model Parameter Learning

Fit conditional probability tables (CPTs) for each node, which describe the probability of node failure or disruption given parent node states. Python package pgmpy is useful here.

python
from pgmpy.models import BayesianNetwork from pgmpy.factors.discrete import TabularCPD from pgmpy.inference import VariableElimination # Define network structure model = BayesianNetwork([('Supplier_A', 'Supplier_B'), ('Supplier_B', 'Manufacturer'), ('Manufacturer', 'Distributor'), ('Distributor', 'Retailer')]) # Example CPTs (simplified) cpd_supplier_a = TabularCPD('Supplier_A', 2, [[0.95], [0.05]]) # 0=No Failure, 1=Failure cpd_supplier_b = TabularCPD('Supplier_B', 2, [[0.98, 0.80], [0.02, 0.20]], evidence=['Supplier_A'], evidence_card=[2]) cpd_manufacturer = TabularCPD('Manufacturer', 2, [[0.97, 0.75], [0.03, 0.25]], evidence=['Supplier_B'], evidence_card=[2]) cpd_distributor = TabularCPD('Distributor', 2, [[0.99, 0.70], [0.01, 0.30]], evidence=['Manufacturer'], evidence_card=[2]) cpd_retailer = TabularCPD('Retailer', 2, [[0.99, 0.60], [0.01, 0.40]], evidence=['Distributor'], evidence_card=[2]) model.add_cpds(cpd_supplier_a, cpd_supplier_b, cpd_manufacturer, cpd_distributor, cpd_retailer) model.check_model()

Step 5: Step-by-Step Calculation Example

Suppose we want to calculate the probability that the Retailer fails (Retailer=1) given that Supplier_A fails (Supplier_A=1). We use the chain rule for Bayesian Networks:

P(Retailer=1Supplier_A=1)=all  other  nodesP(Retailer=1Distributor)×P(DistributorManufacturer)×P(ManufacturerSupplier_B)×P(Supplier_BSupplier_A=1)×P(Supplier_A=1)

Let's break it down step by step:

  1. Supplier_A fails: P(Supplier_A=1)=0.05 (but since we condition on this, it is set to 1 for this calculation).

  2. Supplier_B given Supplier_A fails: P(Supplier_B=1Supplier_A=1)=0.20P(Supplier_B=0Supplier_A=1)=0.80

  3. Manufacturer given Supplier_B:

    • If Supplier_B=1: P(Manufacturer=1Supplier_B=1)=0.25P(Manufacturer=0Supplier_B=1)=0.75

    • If Supplier_B=0: P(Manufacturer=1Supplier_B=0)=0.03P(Manufacturer=0Supplier_B=0)=0.97

  4. Distributor given Manufacturer:

    • If Manufacturer=1: P(Distributor=1Manufacturer=1)=0.30P(Distributor=0Manufacturer=1)=0.70

    • If Manufacturer=0: P(Distributor=1Manufacturer=0)=0.01P(Distributor=0Manufacturer=0)=0.99

  5. Retailer given Distributor:

    • If Distributor=1: P(Retailer=1Distributor=1)=0.40

    • If Distributor=0: P(Retailer=1Distributor=0)=0.01

Now, enumerate all possible paths (Supplier_B, Manufacturer, Distributor) and sum the probabilities:

  • For each combination, multiply the conditional probabilities along the path, then sum for all paths where Retailer=1.

Example Calculation for one path:

  • Supplier_A=1, Supplier_B=1, Manufacturer=1, Distributor=1, Retailer=1:

    • P(SupplierB=1SupplierA=1)=0.20

    • P(Manufacturer=1SupplierB=1)=0.25

    • P(Distributor=1Manufacturer=1)=0.30

    • P(Retailer=1Distributor=1)=0.40

    • Multiply: 0.20×0.25×0.30×0.40=0.006

Repeat for all possible combinations where Retailer=1, sum all such products to get the total probability.

Step 6: Output Table — Conditional Probabilities Example

NodeConditionP(Failure = 1)
Supplier_ANone0.05
Supplier_BSupplier_A = 0 (No failure)0.02
Supplier_BSupplier_A = 1 (Failure)0.20
ManufacturerSupplier_B = 00.03
ManufacturerSupplier_B = 10.25

Step 7: Visualization and Interpretation

Below is an example network graph visualization using NetworkX and matplotlib:

python
import networkx as nx import matplotlib.pyplot as plt G = nx.DiGraph() G.add_edges_from([('Supplier_A', 'Supplier_B'), ('Supplier_B', 'Manufacturer'), ('Manufacturer', 'Distributor'), ('Distributor', 'Retailer')]) pos = nx.spring_layout(G) nx.draw(G, pos, with_labels=True, node_color='lightblue', arrowsize=20) plt.title('Supply Chain Bayesian Network Structure') plt.show()

Interpretation:
This graph shows the flow and dependencies. Bayesian inference quantifies how failure impacts propagate through these paths. For example, a failure at Supplier_A significantly increases the risk of failure at downstream nodes, especially the Retailer.

Step 8: Enhancing Network Resilience

Using insights from the Bayesian Network, strategic decisions include:

  • Diversifying suppliers to reduce dependence.

  • Increasing inventory buffers at critical nodes.

  • Prioritizing risk mitigation efforts based on inferred failure probabilities.

These strategies improve overall network resilience and reduce supply chain disruptions.

Conclusion

Bayesian Networks provide a powerful framework to model complex dependencies in supply chains and perform probabilistic risk assessments. Combining network modeling with Python tools enables engineers to understand vulnerabilities and optimize logistics for greater resilience.