mcpField
R
risk-mitigation

risk-mitigation

github.com/kishorkukrejaその他8449 回インストール3 週間前に更新
リポジトリ

risk-mitigation について

サプライチェーンチームがリスクを特定・評価・定量化して軽減し、レジリエンスを高めるためのスキルです。リスク分類、定量評価やシナリオ計画、対応策、レポート形式を扱います。

主な機能

  1. 01サプライチェーンリスクの分類と評価
  2. 02定量的なリスクモデリング
  3. 03中断シナリオとストレステスト
  4. 04回避・軽減・移転・受容の戦略
  5. 05レジリエンス計画とリスクレポート

活用シーン

  1. 01サプライチェーン各層のリスク評価
  2. 02サプライヤー障害や物流中断のシナリオ検証
  3. 03リスクに応じた軽減策の優先順位付け
  4. 04レジリエンスと事業継続計画の策定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/kishorkukreja/awesome-supply-chain --skill risk-mitigation

インストール後、Claude Code で/risk-mitigationを入力して読み込まれたか確認します。

詳細

リスク軽減

サプライチェーンのリスク管理とレジリエンスの専門家として、組織がサプライチェーン全体のリスクを特定、評価、定量化、軽減しながら、混乱に対応する適応力を構築できるよう支援します。

初期評価

リスク軽減戦略を策定する前に、以下を把握します。

  1. リスクの背景

    • 最近、どのような混乱が発生しましたか?
    • 業界固有のリスクへの露出はありますか?
    • 地理的なリスクの集中はありますか?
    • 現在のリスク管理の成熟度はどの程度ですか?
  2. サプライチェーンの複雑さ

    • サプライチェーンには何段階の階層がありますか?
    • グローバル展開ですか、それとも地域展開ですか?
    • 単一調達への依存はありますか?
    • リードタイムの長さと変動幅はどの程度ですか?
  3. 事業影響の許容度

    • 許容できる最大のダウンタイムはどの程度ですか?
    • 混乱によってリスクにさらされる収益はどの程度ですか?
    • 顧客との SLA に関する違約金はありますか?
    • ブランドの評判に関する懸念はありますか?
  4. 既存の能力

    • 現在、どのようなリスク監視プロセスを実施していますか?
    • 事業継続計画は整備されていますか?
    • バッファ在庫を維持していますか?
    • 生産や物流に柔軟性はありますか?

リスク管理フレームワーク

リスクの分類

1. 供給リスク

  • サプライヤーの破綻や倒産
  • 品質問題やリコール
  • 生産能力の制約
  • 原材料の不足
  • 単一調達への依存
  • サプライヤーの集中

2. 需要リスク

  • 需要の変動
  • 需要予測の不正確さ
  • 新製品の不確実性
  • 市場の変化
  • 顧客の集中
  • ブルウィップ効果

3. オペレーショナルリスク

  • 生産の混乱
  • 設備の故障
  • 品質不良
  • IT システムの停止
  • 労働争議
  • プロセスの障害

4. 物流リスク

  • 輸送の遅延
  • 港湾の混雑
  • 運送業者の業務停止
  • 通関上の問題
  • ラストマイルの課題
  • 倉庫の業務停止

5. 外部リスク

  • 自然災害(ハリケーン、地震、洪水)
  • パンデミックや健康危機
  • 地政学的事象(戦争、制裁)
  • サイバー攻撃
  • テロ
  • 気候変動の影響

6. 財務リスク

  • 為替変動
  • 商品価格の変動
  • 信用リスク
  • 支払いの遅延
  • 景気後退
  • インフレーション

7. 規制・コンプライアンスリスク

  • 規制の変更
  • 貿易制限
  • 関税および諸税
  • 環境規制
  • 製品安全基準
  • データプライバシー法

リスク評価の方法論

定量的なリスクモデリング
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt

