算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
ds-synthetic-control【设计与创意】"Implements synthetic control methods, difference-in-differences estimation and quasi-experimental designs for impact evaluation"
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: ds-synthetic-control compatibility: opencode completeness: 95 content-types:
Comprehensive guide to synthetic control methods in machine learning and data science workflows.
Synthetic Control Methods is a critical component of the machine learning workflow. This skill covers:
import numpy as np
from scipy.optimize import minimize
from typing import Tuple
def compute_synthetic_weights(
X_donor: np.ndarray,
X_treated: np.ndarray,
regularization: float = 1e-4
) -> np.ndarray:
"""
Compute optimal donor weights for synthetic control using constrained optimization.
Args:
X_donor: (n_donors, n_features) matrix of donor pre-treatment data
X_treated: (n_features,) vector of treated unit pre-treatment data
regularization: L2 penalty to prevent overfitting weights
Returns:
Optimal non-negative weights summing to 1.0
Raises:
ValueError: If input dimensions are incompatible
"""
if X_donor.shape[1] != X_treated.shape[0]:
raise ValueError("Donor features must match treated feature dimensions")
def objective(w: np.ndarray) -> float:
prediction = X_donor @ w
residual = X_treated - prediction
return float(np.sum(residual**2) + regularization * np.sum(w**2))
constraints = (
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1.0}
{'type': 'ineq', 'fun': lambda w: w}
)
n_donors = X_donor.shape[0]
initial_weights = np.ones(n_donors) / n_donors
result = minimize(
objective,
initial_weights,
constraints=constraints,
method='SLSQP'
options={'maxiter': 1000, 'ftol': 1e-9}
)
if not result.success:
raise RuntimeError(f"Weight optimization failed: {result.message}")
return result.x
import logging
import numpy as np
import pandas as pd
from typing import Dict, Any, Optional
from scipy.optimize import minimize
logger = logging.getLogger(__name__)
class SyntheticControlEstimator:
"""Production-grade Synthetic Control Method estimator with DiD support."""
def __init__(self, regularization: float = 1e-4, max_iter: int = 1000) -> None:
self.regularization = regularization
self.max_iter = max_iter
self.weights_: Optional[np.ndarray] = None
self.pre_error_: Optional[float] = None
self.post_error_: Optional[float] = None
def _optimize_weights(self, X_donor: np.ndarray, X_treated: np.ndarray) -> np.ndarray:
"""Find non-negative weights summing to 1 that minimize pre-treatment error."""
def loss(w: np.ndarray) -> float:
pred = X_donor @ w
error = X_treated - pred
return float(np.sum(error**2) + self.regularization * np.sum(w**2))
constraints = (
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1.0}
{'type': 'ineq', 'fun': lambda w: w}
)
n_donors = X_donor.shape[0]
w0 = np.ones(n_donors) / n_donors
res = minimize(
loss, w0, constraints=constraints, method='SLSQP'
options={'maxiter': self.max_iter}
)
if not res.success:
logger.warning(f"Weight optimization did not converge: {res.message}")
return res.x
def fit_predict(
self,
donor_data: pd.DataFrame,
treated_data: pd.DataFrame,
period_col: str = 'period',
treated_unit_id: str = 'treated'
) -> Dict[str, Any]:
"""Fit SCM and predict counterfactual outcomes."""
if donor_data.empty or treated_data.empty:
raise ValueError("Input DataFrames cannot be empty")
donor_pre = donor_data[donor_data[period_col] < 0].drop(columns=[treated_unit_id])
treated_pre = treated_data[treated_data[period_col] < 0].drop(columns=[treated_unit_id])
X_donor = donor_pre.values
X_treated = treated_pre.values.flatten()
self.weights_ = self._optimize_weights(X_donor, X_treated)
self.pre_error_ = float(np.mean((X_treated - X_donor @ self.weights_)**2))
donor_post = donor_data[donor_data[period_col] >= 0].drop(columns=[treated_unit_id])
counterfactual = donor_post.values @ self.weights_
return {
'weights': self.weights_
'pre_mse': self.pre_error_
'counterfactual': counterfactual
'status': 'success'
}
# BAD: Hardcoded values, no validation, violates DRY principle
def bad_scm(data):
w = [0.1, 0.2, 0.3, 0.4] # Magic numbers
return sum(w) * data['y']
# GOOD: Type hints, validation, configurable parameters, follows SOLID/DRY
def good_scm(
donor_matrix: np.ndarray,
target_vector: np.ndarray,
reg_lambda: float = 1e-3
) -> np.ndarray:
if donor_matrix.shape[1] != target_vector.shape[0]:
raise ValueError("Dimension mismatch")
weights = compute_synthetic_weights(donor_matrix, target_vector, reg_lambda)
return weights
| Pitfall | Problem | Solution | |
Authoritative documentation links for this skill's domain. The model follows markdown links at load time to resolve external references and inline content.