[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6FK4HKP22S8DHTR91F1RBXT":3,"skill-same:01M6FK4HKP22S8DHTR91F1RBXT":66},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":39,"commitSha":40,"skillDirectory":41,"forksCount":42,"repositoryHtmlUrl":43,"repositoryHomepageUrl":6,"ownerHtmlUrl":44,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":45,"install":46,"resources":59},"01M6FK4HKP22S8DHTR91F1RBXT","risk-assessment-ml",null,"Apply machine learning for construction project risk assessment. Predict schedule delays, cost overruns, and safety incidents using historical data and project characteristics.","kbarbel640-del\u002Fskills","kbarbel640-del","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F255315490?v=4","01M6CJPPQGCCESXMG3K7BBGQ5J","01M6CJPPX2PB2BCZERFVM2C2B3",1,"MIT","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdatadrivenconstruction\u002Frisk-assessment-ml\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"ml","risk assessment","assessment","risk","risk assessment ml","machine learning","data","risk-assessment","Safety","learning","schedule","cost","project","machine","incidents","2026-11-10 10:12:30",false,"---\r\nslug: \"risk-assessment-ml\"\r\ndisplay_name: \"Risk Assessment ML\"\r\ndescription: \"Apply machine learning for construction project risk assessment. Predict schedule delays, cost overruns, and safety incidents using historical data and project characteristics.\"\r\n---\r\n\r\n# Risk Assessment with Machine Learning\r\n\r\n## Overview\r\n\r\nThis skill implements ML-based risk assessment for construction projects. Predict potential risks before they occur and prioritize mitigation strategies based on data-driven insights.\r\n\r\n**Risk Categories:**\r\n- **Schedule Risk**: Delays, critical path impacts\r\n- **Cost Risk**: Budget overruns, change orders\r\n- **Safety Risk**: Incident probability, hazard identification\r\n- **Quality Risk**: Defects, rework probability\r\n\r\n## Quick Start\r\n\r\n```python\r\nimport pandas as pd\r\nimport numpy as np\r\nfrom sklearn.ensemble import RandomForestClassifier, GradientBoostingRegressor\r\nfrom sklearn.model_selection import train_test_split\r\nfrom sklearn.preprocessing import StandardScaler\r\n\r\n# Load historical project data\r\nprojects = pd.read_csv(\"project_history.csv\")\r\n\r\n# Features for risk prediction\r\nfeatures = ['project_size_m2', 'budget_usd', 'duration_days',\r\n            'complexity_score', 'team_size', 'similar_projects_exp']\r\n\r\nX = projects[features]\r\ny_delay = projects['had_delay']  # Binary: 1=delay, 0=on-time\r\n\r\n# Train risk model\r\nX_train, X_test, y_train, y_test = train_test_split(X, y_delay, test_size=0.2)\r\n\r\nmodel = RandomForestClassifier(n_estimators=100, random_state=42)\r\nmodel.fit(X_train, y_train)\r\n\r\n# Predict risk for new project\r\nnew_project = [[5000, 2000000, 365, 3, 50, 5]]\r\nrisk_probability = model.predict_proba(new_project)[0][1]\r\nprint(f\"Delay Risk: {risk_probability:.1%}\")\r\n```\r\n\r\n## Comprehensive Risk Model\r\n\r\n### Risk Assessment Framework\r\n\r\n```python\r\nimport pandas as pd\r\nimport numpy as np\r\nfrom sklearn.ensemble import RandomForestClassifier, GradientBoostingRegressor\r\nfrom sklearn.preprocessing import StandardScaler, LabelEncoder\r\nfrom sklearn.model_selection import cross_val_score\r\nfrom dataclasses import dataclass\r\nfrom typing import Dict, List, Optional\r\nimport joblib\r\n\r\n@dataclass\r\nclass RiskPrediction:\r\n    category: str\r\n    probability: float\r\n    severity: str\r\n    impact_days: Optional[float]\r\n    impact_cost: Optional[float]\r\n    confidence: float\r\n    contributing_factors: List[str]\r\n    recommended_actions: List[str]\r\n\r\nclass ConstructionRiskAssessor:\r\n    \"\"\"ML-based construction risk assessment\"\"\"\r\n\r\n    def __init__(self):\r\n        self.models = {}\r\n        self.scalers = {}\r\n        self.encoders = {}\r\n        self.feature_importance = {}\r\n\r\n    def prepare_features(self, df: pd.DataFrame) -> pd.DataFrame:\r\n        \"\"\"Prepare features for training\u002Fprediction\"\"\"\r\n        features = df.copy()\r\n\r\n        # Encode categorical variables\r\n        categorical_cols = features.select_dtypes(include=['object']).columns\r\n        for col in categorical_cols:\r\n            if col not in self.encoders:\r\n                self.encoders[col] = LabelEncoder()\r\n                features[col] = self.encoders[col].fit_transform(features[col].astype(str))\r\n            else:\r\n                features[col] = self.encoders[col].transform(features[col].astype(str))\r\n\r\n        # Handle missing values\r\n        features = features.fillna(features.median())\r\n\r\n        return features\r\n\r\n    def train_delay_model(self, df: pd.DataFrame, target_col: str = 'delay_days'):\r\n        \"\"\"Train schedule delay prediction model\"\"\"\r\n        features = self.prepare_features(df.drop(columns=[target_col]))\r\n        target = df[target_col]\r\n\r\n        # Binary classification: delay or not\r\n        target_binary = (target > 0).astype(int)\r\n\r\n        # Scale features\r\n        self.scalers['delay'] = StandardScaler()\r\n        X_scaled = self.scalers['delay'].fit_transform(features)\r\n\r\n        # Train model\r\n        self.models['delay_classifier'] = RandomForestClassifier(\r\n            n_estimators=100,\r\n            max_depth=10,\r\n            random_state=42\r\n        )\r\n        self.models['delay_classifier'].fit(X_scaled, target_binary)\r\n\r\n        # Train regression for delay magnitude\r\n        delayed_mask = target > 0\r\n        if delayed_mask.sum() > 10:\r\n            self.models['delay_regressor'] = GradientBoostingRegressor(\r\n                n_estimators=100,\r\n                max_depth=5,\r\n                random_state=42\r\n            )\r\n            self.models['delay_regressor'].fit(\r\n                X_scaled[delayed_mask],\r\n                target[delayed_mask]\r\n            )\r\n\r\n        # Store feature importance\r\n        self.feature_importance['delay'] = dict(zip(\r\n            features.columns,\r\n            self.models['delay_classifier'].feature_importances_\r\n        ))\r\n\r\n        return self._evaluate_model('delay_classifier', X_scaled, target_binary)\r\n\r\n    def train_cost_overrun_model(self, df: pd.DataFrame,\r\n                                  target_col: str = 'cost_overrun_pct'):\r\n        \"\"\"Train cost overrun prediction model\"\"\"\r\n        features = self.prepare_features(df.drop(columns=[target_col]))\r\n        target = df[target_col]\r\n\r\n        # Binary: overrun or not\r\n        target_binary = (target > 0).astype(int)\r\n\r\n        self.scalers['cost'] = StandardScaler()\r\n        X_scaled = self.scalers['cost'].fit_transform(features)\r\n\r\n        self.models['cost_classifier'] = RandomForestClassifier(\r\n            n_estimators=100,\r\n            max_depth=10,\r\n            random_state=42\r\n        )\r\n        self.models['cost_classifier'].fit(X_scaled, target_binary)\r\n\r\n        # Regression for magnitude\r\n        overrun_mask = target > 0\r\n        if overrun_mask.sum() > 10:\r\n            self.models['cost_regressor'] = GradientBoostingRegressor(\r\n                n_estimators=100,\r\n                max_depth=5,\r\n                random_state=42\r\n            )\r\n            self.models['cost_regressor'].fit(\r\n                X_scaled[overrun_mask],\r\n                target[overrun_mask]\r\n            )\r\n\r\n        self.feature_importance['cost'] = dict(zip(\r\n            features.columns,\r\n            self.models['cost_classifier'].feature_importances_\r\n        ))\r\n\r\n        return self._evaluate_model('cost_classifier', X_scaled, target_binary)\r\n\r\n    def train_safety_model(self, df: pd.DataFrame,\r\n                           target_col: str = 'incident_occurred'):\r\n        \"\"\"Train safety incident prediction model\"\"\"\r\n        features = self.prepare_features(df.drop(columns=[target_col]))\r\n        target = df[target_col]\r\n\r\n        self.scalers['safety'] = StandardScaler()\r\n        X_scaled = self.scalers['safety'].fit_transform(features)\r\n\r\n        self.models['safety_classifier'] = RandomForestClassifier(\r\n            n_estimators=100,\r\n            max_depth=8,\r\n            class_weight='balanced',  # Handle imbalanced data\r\n            random_state=42\r\n        )\r\n        self.models['safety_classifier'].fit(X_scaled, target)\r\n\r\n        self.feature_importance['safety'] = dict(zip(\r\n            features.columns,\r\n            self.models['safety_classifier'].feature_importances_\r\n        ))\r\n\r\n        return self._evaluate_model('safety_classifier', X_scaled, target)\r\n\r\n    def _evaluate_model(self, model_name: str, X: np.ndarray, y: np.ndarray) -> Dict:\r\n        \"\"\"Evaluate model with cross-validation\"\"\"\r\n        model = self.models[model_name]\r\n        scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')\r\n\r\n        return {\r\n            'model': model_name,\r\n            'accuracy_mean': scores.mean(),\r\n            'accuracy_std': scores.std()\r\n        }\r\n\r\n    def predict_risks(self, project_data: Dict) -> List[RiskPrediction]:\r\n        \"\"\"Predict all risks for a project\"\"\"\r\n        df = pd.DataFrame([project_data])\r\n        features = self.prepare_features(df)\r\n        predictions = []\r\n\r\n        # Schedule risk\r\n        if 'delay_classifier' in self.models:\r\n            X_delay = self.scalers['delay'].transform(features)\r\n            delay_prob = self.models['delay_classifier'].predict_proba(X_delay)[0][1]\r\n\r\n            delay_days = None\r\n            if delay_prob > 0.5 and 'delay_regressor' in self.models:\r\n                delay_days = self.models['delay_regressor'].predict(X_delay)[0]\r\n\r\n            predictions.append(RiskPrediction(\r\n                category='Schedule',\r\n                probability=delay_prob,\r\n                severity=self._get_severity(delay_prob),\r\n                impact_days=delay_days,\r\n                impact_cost=delay_days * project_data.get('daily_cost', 10000) if delay_days else None,\r\n                confidence=0.85,\r\n                contributing_factors=self._get_top_factors('delay', features.iloc[0]),\r\n                recommended_actions=self._get_delay_actions(delay_prob)\r\n            ))\r\n\r\n        # Cost risk\r\n        if 'cost_classifier' in self.models:\r\n            X_cost = self.scalers['cost'].transform(features)\r\n            cost_prob = self.models['cost_classifier'].predict_proba(X_cost)[0][1]\r\n\r\n            overrun_pct = None\r\n            if cost_prob > 0.5 and 'cost_regressor' in self.models:\r\n                overrun_pct = self.models['cost_regressor'].predict(X_cost)[0]\r\n\r\n            predictions.append(RiskPrediction(\r\n                category='Cost',\r\n                probability=cost_prob,\r\n                severity=self._get_severity(cost_prob),\r\n                impact_days=None,\r\n                impact_cost=project_data.get('budget', 0) * overrun_pct \u002F 100 if overrun_pct else None,\r\n                confidence=0.80,\r\n                contributing_factors=self._get_top_factors('cost', features.iloc[0]),\r\n                recommended_actions=self._get_cost_actions(cost_prob)\r\n            ))\r\n\r\n        # Safety risk\r\n        if 'safety_classifier' in self.models:\r\n            X_safety = self.scalers['safety'].transform(features)\r\n            safety_prob = self.models['safety_classifier'].predict_proba(X_safety)[0][1]\r\n\r\n            predictions.append(RiskPrediction(\r\n                category='Safety',\r\n                probability=safety_prob,\r\n                severity=self._get_severity(safety_prob),\r\n                impact_days=None,\r\n                impact_cost=None,\r\n                confidence=0.75,\r\n                contributing_factors=self._get_top_factors('safety', features.iloc[0]),\r\n                recommended_actions=self._get_safety_actions(safety_prob)\r\n            ))\r\n\r\n        return predictions\r\n\r\n    def _get_severity(self, probability: float) -> str:\r\n        if probability >= 0.7:\r\n            return 'High'\r\n        elif probability >= 0.4:\r\n            return 'Medium'\r\n        else:\r\n            return 'Low'\r\n\r\n    def _get_top_factors(self, risk_type: str, project_features: pd.Series) -> List[str]:\r\n        \"\"\"Get top contributing factors for risk\"\"\"\r\n        importance = self.feature_importance.get(risk_type, {})\r\n        sorted_factors = sorted(importance.items(), key=lambda x: x[1], reverse=True)\r\n        return [f[0] for f in sorted_factors[:5]]\r\n\r\n    def _get_delay_actions(self, probability: float) -> List[str]:\r\n        actions = []\r\n        if probability > 0.7:\r\n            actions.extend([\r\n                'Add buffer to critical path activities',\r\n                'Increase resource allocation',\r\n                'Implement daily progress monitoring'\r\n            ])\r\n        elif probability > 0.4:\r\n            actions.extend([\r\n                'Review schedule with contractors',\r\n                'Identify potential fast-track opportunities'\r\n            ])\r\n        else:\r\n            actions.append('Standard schedule monitoring')\r\n        return actions\r\n\r\n    def _get_cost_actions(self, probability: float) -> List[str]:\r\n        actions = []\r\n        if probability > 0.7:\r\n            actions.extend([\r\n                'Increase contingency reserve',\r\n                'Lock in material prices',\r\n                'Review scope with stakeholders'\r\n            ])\r\n        elif probability > 0.4:\r\n            actions.extend([\r\n                'Monitor change order frequency',\r\n                'Implement value engineering review'\r\n            ])\r\n        else:\r\n            actions.append('Standard cost tracking')\r\n        return actions\r\n\r\n    def _get_safety_actions(self, probability: float) -> List[str]:\r\n        actions = []\r\n        if probability > 0.7:\r\n            actions.extend([\r\n                'Conduct safety stand-down',\r\n                'Increase safety personnel',\r\n                'Review high-risk activities'\r\n            ])\r\n        elif probability > 0.4:\r\n            actions.extend([\r\n                'Increase safety inspections',\r\n                'Refresh safety training'\r\n            ])\r\n        else:\r\n            actions.append('Maintain standard safety protocols')\r\n        return actions\r\n\r\n    def save_models(self, path: str):\r\n        \"\"\"Save trained models\"\"\"\r\n        joblib.dump({\r\n            'models': self.models,\r\n            'scalers': self.scalers,\r\n            'encoders': self.encoders,\r\n            'feature_importance': self.feature_importance\r\n        }, path)\r\n\r\n    def load_models(self, path: str):\r\n        \"\"\"Load trained models\"\"\"\r\n        data = joblib.load(path)\r\n        self.models = data['models']\r\n        self.scalers = data['scalers']\r\n        self.encoders = data['encoders']\r\n        self.feature_importance = data['feature_importance']\r\n```\r\n\r\n## Feature Engineering\r\n\r\n### Project Risk Features\r\n\r\n```python\r\ndef engineer_risk_features(project_data: pd.DataFrame) -> pd.DataFrame:\r\n    \"\"\"Create features for risk prediction\"\"\"\r\n    df = project_data.copy()\r\n\r\n    # Size and complexity metrics\r\n    df['cost_per_sqm'] = df['budget'] \u002F df['area_sqm']\r\n    df['duration_per_sqm'] = df['duration_days'] \u002F df['area_sqm']\r\n\r\n    # Team metrics\r\n    df['workers_per_1000sqm'] = df['peak_workers'] \u002F (df['area_sqm'] \u002F 1000)\r\n\r\n    # Weather exposure\r\n    df['outdoor_work_pct'] = df['outdoor_activities'] \u002F df['total_activities']\r\n\r\n    # Contract complexity\r\n    df['subcontractor_ratio'] = df['num_subcontractors'] \u002F df['total_contractors']\r\n\r\n    # Experience factors\r\n    df['team_avg_experience'] = df['total_team_years'] \u002F df['team_size']\r\n\r\n    # Season risk\r\n    df['winter_months'] = df.apply(\r\n        lambda r: count_winter_months(r['start_date'], r['end_date']), axis=1\r\n    )\r\n\r\n    # Location risk\r\n    df['urban_complexity'] = df['location_type'].map({\r\n        'rural': 1, 'suburban': 2, 'urban': 3, 'downtown': 4\r\n    })\r\n\r\n    return df\r\n\r\ndef count_winter_months(start_date, end_date):\r\n    \"\"\"Count winter months in project duration\"\"\"\r\n    winter_months = [11, 12, 1, 2, 3]\r\n    months = pd.date_range(start_date, end_date, freq='M')\r\n    return sum(1 for m in months if m.month in winter_months)\r\n```\r\n\r\n## Risk Report Generation\r\n\r\n```python\r\ndef generate_risk_report(assessor: ConstructionRiskAssessor,\r\n                        project_data: Dict,\r\n                        output_path: str):\r\n    \"\"\"Generate comprehensive risk assessment report\"\"\"\r\n    predictions = assessor.predict_risks(project_data)\r\n\r\n    with pd.ExcelWriter(output_path, engine='openpyxl') as writer:\r\n        # Summary\r\n        summary = pd.DataFrame([{\r\n            'Category': p.category,\r\n            'Risk Level': p.severity,\r\n            'Probability': f\"{p.probability:.1%}\",\r\n            'Impact Days': p.impact_days,\r\n            'Impact Cost': p.impact_cost,\r\n            'Top Factor': p.contributing_factors[0] if p.contributing_factors else ''\r\n        } for p in predictions])\r\n        summary.to_excel(writer, sheet_name='Summary', index=False)\r\n\r\n        # Detailed recommendations\r\n        actions = []\r\n        for p in predictions:\r\n            for action in p.recommended_actions:\r\n                actions.append({\r\n                    'Category': p.category,\r\n                    'Risk Level': p.severity,\r\n                    'Recommended Action': action\r\n                })\r\n        pd.DataFrame(actions).to_excel(writer, sheet_name='Actions', index=False)\r\n\r\n    return output_path\r\n```\r\n\r\n## Quick Reference\r\n\r\n| Risk Type | Key Features | Model Type |\r\n|-----------|--------------|------------|\r\n| Schedule | Duration, complexity, weather | Random Forest |\r\n| Cost | Budget, scope changes, market | Gradient Boosting |\r\n| Safety | Work type, team experience | Random Forest |\r\n| Quality | Supervision, materials | Logistic Regression |\r\n\r\n## Resources\r\n\r\n- **Scikit-learn**: https:\u002F\u002Fscikit-learn.org\r\n- **DDC Website**: https:\u002F\u002Fdatadrivenconstruction.io\r\n\r\n## Next Steps\r\n\r\n- See `cost-prediction` for detailed cost modeling\r\n- See `4d-simulation` for schedule analysis\r\n- See `data-visualization` for risk dashboards\r\n","# Risk Assessment with Machine Learning\r\n\r\n## Overview\r\n\r\nThis skill implements ML-based risk assessment for construction projects. Predict potential risks before they occur and prioritize mitigation strategies based on data-driven insights.\r\n\r\n**Risk Categories:**\r\n- **Schedule Risk**: Delays, critical path impacts\r\n- **Cost Risk**: Budget overruns, change orders\r\n- **Safety Risk**: Incident probability, hazard identification\r\n- **Quality Risk**: Defects, rework probability\r\n\r\n## Quick Start\r\n\r\n```python\r\nimport pandas as pd\r\nimport numpy as np\r\nfrom sklearn.ensemble import RandomForestClassifier, GradientBoostingRegressor\r\nfrom sklearn.model_selection import train_test_split\r\nfrom sklearn.preprocessing import StandardScaler\r\n\r\n# Load historical project data\r\nprojects = pd.read_csv(\"project_history.csv\")\r\n\r\n# Features for risk prediction\r\nfeatures = ['project_size_m2', 'budget_usd', 'duration_days',\r\n            'complexity_score', 'team_size', 'similar_projects_exp']\r\n\r\nX = projects[features]\r\ny_delay = projects['had_delay']  # Binary: 1=delay, 0=on-time\r\n\r\n# Train risk model\r\nX_train, X_test, y_train, y_test = train_test_split(X, y_delay, test_size=0.2)\r\n\r\nmodel = RandomForestClassifier(n_estimators=100, random_state=42)\r\nmodel.fit(X_train, y_train)\r\n\r\n# Predict risk for new project\r\nnew_project = [[5000, 2000000, 365, 3, 50, 5]]\r\nrisk_probability = model.predict_proba(new_project)[0][1]\r\nprint(f\"Delay Risk: {risk_probability:.1%}\")\r\n```\r\n\r\n## Comprehensive Risk Model\r\n\r\n### Risk Assessment Framework\r\n\r\n```python\r\nimport pandas as pd\r\nimport numpy as np\r\nfrom sklearn.ensemble import RandomForestClassifier, GradientBoostingRegressor\r\nfrom sklearn.preprocessing import StandardScaler, LabelEncoder\r\nfrom sklearn.model_selection import cross_val_score\r\nfrom dataclasses import dataclass\r\nfrom typing import Dict, List, Optional\r\nimport joblib\r\n\r\n@dataclass\r\nclass RiskPrediction:\r\n    category: str\r\n    probability: float\r\n    severity: str\r\n    impact_days: Optional[float]\r\n    impact_cost: Optional[float]\r\n    confidence: float\r\n    contributing_factors: List[str]\r\n    recommended_actions: List[str]\r\n\r\nclass ConstructionRiskAssessor:\r\n    \"\"\"ML-based construction risk assessment\"\"\"\r\n\r\n    def __init__(self):\r\n        self.models = {}\r\n        self.scalers = {}\r\n        self.encoders = {}\r\n        self.feature_importance = {}\r\n\r\n    def prepare_features(self, df: pd.DataFrame) -> pd.DataFrame:\r\n        \"\"\"Prepare features for training\u002Fprediction\"\"\"\r\n        features = df.copy()\r\n\r\n        # Encode categorical variables\r\n        categorical_cols = features.select_dtypes(include=['object']).columns\r\n        for col in categorical_cols:\r\n            if col not in self.encoders:\r\n                self.encoders[col] = LabelEncoder()\r\n                features[col] = self.encoders[col].fit_transform(features[col].astype(str))\r\n            else:\r\n                features[col] = self.encoders[col].transform(features[col].astype(str))\r\n\r\n        # Handle missing values\r\n        features = features.fillna(features.median())\r\n\r\n        return features\r\n\r\n    def train_delay_model(self, df: pd.DataFrame, target_col: str = 'delay_days'):\r\n        \"\"\"Train schedule delay prediction model\"\"\"\r\n        features = self.prepare_features(df.drop(columns=[target_col]))\r\n        target = df[target_col]\r\n\r\n        # Binary classification: delay or not\r\n        target_binary = (target > 0).astype(int)\r\n\r\n        # Scale features\r\n        self.scalers['delay'] = StandardScaler()\r\n        X_scaled = self.scalers['delay'].fit_transform(features)\r\n\r\n        # Train model\r\n        self.models['delay_classifier'] = RandomForestClassifier(\r\n            n_estimators=100,\r\n            max_depth=10,\r\n            random_state=42\r\n        )\r\n        self.models['delay_classifier'].fit(X_scaled, target_binary)\r\n\r\n        # Train regression for delay magnitude\r\n        delayed_mask = target > 0\r\n        if delayed_mask.sum() > 10:\r\n            self.models['delay_regressor'] = GradientBoostingRegressor(\r\n                n_estimators=100,\r\n                max_depth=5,\r\n                random_state=42\r\n            )\r\n            self.models['delay_regressor'].fit(\r\n                X_scaled[delayed_mask],\r\n                target[delayed_mask]\r\n            )\r\n\r\n        # Store feature importance\r\n        self.feature_importance['delay'] = dict(zip(\r\n            features.columns,\r\n            self.models['delay_classifier'].feature_importances_\r\n        ))\r\n\r\n        return self._evaluate_model('delay_classifier', X_scaled, target_binary)\r\n\r\n    def train_cost_overrun_model(self, df: pd.DataFrame,\r\n                                  target_col: str = 'cost_overrun_pct'):\r\n        \"\"\"Train cost overrun prediction model\"\"\"\r\n        features = self.prepare_features(df.drop(columns=[target_col]))\r\n        target = df[target_col]\r\n\r\n        # Binary: overrun or not\r\n        target_binary = (target > 0).astype(int)\r\n\r\n        self.scalers['cost'] = StandardScaler()\r\n        X_scaled = self.scalers['cost'].fit_transform(features)\r\n\r\n        self.models['cost_classifier'] = RandomForestClassifier(\r\n            n_estimators=100,\r\n            max_depth=10,\r\n            random_state=42\r\n        )\r\n        self.models['cost_classifier'].fit(X_scaled, target_binary)\r\n\r\n        # Regression for magnitude\r\n        overrun_mask = target > 0\r\n        if overrun_mask.sum() > 10:\r\n            self.models['cost_regressor'] = GradientBoostingRegressor(\r\n                n_estimators=100,\r\n                max_depth=5,\r\n                random_state=42\r\n            )\r\n            self.models['cost_regressor'].fit(\r\n                X_scaled[overrun_mask],\r\n                target[overrun_mask]\r\n            )\r\n\r\n        self.feature_importance['cost'] = dict(zip(\r\n            features.columns,\r\n            self.models['cost_classifier'].feature_importances_\r\n        ))\r\n\r\n        return self._evaluate_model('cost_classifier', X_scaled, target_binary)\r\n\r\n    def train_safety_model(self, df: pd.DataFrame,\r\n                           target_col: str = 'incident_occurred'):\r\n        \"\"\"Train safety incident prediction model\"\"\"\r\n        features = self.prepare_features(df.drop(columns=[target_col]))\r\n        target = df[target_col]\r\n\r\n        self.scalers['safety'] = StandardScaler()\r\n        X_scaled = self.scalers['safety'].fit_transform(features)\r\n\r\n        self.models['safety_classifier'] = RandomForestClassifier(\r\n            n_estimators=100,\r\n            max_depth=8,\r\n            class_weight='balanced',  # Handle imbalanced data\r\n            random_state=42\r\n        )\r\n        self.models['safety_classifier'].fit(X_scaled, target)\r\n\r\n        self.feature_importance['safety'] = dict(zip(\r\n            features.columns,\r\n            self.models['safety_classifier'].feature_importances_\r\n        ))\r\n\r\n        return self._evaluate_model('safety_classifier', X_scaled, target)\r\n\r\n    def _evaluate_model(self, model_name: str, X: np.ndarray, y: np.ndarray) -> Dict:\r\n        \"\"\"Evaluate model with cross-validation\"\"\"\r\n        model = self.models[model_name]\r\n        scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')\r\n\r\n        return {\r\n            'model': model_name,\r\n            'accuracy_mean': scores.mean(),\r\n            'accuracy_std': scores.std()\r\n        }\r\n\r\n    def predict_risks(self, project_data: Dict) -> List[RiskPrediction]:\r\n        \"\"\"Predict all risks for a project\"\"\"\r\n        df = pd.DataFrame([project_data])\r\n        features = self.prepare_features(df)\r\n        predictions = []\r\n\r\n        # Schedule risk\r\n        if 'delay_classifier' in self.models:\r\n            X_delay = self.scalers['delay'].transform(features)\r\n            delay_prob = self.models['delay_classifier'].predict_proba(X_delay)[0][1]\r\n\r\n            delay_days = None\r\n            if delay_prob > 0.5 and 'delay_regressor' in self.models:\r\n                delay_days = self.models['delay_regressor'].predict(X_delay)[0]\r\n\r\n            predictions.append(RiskPrediction(\r\n                category='Schedule',\r\n                probability=delay_prob,\r\n                severity=self._get_severity(delay_prob),\r\n                impact_days=delay_days,\r\n                impact_cost=delay_days * project_data.get('daily_cost', 10000) if delay_days else None,\r\n                confidence=0.85,\r\n                contributing_factors=self._get_top_factors('delay', features.iloc[0]),\r\n                recommended_actions=self._get_delay_actions(delay_prob)\r\n            ))\r\n\r\n        # Cost risk\r\n        if 'cost_classifier' in self.models:\r\n            X_cost = self.scalers['cost'].transform(features)\r\n            cost_prob = self.models['cost_classifier'].predict_proba(X_cost)[0][1]\r\n\r\n            overrun_pct = None\r\n            if cost_prob > 0.5 and 'cost_regressor' in self.models:\r\n                overrun_pct = self.models['cost_regressor'].predict(X_cost)[0]\r\n\r\n            predictions.append(RiskPrediction(\r\n                category='Cost',\r\n                probability=cost_prob,\r\n                severity=self._get_severity(cost_prob),\r\n                impact_days=None,\r\n                impact_cost=project_data.get('budget', 0) * overrun_pct \u002F 100 if overrun_pct else None,\r\n                confidence=0.80,\r\n                contributing_factors=self._get_top_factors('cost', features.iloc[0]),\r\n                recommended_actions=self._get_cost_actions(cost_prob)\r\n            ))\r\n\r\n        # Safety risk\r\n        if 'safety_classifier' in self.models:\r\n            X_safety = self.scalers['safety'].transform(features)\r\n            safety_prob = self.models['safety_classifier'].predict_proba(X_safety)[0][1]\r\n\r\n            predictions.append(RiskPrediction(\r\n                category='Safety',\r\n                probability=safety_prob,\r\n                severity=self._get_severity(safety_prob),\r\n                impact_days=None,\r\n                impact_cost=None,\r\n                confidence=0.75,\r\n                contributing_factors=self._get_top_factors('safety', features.iloc[0]),\r\n                recommended_actions=self._get_safety_actions(safety_prob)\r\n            ))\r\n\r\n        return predictions\r\n\r\n    def _get_severity(self, probability: float) -> str:\r\n        if probability >= 0.7:\r\n            return 'High'\r\n        elif probability >= 0.4:\r\n            return 'Medium'\r\n        else:\r\n            return 'Low'\r\n\r\n    def _get_top_factors(self, risk_type: str, project_features: pd.Series) -> List[str]:\r\n        \"\"\"Get top contributing factors for risk\"\"\"\r\n        importance = self.feature_importance.get(risk_type, {})\r\n        sorted_factors = sorted(importance.items(), key=lambda x: x[1], reverse=True)\r\n        return [f[0] for f in sorted_factors[:5]]\r\n\r\n    def _get_delay_actions(self, probability: float) -> List[str]:\r\n        actions = []\r\n        if probability > 0.7:\r\n            actions.extend([\r\n                'Add buffer to critical path activities',\r\n                'Increase resource allocation',\r\n                'Implement daily progress monitoring'\r\n            ])\r\n        elif probability > 0.4:\r\n            actions.extend([\r\n                'Review schedule with contractors',\r\n                'Identify potential fast-track opportunities'\r\n            ])\r\n        else:\r\n            actions.append('Standard schedule monitoring')\r\n        return actions\r\n\r\n    def _get_cost_actions(self, probability: float) -> List[str]:\r\n        actions = []\r\n        if probability > 0.7:\r\n            actions.extend([\r\n                'Increase contingency reserve',\r\n                'Lock in material prices',\r\n                'Review scope with stakeholders'\r\n            ])\r\n        elif probability > 0.4:\r\n            actions.extend([\r\n                'Monitor change order frequency',\r\n                'Implement value engineering review'\r\n            ])\r\n        else:\r\n            actions.append('Standard cost tracking')\r\n        return actions\r\n\r\n    def _get_safety_actions(self, probability: float) -> List[str]:\r\n        actions = []\r\n        if probability > 0.7:\r\n            actions.extend([\r\n                'Conduct safety stand-down',\r\n                'Increase safety personnel',\r\n                'Review high-risk activities'\r\n            ])\r\n        elif probability > 0.4:\r\n            actions.extend([\r\n                'Increase safety inspections',\r\n                'Refresh safety training'\r\n            ])\r\n        else:\r\n            actions.append('Maintain standard safety protocols')\r\n        return actions\r\n\r\n    def save_models(self, path: str):\r\n        \"\"\"Save trained models\"\"\"\r\n        joblib.dump({\r\n            'models': self.models,\r\n            'scalers': self.scalers,\r\n            'encoders': self.encoders,\r\n            'feature_importance': self.feature_importance\r\n        }, path)\r\n\r\n    def load_models(self, path: str):\r\n        \"\"\"Load trained models\"\"\"\r\n        data = joblib.load(path)\r\n        self.models = data['models']\r\n        self.scalers = data['scalers']\r\n        self.encoders = data['encoders']\r\n        self.feature_importance = data['feature_importance']\r\n```\r\n\r\n## Feature Engineering\r\n\r\n### Project Risk Features\r\n\r\n```python\r\ndef engineer_risk_features(project_data: pd.DataFrame) -> pd.DataFrame:\r\n    \"\"\"Create features for risk prediction\"\"\"\r\n    df = project_data.copy()\r\n\r\n    # Size and complexity metrics\r\n    df['cost_per_sqm'] = df['budget'] \u002F df['area_sqm']\r\n    df['duration_per_sqm'] = df['duration_days'] \u002F df['area_sqm']\r\n\r\n    # Team metrics\r\n    df['workers_per_1000sqm'] = df['peak_workers'] \u002F (df['area_sqm'] \u002F 1000)\r\n\r\n    # Weather exposure\r\n    df['outdoor_work_pct'] = df['outdoor_activities'] \u002F df['total_activities']\r\n\r\n    # Contract complexity\r\n    df['subcontractor_ratio'] = df['num_subcontractors'] \u002F df['total_contractors']\r\n\r\n    # Experience factors\r\n    df['team_avg_experience'] = df['total_team_years'] \u002F df['team_size']\r\n\r\n    # Season risk\r\n    df['winter_months'] = df.apply(\r\n        lambda r: count_winter_months(r['start_date'], r['end_date']), axis=1\r\n    )\r\n\r\n    # Location risk\r\n    df['urban_complexity'] = df['location_type'].map({\r\n        'rural': 1, 'suburban': 2, 'urban': 3, 'downtown': 4\r\n    })\r\n\r\n    return df\r\n\r\ndef count_winter_months(start_date, end_date):\r\n    \"\"\"Count winter months in project duration\"\"\"\r\n    winter_months = [11, 12, 1, 2, 3]\r\n    months = pd.date_range(start_date, end_date, freq='M')\r\n    return sum(1 for m in months if m.month in winter_months)\r\n```\r\n\r\n## Risk Report Generation\r\n\r\n```python\r\ndef generate_risk_report(assessor: ConstructionRiskAssessor,\r\n                        project_data: Dict,\r\n                        output_path: str):\r\n    \"\"\"Generate comprehensive risk assessment report\"\"\"\r\n    predictions = assessor.predict_risks(project_data)\r\n\r\n    with pd.ExcelWriter(output_path, engine='openpyxl') as writer:\r\n        # Summary\r\n        summary = pd.DataFrame([{\r\n            'Category': p.category,\r\n            'Risk Level': p.severity,\r\n            'Probability': f\"{p.probability:.1%}\",\r\n            'Impact Days': p.impact_days,\r\n            'Impact Cost': p.impact_cost,\r\n            'Top Factor': p.contributing_factors[0] if p.contributing_factors else ''\r\n        } for p in predictions])\r\n        summary.to_excel(writer, sheet_name='Summary', index=False)\r\n\r\n        # Detailed recommendations\r\n        actions = []\r\n        for p in predictions:\r\n            for action in p.recommended_actions:\r\n                actions.append({\r\n                    'Category': p.category,\r\n                    'Risk Level': p.severity,\r\n                    'Recommended Action': action\r\n                })\r\n        pd.DataFrame(actions).to_excel(writer, sheet_name='Actions', index=False)\r\n\r\n    return output_path\r\n```\r\n\r\n## Quick Reference\r\n\r\n| Risk Type | Key Features | Model Type |\r\n|-----------|--------------|------------|\r\n| Schedule | Duration, complexity, weather | Random Forest |\r\n| Cost | Budget, scope changes, market | Gradient Boosting |\r\n| Safety | Work type, team experience | Random Forest |\r\n| Quality | Supervision, materials | Logistic Regression |\r\n\r\n## Resources\r\n\r\n- **Scikit-learn**: https:\u002F\u002Fscikit-learn.org\r\n- **DDC Website**: https:\u002F\u002Fdatadrivenconstruction.io\r\n\r\n## Next Steps\r\n\r\n- See `cost-prediction` for detailed cost modeling\r\n- See `4d-simulation` for schedule analysis\r\n- See `data-visualization` for risk dashboards\r\n",{"slug":5,"description":7,"display_name":38},"Risk Assessment ML","main","e7e336ac628c3e3bd771aff1aaa469c93778f94a","skills\u002Fdatadrivenconstruction\u002Frisk-assessment-ml",0,"https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del","2026-08-23 22:39:37",{"source":8,"skillName":5,"commands":47,"prompt":57,"zipAvailable":58},[48,51,54],{"tool":49,"command":50},"npx","npx skills add kbarbel640-del\u002Fskills --skill risk-assessment-ml",{"tool":52,"command":53},"bunx","bunx skills add kbarbel640-del\u002Fskills --skill risk-assessment-ml",{"tool":55,"command":56},"pnpm","pnpm dlx skills add kbarbel640-del\u002Fskills --skill risk-assessment-ml","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdatadrivenconstruction\u002Frisk-assessment-ml\u002FSKILL.md",true,[60],{"path":61,"resourceType":62,"resourceTypeDesc":63,"sizeBytes":64,"sourceHtmlUrl":65},"_meta.json","REFERENCE","参考文档",304,"https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdatadrivenconstruction\u002Frisk-assessment-ml\u002F_meta.json",[67,98,127,148,154,174],{"skillNo":68,"name":69,"nameZh":6,"description":70,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":78,"publishedAt":33},"01M6G8J55967D6281ACMKAKTEQ","crowd-prompting","A marketplace where AI agents improve prompts, system instructions, tool descriptions, and other text-based content with domain expertise from real-world operations — and earn tokens for valuable contributions.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzzadrian\u002Fcrowd-prompting\u002FSKILL.md",[73],{"categoryNo":74,"categoryName":75,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],"crowd prompting","prompting","api","with","tokens","domain","world","prompts","operations","instructions","text","tool","system","improve","productivity","marketplace","https","content","ai agents",{"skillNo":99,"name":100,"nameZh":6,"description":101,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":109,"publishedAt":33},"01M6G8J0PKPAYVET6BWE8W4C26","dilemm-ai","Compete in DilemmAI, the prisoner's dilemma AI arena at dilemm.ai. Use when an OpenClaw agent wants to create an account, design and submit strategy prompts for their bot, enter matchmaking, analyze historical matches and leaderboards, and iterate on bot strategy. Requires headless browser automation (no API available yet).","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzyori\u002Fdilemm-ai\u002FSKILL.md",[104],{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[110,81,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,86,126],"dilemm ai","arena","analyze","browser","openclaw agent","create","automation","browser automation","bot","openclaw","design","strategy","headless","compete","submit","matchmaking","use",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":136,"publishedAt":33},"01M6G8HWAF3K9SW7NP3Z83CPJ6","arxiv-paper-reviews","Interact with arXiv Crawler API to fetch papers, read reviews, and submit comments. Use when working with arXiv papers, fetching paper lists by date\u002Fcategory\u002Finterest, viewing paper details with comments, or submitting paper reviews via API at http:\u002F\u002F150.158.152.82:8000.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzxrys\u002Fweak-accept\u002FSKILL.md",[133],{"categoryNo":134,"categoryName":135,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000021","资料检索与研究",[137,138,139,140,141,142,143,82,144,124,126,145,81,146,147],"arxiv paper reviews","reviews","arxiv","paper","crawler","papers","comments","fetch","read","http","via",{"skillNo":149,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":153,"publishedAt":33},"01M6G8HQJ7N7WMY6YV7D7SSJ16","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzxrys\u002Farxiv-paper-reviews\u002FSKILL.md",[152],{"categoryNo":134,"categoryName":135,"taxonomyType":107,"taxonomyTypeDesc":108},[140,139,138,137,147,142,143,82,141,124,126,144,145,81,146],{"skillNo":155,"name":156,"nameZh":6,"description":157,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":158,"categories":159,"keywords":160,"publishedAt":33},"01M6G8HM95Y64JNVFC2HN4E2BG","git-summary","Get a quick summary of the current Git repository including status, recent commits, branches, and contributors.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzweack\u002Fgit-summary\u002FSKILL.md",[],[161,162,163,164,165,166,167,168,169,170,171,172,173],"git","summary","git summary","commits","repository","win32","status","linux","contributors","true","quick","get","branches",{"skillNo":175,"name":176,"nameZh":6,"description":177,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":178,"categories":179,"keywords":184,"publishedAt":33},"01M6G8HGEGF05CNEJCGVYFSC4R","agent-constitution","Interact with AgentConstitution governance contracts on Base Sepolia. Check compliance, read rules, log actions, query governance state.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fztsalexey\u002Fagent-constitution\u002FSKILL.md",[180,181],{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},{"categoryNo":182,"categoryName":183,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000037","律师与法务",[185,186,187,188,82,189,190,39,191,145,192,193,194,195,196,95,197,198,199],"agent constitution","constitution","contracts","tree","query","base","log","check","Rules","projects","compliance","actions","state","governance","github"]