class SupplyChainRiskAssessment:
    """Comprehensive supply chain risk assessment framework"""

    def __init__(self):
        self.risk_register = []

    def add_risk(self, risk_id, risk_name, category, probability,
                impact_revenue, impact_days, current_controls,
                residual_probability=None):
        """
        Add risk to risk register

        probability: likelihood (0-1)
        impact_revenue: financial impact ($)
        impact_days: operational impact (days of disruption)
        """

        # If residual probability not provided, assume controls reduce by 30%
        if residual_probability is None:
            residual_probability = probability * 0.7

        # Calculate risk scores
        inherent_risk_score = probability * impact_revenue
        residual_risk_score = residual_probability * impact_revenue

        # Risk level classification
        def classify_risk(score):
            if score > 1000000:
                return 'Critical'
            elif score > 500000:
                return 'High'
            elif score > 100000:
                return 'Medium'
            else:
                return 'Low'

        self.risk_register.append({
            'risk_id': risk_id,
            'risk_name': risk_name,
            'category': category,
            'inherent_probability': probability,
            'residual_probability': residual_probability,
            'impact_revenue': impact_revenue,
            'impact_days': impact_days,
            'inherent_risk_score': inherent_risk_score,
            'residual_risk_score': residual_risk_score,
            'inherent_risk_level': classify_risk(inherent_risk_score),
            'residual_risk_level': classify_risk(residual_risk_score),
            'current_controls': current_controls,
            'risk_reduction': inherent_risk_score - residual_risk_score
        })

    def calculate_value_at_risk(self, confidence_level=0.95):
        """
        Calculate Value at Risk (VaR) for supply chain

        VaR = maximum expected loss at given confidence level
        """

        df = pd.DataFrame(self.risk_register)

        if len(df) == 0:
            return None

        # Monte Carlo simulation of risk events
        n_simulations = 10000
        simulation_results = []

        for _ in range(n_simulations):
            total_loss = 0

            for _, risk in df.iterrows():
                # Simulate if risk occurs
                if np.random.random() < risk['residual_probability']:
                    # Loss if risk occurs (with some variability)
                    loss = np.random.normal(
                        risk['impact_revenue'],
                        risk['impact_revenue'] * 0.2  # 20% std dev
                    )
                    total_loss += abs(loss)

            simulation_results.append(total_loss)

        simulation_results = np.array(simulation_results)

        # Calculate VaR
        var = np.percentile(simulation_results, confidence_level * 100)

        # Calculate CVaR (Conditional VaR - expected loss beyond VaR)
        cvar = simulation_results[simulation_results >= var].mean()

        # Expected annual loss
        expected_loss = simulation_results.mean()

        return {
            'value_at_risk': round(var, 2),
            'conditional_var': round(cvar, 2),
            'expected_annual_loss': round(expected_loss, 2),
            'confidence_level': confidence_level,
            'max_simulated_loss': round(simulation_results.max(), 2),
            'simulations': n_simulations
        }

    def prioritize_risks(self):
        """Generate prioritized risk register"""

        df = pd.DataFrame(self.risk_register)

        if len(df) == 0:
            return df

        # Sort by residual risk score descending
        df = df.sort_values('residual_risk_score', ascending=False)

        # Add ranking
        df['priority_rank'] = range(1, len(df) + 1)

        return df

    def identify_mitigation_priorities(self, budget_limit=None):
        """
        Identify which risks to prioritize for mitigation investment

        Uses cost-benefit approach
        """

        df = self.prioritize_risks()

        # Calculate mitigation value (risk reduction potential)
        df['mitigation_value'] = df['inherent_risk_score'] - df['residual_risk_score']

        # Estimate mitigation cost (simplified: 10% of impact)
        df['estimated_mitigation_cost'] = df['impact_revenue'] * 0.10

        # ROI of mitigation
        df['mitigation_roi'] = df['mitigation_value'] / df['estimated_mitigation_cost']

        # Sort by ROI descending
        df = df.sort_values('mitigation_roi', ascending=False)

        if budget_limit:
            # Select risks within budget
            df['cumulative_cost'] = df['estimated_mitigation_cost'].cumsum()
            df['within_budget'] = df['cumulative_cost'] <= budget_limit
        else:
            df['within_budget'] = True

        return df

    def calculate_supply_chain_resilience_index(self, resilience_factors):
        """
        Calculate Supply Chain Resilience Index

        resilience_factors: dict with various resilience metrics
        """

        # Resilience dimensions (0-100 scale)
        flexibility = resilience_factors.get('flexibility', 50)
        redundancy = resilience_factors.get('redundancy', 50)
        visibility = resilience_factors.get('visibility', 50)
        collaboration = resilience_factors.get('collaboration', 50)
        agility = resilience_factors.get('agility', 50)
        robustness = resilience_factors.get('robustness', 50)

        # Weighted average
        weights = {
            'flexibility': 0.20,
            'redundancy': 0.20,
            'visibility': 0.15,
            'collaboration': 0.15,
            'agility': 0.15,
            'robustness': 0.15
        }

        resilience_index = (
            flexibility * weights['flexibility'] +
            redundancy * weights['redundancy'] +
            visibility * weights['visibility'] +
            collaboration * weights['collaboration'] +
            agility * weights['agility'] +
            robustness * weights['robustness']
        )

        # Classify resilience level
        if resilience_index >= 80:
            level = 'Highly Resilient'
        elif resilience_index >= 65:
            level = 'Resilient'
        elif resilience_index >= 50:
            level = 'Moderately Resilient'
        elif resilience_index >= 35:
            level = 'Vulnerable'
        else:
            level = 'Highly Vulnerable'

        return {
            'resilience_index': round(resilience_index, 1),
            'resilience_level': level,
            'dimension_scores': {
                'flexibility': flexibility,
                'redundancy': redundancy,
                'visibility': visibility,
                'collaboration': collaboration,
                'agility': agility,
                'robustness': robustness
            }
        }


# Example usage
risk_assessment = SupplyChainRiskAssessment()

# Add various risks
risk_assessment.add_risk(
    risk_id='R001',
    risk_name='Single-source supplier failure',
    category='Supply',
    probability=0.15,
    impact_revenue=2000000,
    impact_days=90,
    current_controls='Quarterly reviews, financial monitoring',
    residual_probability=0.10
)

risk_assessment.add_risk(
    risk_id='R002',
    risk_name='Port congestion (West Coast)',
    category='Logistics',
    probability=0.25,
    impact_revenue=500000,
    impact_days=30,
    current_controls='Dual port strategy, air freight backup',
    residual_probability=0.15
)

risk_assessment.add_risk(
    risk_id='R003',
    risk_name='Demand forecast error (new product)',
    category='Demand',
    probability=0.40,
    impact_revenue=800000,
    impact_days=60,
    current_controls='Market research, test markets',
    residual_probability=0.30
)

risk_assessment.add_risk(
    risk_id='R004',
    risk_name='Cyberattack on systems',
    category='External',
    probability=0.20,
    impact_revenue=3000000,
    impact_days=45,
    current_controls='Firewalls, backups, monitoring',
    residual_probability=0.12
)

risk_assessment.add_risk(
    risk_id='R005',
    risk_name='Natural disaster (supplier location)',
    category='External',
    probability=0.10,
    impact_revenue=1500000,
    impact_days=120,
    current_controls='Insurance, geographic diversification',
    residual_probability=0.08
)

# Prioritize risks
risk_register = risk_assessment.prioritize_risks()
print("Risk Register (Prioritized):")
print(risk_register[['risk_id', 'risk_name', 'residual_risk_level', 'residual_risk_score']])

# Calculate Value at Risk
var_result = risk_assessment.calculate_value_at_risk(confidence_level=0.95)
print(f"\n\nValue at Risk (95% confidence): ${var_result['value_at_risk']:,.2f}")
print(f"Expected Annual Loss: ${var_result['expected_annual_loss']:,.2f}")
print(f"Conditional VaR: ${var_result['conditional_var']:,.2f}")

# Mitigation priorities
mitigation_priorities = risk_assessment.identify_mitigation_priorities(budget_limit=500000)
print("\n\nMitigation Priorities:")
print(mitigation_priorities[['risk_id', 'risk_name', 'mitigation_roi', 'estimated_mitigation_cost', 'within_budget']])

# Calculate resilience index
resilience_factors = {
    'flexibility': 65,      # Supply/production flexibility
    'redundancy': 55,       # Backup suppliers, inventory
    'visibility': 70,       # End-to-end visibility
    'collaboration': 60,    # Partner collaboration
    'agility': 58,          # Speed of response
    'robustness': 62        # Ability to withstand shocks
}

resilience = risk_assessment.calculate_supply_chain_resilience_index(resilience_factors)
print(f"\n\nSupply Chain Resilience Index: {resilience['resilience_index']}/100")
print(f"Resilience Level: {resilience['resilience_level']}")

シナリオ計画とストレステスト

混乱シナリオのモデリング
class ScenarioPlanner:
    """Model and analyze supply chain disruption scenarios"""

    def __init__(self, baseline_data):
        self.baseline = baseline_data
        self.scenarios = []

    def add_scenario(self, scenario_name, probability, disruption_impacts):
        """
        Add disruption scenario

        disruption_impacts: dict with impact parameters
        """

        # Calculate scenario impact
        revenue_impact = disruption_impacts.get('revenue_loss', 0)
        cost_impact = disruption_impacts.get('additional_costs', 0)
        duration_days = disruption_impacts.get('duration_days', 0)

        total_impact = revenue_impact + cost_impact

        # Calculate expected value (probability-weighted)
        expected_impact = total_impact * probability

        # Recovery time
        recovery_days = disruption_impacts.get('recovery_days', duration_days * 1.5)

        self.scenarios.append({
            'scenario': scenario_name,
            'probability': probability,
            'revenue_loss': revenue_impact,
            'additional_costs': cost_impact,
            'total_impact': total_impact,
            'expected_impact': expected_impact,
            'duration_days': duration_days,
            'recovery_days': recovery_days,
            'affected_revenue_pct': (revenue_impact / self.baseline['annual_revenue'] * 100)
        })

    def stress_test(self, scenario_name):
        """
        Perform stress test for specific scenario

        Models cascade effects and secondary impacts
        """

        scenario = next((s for s in self.scenarios if s['scenario'] == scenario_name), None)

        if not scenario:
            return None

        # Calculate cascade effects
        primary_impact = scenario['total_impact']

        # Secondary impacts (simplified model)
        # 1. Customer penalties for late delivery
        late_delivery_penalty = primary_impact * 0.15

        # 2. Inventory carrying costs (if building buffer)
        additional_inventory_cost = primary_impact * 0.08

        # 3. Expediting costs (air freight, overtime)
        expediting_cost = primary_impact * 0.20

        # 4. Lost customer goodwill (long-term revenue impact)
        customer_attrition_impact = primary_impact * 0.25

        # Total impact with cascades
        total_with_cascade = (
            primary_impact +
            late_delivery_penalty +
            additional_inventory_cost +
            expediting_cost +
            customer_attrition_impact
        )

        return {
            'scenario': scenario_name,
            'primary_impact': round(primary_impact, 2),
            'secondary_impacts': {
                'late_delivery_penalties': round(late_delivery_penalty, 2),
                'inventory_costs': round(additional_inventory_cost, 2),
                'expediting_costs': round(expediting_cost, 2),
                'customer_attrition': round(customer_attrition_impact, 2)
            },
            'total_impact_with_cascade': round(total_with_cascade, 2),
            'cascade_multiplier': round(total_with_cascade / primary_impact, 2)
        }

    def compare_scenarios(self):
        """Compare all scenarios"""

        df = pd.DataFrame(self.scenarios)

        if len(df) == 0:
            return df

        # Sort by expected impact descending
        df = df.sort_values('expected_impact', ascending=False)

        return df

    def monte_carlo_portfolio_risk(self, n_simulations=10000):
        """
        Monte Carlo simulation of portfolio risk

        Simulates multiple disruptions occurring in same year
        """

        results = []

        for _ in range(n_simulations):
            annual_impact = 0

            for scenario in self.scenarios:
                # Check if this scenario occurs
                if np.random.random() < scenario['probability']:
                    # Add impact with variability
                    impact = np.random.normal(
                        scenario['total_impact'],
                        scenario['total_impact'] * 0.25  # 25% std dev
                    )
                    annual_impact += abs(impact)

            results.append(annual_impact)

        results = np.array(results)

        # Calculate statistics
        var_95 = np.percentile(results, 95)
        var_99 = np.percentile(results, 99)
        expected_loss = results.mean()
        max_loss = results.max()

        return {
            'expected_annual_loss': round(expected_loss, 2),
            'var_95': round(var_95, 2),
            'var_99': round(var_99, 2),
            'maximum_simulated_loss': round(max_loss, 2),
            'probability_zero_loss': round((results == 0).sum() / n_simulations * 100, 1),
            'probability_major_loss': round((results > self.baseline['annual_revenue'] * 0.05).sum() / n_simulations * 100, 1)
        }


# Example scenario planning
baseline = {
    'annual_revenue': 100000000,
    'operating_margin': 0.15,
    'inventory_value': 15000000
}

planner = ScenarioPlanner(baseline)

# Add scenarios
planner.add_scenario(
    'Major supplier failure',
    probability=0.10,
    disruption_impacts={
        'revenue_loss': 5000000,
        'additional_costs': 1000000,
        'duration_days': 90,
        'recovery_days': 120
    }
)

planner.add_scenario(
    'Pandemic (COVID-like)',
    probability=0.05,
    disruption_impacts={
        'revenue_loss': 15000000,
        'additional_costs': 3000000,
        'duration_days': 180,
        'recovery_days': 365
    }
)

planner.add_scenario(
    'Regional natural disaster',
    probability=0.15,
    disruption_impacts={
        'revenue_loss': 3000000,
        'additional_costs': 800000,
        'duration_days': 60,
        'recovery_days': 90
    }
)

planner.add_scenario(
    'Geopolitical crisis (trade restrictions)',
    probability=0.20,
    disruption_impacts={
        'revenue_loss': 8000000,
        'additional_costs': 2000000,
        'duration_days': 120,
        'recovery_days': 180
    }
)

planner.add_scenario(
    'Cyberattack (ransomware)',
    probability=0.12,
    disruption_impacts={
        'revenue_loss': 4000000,
        'additional_costs': 1500000,
        'duration_days': 30,
        'recovery_days': 45
    }
)

# Compare scenarios
comparison = planner.compare_scenarios()
print("Scenario Comparison:")
print(comparison[['scenario', 'probability', 'total_impact', 'expected_impact', 'duration_days']])

# Stress test specific scenario
stress_result = planner.stress_test('Pandemic (COVID-like)')
print(f"\n\nStress Test: Pandemic Scenario")
print(f"Primary Impact: ${stress_result['primary_impact']:,.2f}")
print(f"Total with Cascade: ${stress_result['total_impact_with_cascade']:,.2f}")
print(f"Cascade Multiplier: {stress_result['cascade_multiplier']}x")

# Monte Carlo simulation
mc_results = planner.monte_carlo_portfolio_risk(n_simulations=10000)
print(f"\n\nMonte Carlo Risk Analysis:")
print(f"Expected Annual Loss: ${mc_results['expected_annual_loss']:,.2f}")
print(f"Value at Risk (95%): ${mc_results['var_95']:,.2f}")
print(f"Value at Risk (99%): ${mc_results['var_99']:,.2f}")
print(f"Probability of Major Loss (>5% revenue): {mc_results['probability_major_loss']}%")

軽減戦略

リスク対応フレームワーク

1. 回避

  • リスクの発生源を排除する
  • リスクの高い市場やサプライヤーから撤退する
  • 依存関係を避けるよう製品設計を変更する

2. 低減

  • 発生可能性や影響を抑える管理策を導入する
  • 複数調達、安全在庫、プロセス改善を実施する
  • 最も一般的な戦略です

3. 移転

  • リスクを別の当事者に移す
  • 保険、違約金条項を含む契約、アウトソーシングを活用する
  • 移転にかかるコストが妥当であることを確認する必要があります

4. 受容

  • リスクを意識的に受け入れる
  • 発生確率と影響が低いリスクを対象とする
  • コンティンジェンシープランを準備しておく
レジリエンス構築戦略
class ResilienceBuilder:
    """Build supply chain resilience through strategic interventions"""

    def __init__(self, current_state):
        self.current_state = current_state
        self.interventions = []

    def evaluate_dual_sourcing(self, primary_supplier, backup_supplier, demand):
        """
        Evaluate dual sourcing strategy

        Compares cost vs. resilience benefit
        """

        # Single source scenario
        single_source_cost = demand * primary_supplier['unit_cost']

        # Risk of disruption
        disruption_probability = primary_supplier['disruption_probability']
        disruption_cost = primary_supplier['disruption_cost']

        single_source_expected_cost = single_source_cost + (disruption_probability * disruption_cost)

        # Dual source scenario (60/40 split)
        primary_volume = demand * 0.6
        backup_volume = demand * 0.4

        dual_source_cost = (
            primary_volume * primary_supplier['unit_cost'] +
            backup_volume * backup_supplier['unit_cost']
        )

        # Reduced disruption risk (assume 70% reduction)
        reduced_disruption_prob = disruption_probability * 0.3
        dual_source_expected_cost = dual_source_cost + (reduced_disruption_prob * disruption_cost)

        # Analysis
        additional_cost = dual_source_cost - single_source_cost
        risk_reduction = single_source_expected_cost - dual_source_expected_cost

        return {
            'single_source_cost': round(single_source_cost, 2),
            'single_source_expected_cost': round(single_source_expected_cost, 2),
            'dual_source_cost': round(dual_source_cost, 2),
            'dual_source_expected_cost': round(dual_source_expected_cost, 2),
            'additional_cost': round(additional_cost, 2),
            'risk_reduction': round(risk_reduction, 2),
            'net_benefit': round(risk_reduction - additional_cost, 2),
            'recommendation': 'Implement dual sourcing' if risk_reduction > additional_cost else 'Maintain single source'
        }

    def evaluate_safety_stock(self, demand_data, lead_time_data, target_service_level=0.95):
        """
        Evaluate optimal safety stock for risk mitigation

        Balances inventory cost vs. stockout risk
        """

        # Demand parameters
        avg_daily_demand = demand_data['avg_daily_demand']
        demand_std = demand_data['demand_std']

        # Lead time parameters
        avg_lead_time = lead_time_data['avg_lead_time_days']
        lead_time_std = lead_time_data['lead_time_std_days']

        # Safety stock calculation
        z_score = stats.norm.ppf(target_service_level)

        # Combined variability
        variance_during_lt = (
            avg_lead_time * demand_std**2 +
            avg_daily_demand**2 * lead_time_std**2
        )
        std_during_lt = np.sqrt(variance_during_lt)

        safety_stock = z_score * std_during_lt

        # Cost analysis
        unit_cost = demand_data['unit_cost']
        holding_cost_rate = 0.25  # 25% annual holding cost

        annual_holding_cost = safety_stock * unit_cost * holding_cost_rate

        # Stockout cost avoided
        stockout_probability_without_ss = 0.50  # 50% chance without safety stock
        stockout_probability_with_ss = 1 - target_service_level

        stockout_cost_per_event = demand_data['stockout_cost_per_event']
        stockouts_per_year = 365 / avg_lead_time  # Number of replenishment cycles

        stockout_cost_avoided = (
            (stockout_probability_without_ss - stockout_probability_with_ss) *
            stockouts_per_year *
            stockout_cost_per_event
        )

        net_benefit = stockout_cost_avoided - annual_holding_cost

        return {
            'safety_stock_units': round(safety_stock, 0),
            'safety_stock_value': round(safety_stock * unit_cost, 2),
            'annual_holding_cost': round(annual_holding_cost, 2),
            'stockout_cost_avoided': round(stockout_cost_avoided, 2),
            'net_annual_benefit': round(net_benefit, 2),
            'days_of_supply': round(safety_stock / avg_daily_demand, 1),
            'service_level_achieved': target_service_level
        }

    def evaluate_nearshoring(self, offshore_option, nearshore_option, demand):
        """
        Evaluate nearshoring to reduce supply chain risk

        Compare offshore vs. nearshore sourcing
        """

        # Offshore scenario
        offshore_cost = demand * offshore_option['unit_cost']
        offshore_lead_time = offshore_option['lead_time_days']
        offshore_disruption_risk = offshore_option['disruption_probability']
        offshore_disruption_cost = offshore_option['disruption_cost']

        offshore_total_cost = offshore_cost + (offshore_disruption_risk * offshore_disruption_cost)

        # Nearshore scenario
        nearshore_cost = demand * nearshore_option['unit_cost']
        nearshore_lead_time = nearshore_option['lead_time_days']
        nearshore_disruption_risk = nearshore_option['disruption_probability']
        nearshore_disruption_cost = nearshore_option['disruption_cost']

        nearshore_total_cost = nearshore_cost + (nearshore_disruption_risk * nearshore_disruption_cost)

        # Benefits
        lead_time_reduction = offshore_lead_time - nearshore_lead_time
        inventory_reduction = lead_time_reduction * (demand / 365) * nearshore_option['unit_cost'] * 0.25

        risk_reduction = (
            (offshore_disruption_risk * offshore_disruption_cost) -
            (nearshore_disruption_risk * nearshore_disruption_cost)
        )

        # Incremental cost
        incremental_cost = nearshore_cost - offshore_cost

        # Net benefit
        total_benefit = risk_reduction + inventory_reduction
        net_benefit = total_benefit - incremental_cost

        return {
            'offshore_total_cost': round(offshore_total_cost, 2),
            'nearshore_total_cost': round(nearshore_total_cost, 2),
            'incremental_cost': round(incremental_cost, 2),
            'lead_time_reduction_days': lead_time_reduction,
            'risk_reduction_value': round(risk_reduction, 2),
            'inventory_reduction_value': round(inventory_reduction, 2),
            'total_benefit': round(total_benefit, 2),
            'net_benefit': round(net_benefit, 2),
            'payback_period_years': round(abs(incremental_cost / total_benefit), 2) if total_benefit > 0 else float('inf'),
            'recommendation': 'Nearshore' if net_benefit > 0 else 'Remain offshore'
        }


# Example resilience building
current_state = {
    'annual_revenue': 50000000,
    'supply_chain_cost': 30000000
}

resilience_builder = ResilienceBuilder(current_state)

# Evaluate dual sourcing
primary = {
    'unit_cost': 10.00,
    'disruption_probability': 0.15,
    'disruption_cost': 2000000
}

backup = {
    'unit_cost': 10.80,  # 8% premium
    'disruption_probability': 0.05,
    'disruption_cost': 500000
}

dual_sourcing_result = resilience_builder.evaluate_dual_sourcing(
    primary, backup, demand=1000000
)

print("Dual Sourcing Analysis:")
print(f"  Additional Cost: ${dual_sourcing_result['additional_cost']:,.2f}")
print(f"  Risk Reduction: ${dual_sourcing_result['risk_reduction']:,.2f}")
print(f"  Net Benefit: ${dual_sourcing_result['net_benefit']:,.2f}")
print(f"  Recommendation: {dual_sourcing_result['recommendation']}")

# Evaluate safety stock
demand_data = {
    'avg_daily_demand': 100,
    'demand_std': 25,
    'unit_cost': 50,
    'stockout_cost_per_event': 10000
}

lead_time_data = {
    'avg_lead_time_days': 30,
    'lead_time_std_days': 7
}

safety_stock_result = resilience_builder.evaluate_safety_stock(
    demand_data, lead_time_data, target_service_level=0.95
)

print(f"\n\nSafety Stock Analysis:")
print(f"  Safety Stock: {safety_stock_result['safety_stock_units']} units ({safety_stock_result['days_of_supply']} days)")
print(f"  Annual Holding Cost: ${safety_stock_result['annual_holding_cost']:,.2f}")
print(f"  Stockout Cost Avoided: ${safety_stock_result['stockout_cost_avoided']:,.2f}")
print(f"  Net Annual Benefit: ${safety_stock_result['net_annual_benefit']:,.2f}")

ツールとライブラリ

Python ライブラリ

リスク分析:

  • pandas:データ操作
  • numpy:数値計算
  • scipy:統計分析と分布
  • scikit-learn:予測型リスクモデリング

シミュレーション:

  • simpy:離散イベントシミュレーション
  • mesa:エージェントベースモデリング
  • pymc3:確率的プログラミング

最適化:

  • pulp:線形計画法
  • pyomo:最適化モデリング
  • scipy.optimize:数値最適化

可視化:

  • matplotlib、seaborn:リスクチャート
  • plotly:インタラクティブなダッシュボード
  • networkx:サプライチェーンネットワーク分析
商用ソフトウェア

リスク管理プラットフォーム:

  • Resilinc:サプライチェーンのリスクインテリジェンス
  • Everstream Analytics:AI を活用したリスク予測
  • Interos:サプライチェーンのレジリエンス
  • Exiger:サードパーティリスク管理
  • Riskpulse:天候および物流のリスク

事業継続:

  • Fusion Framework:リスクおよびレジリエンス管理
  • LogicManager:統合リスク管理
  • Resolver:リスクおよびインシデント管理
  • Quantivate:リスクおよびコンプライアンス

サプライチェーン計画:

  • Kinaxis RapidResponse:シナリオ計画と what-if 分析
  • o9 Solutions:リスク分析を備えたデジタル計画
  • Blue Yonder:サプライチェーンの可視化とリスク
  • SAP IBP:リスクを含む統合事業計画

分析とシミュレーション:

  • LLamasoft (Coupa):サプライチェーンの設計とリスクモデリング
  • Anylogistix:サプライチェーンシミュレーション
  • Arena:離散イベントシミュレーション
  • @RISK:モンテカルロシミュレーションのアドイン

よくある課題と解決策

課題:リスク特定の死角

問題:

  • 未知のリスク、または過小評価されているリスク
  • Tier 1 より先の可視性の不足
  • 新たなリスクを把握できていない

解決策:

  • 部門横断チームによる定期的なリスクワークショップ
  • 外部のリスクインテリジェンスサービス
  • サプライヤー監査と現地訪問
  • 業界ベンチマークと同業他社からの学び
  • 新たな脅威を見越したホライズンスキャニング
  • N 階層のサプライチェーンマッピング
課題:発生確率が低く影響が大きい事象の定量化

問題:

  • 過去のデータが限られている
  • 発生確率の推定が難しい
  • 極端な事象(「ブラックスワン」)

解決策:

  • 確率だけに頼らず、シナリオ計画を活用する
  • ストレステストと感度分析
  • 専門家の判断とデルファイ法
  • 最悪のシナリオを考慮する
  • 壊滅的なリスクに備える保険
  • 計画だけでなく、適応能力を構築する
課題:コストとレジリエンスのバランス

問題:

  • レジリエンスへの投資を正当化しにくい
  • コスト最小化への圧力
  • 効果が不確実で、将来に現れる

解決策:

  • リスク低減による期待価値を定量化する
  • 実際に起きた混乱の事例を活用する
  • バリュー・アット・リスク(VaR)を算出する
  • 財務への影響をストレステストする
  • 発生確率と影響が大きいリスクから着手する
  • 段階的に投資し、効果を実証する
課題:組織のサイロ化

問題:

  • リスク管理の責任が各部門に分散している
  • 連携が不足している
  • 全社的なリスクの把握ができていない

解決策:

  • サプライチェーンリスク委員会を設置する
  • 部門横断のリスクワークショップ
  • リスク台帳とモニタリングの一元化
  • 明確なエスカレーションと意思決定のプロセス
  • 経営幹部向けダッシュボードにリスク KPI を含める
  • リスク管理に対する共通のインセンティブ
課題:安定した状況が続いた後の油断

問題:

  • 好況時にリスク管理の優先度が下がる
  • レジリエンスへの投資が減少する
  • 知識と備えが劣化する

解決策:

  • 定期的なシナリオ計画の演習
  • リスク管理を中核プロセスとして維持する
  • 年次リスク評価を必須にする
  • リーダーシップの関与とトップからの姿勢
  • コンプライアンスおよび監査要件との連携
  • 事業継続計画の定期的なテスト
課題:スピードと徹底性の両立

問題:

  • 混乱への対応には迅速な意思決定が必要
  • 分析に使える時間が限られている
  • 不完全な情報で行動する必要がある

解決策:

  • 事前承認済みの対応プレイブック
  • 明確な意思決定権限とエスカレーション
  • ウォールームのプロトコル
  • リアルタイムデータとダッシュボード
  • 危機における簡素化された意思決定フレームワーク
  • 混乱後の学習と改善

出力形式

リスク評価レポート

エグゼクティブサマリー:

  • 主なリスクと全体的なリスクエクスポージャー
  • バリュー・アット・リスク(VaR)の推定値
  • サプライチェーンのレジリエンススコア
  • 必要な優先対応策

リスク登録簿:

リスク IDリスクの説明カテゴリー発生確率影響リスクスコア現在の管理策優先度
R001単一調達先のサプライヤーの障害調達15%$2.0M高四半期ごとのレビュー1
R002港湾の混雑物流25%$500K中2港湾戦略3
R003需要予測の誤差需要40%$800K高市場調査2
R004サイバー攻撃外部20%$3.0M重大セキュリティ管理策1

シナリオ分析:

シナリオ発生確率売上への影響期間復旧時間予想損失
主要サプライヤーの障害10%$5.0M90日120日$600K
パンデミック5%$15.0M180日365日$900K
自然災害15%$3.0M60日90日$570K
貿易制限20%$8.0M120日180日$2.0M

リスク指標:

指標値目標状況
バリュー・アット・リスク(95%)$8.5M<$5M⚠ 目標超過
年間予想損失$4.2M<$3M⚠ 目標超過
レジリエンス指数62/100>70⚠ 目標未達
軽減済みリスク(年初来)1215⚠ 計画より遅延

軽減計画:

取り組み対応するリスク投資額年間効果スケジュール担当
複数調達先プログラムR001$500K$300K2026年第2四半期調達
安全在庫の増加R001, R002$2.0M$800K2026年第1四半期サプライチェーン
ニアショアリングの評価R002, R005$200K未定2026年第3四半期戦略
サイバーレジリエンスR004$800K$600K2026年第1~第2四半期IT

質問事項

さらに詳しい情報が必要な場合:

  1. 最近、どのような混乱を経験しましたか?
  2. 重要な依存関係は何ですか?(単一調達先のサプライヤー、主要施設など)
  3. 業務で許容できる最大ダウンタイムはどのくらいですか?
  4. サプライチェーンの混乱によって、どれだけの売上がリスクにさらされていますか?
  5. 現在のレジリエンス戦略はどのようなものですか?(在庫バッファー、代替サプライヤーなど)
  6. リスクが地理的に集中している地域はありますか?
  7. ティア1サプライヤーより先のサプライチェーンをどの程度把握できていますか?
  8. どのような事業継続計画が整備されていますか?
  9. リスク軽減のための予算はいくらですか?
  10. どのような保険が適用されますか?

関連スキル

  • supplier-risk-management:サプライヤー固有のリスクの評価と軽減に使用します
  • scenario-planning:戦略的なシナリオ分析に使用します
  • demand-forecasting:需要の不確実性の低減に使用します
  • inventory-optimization:安全在庫とバッファー戦略に使用します
  • network-design:レジリエンスの高いサプライチェーンネットワークの設計に使用します
  • supplier-selection:調達先の選定にリスクを組み込む際に使用します
  • compliance-management:規制およびコンプライアンス上のリスクに使用します
  • contract-management:契約を通じたリスク移転に使用します
  • supplier-collaboration:協働によるリスク管理に使用します

コメント