1수율 예측 모델
수율(Yield)은 투입 대비 양품 비율로 제조업의 핵심 KPI입니다. 수율 예측 모델은 공정 변수들과 수율 간의 복잡한 비선형 관계를 학습하여 현재 조건에서의 예상 수율을 예측합니다. 이를 통해 수율 저하가 예상되면 사전에 공정 조건을 조정할 수 있습니다.
수율 최적화 폐쇄 루프
공정 파라미터
온도/압력/속도
원자재 품질
순도/입도
환경 조건
온도/습도
수율 예측 모델 (ML)
GradientBoosting + SHAP 설명
예측 수율 < 임계값?
원인 분석 (SHAP)
온도: -0.03 부정적 영향
압력: +0.01 긍정적 영향
순도: -0.02 부정적 영향
최적화 (Differential Evolution)
최적 파라미터 탐색 → 조정
import numpy as np
from dataclasses import dataclass
from typing import List, Dict, Tuple
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.preprocessing import StandardScaler
import shap
@dataclass
class ProcessBatch:
"""공정 배치 데이터"""
batch_id: str
process_params: Dict[str, float] # 온도, 압력, 시간
raw_material: Dict[str, float] # 원자재 품질
environmental: Dict[str, float] # 환경 조건
yield_rate: float # 수율 (0-1)
class YieldPredictor:
"""수율 예측 모델"""
def __init__(self, feature_names: List[str]):
self.feature_names = feature_names
self.model = GradientBoostingRegressor(
n_estimators=200, max_depth=5, learning_rate=0.05
)
self.scaler = StandardScaler()
self.explainer = None
def _to_features(self, batch: ProcessBatch) -> np.ndarray:
"""배치 → 특성 벡터"""
features = []
for name in self.feature_names:
if name in batch.process_params:
features.append(batch.process_params[name])
elif name in batch.raw_material:
features.append(batch.raw_material[name])
elif name in batch.environmental:
features.append(batch.environmental[name])
return np.array(features)
def fit(self, batches: List[ProcessBatch]):
"""학습"""
X = np.array([self._to_features(b) for b in batches])
y = np.array([b.yield_rate for b in batches])
X_scaled = self.scaler.fit_transform(X)
self.model.fit(X_scaled, y)
self.explainer = shap.TreeExplainer(self.model)
def predict(self, batch: ProcessBatch) -> float:
"""수율 예측"""
X = self._to_features(batch).reshape(1, -1)
return self.model.predict(self.scaler.transform(X))[0]
def explain(self, batch: ProcessBatch) -> Dict[str, float]:
"""SHAP 기반 예측 설명"""
X = self._to_features(batch).reshape(1, -1)
X_scaled = self.scaler.transform(X)
shap_values = self.explainer.shap_values(X_scaled)
return dict(zip(self.feature_names, shap_values[0]))2수율 저하 원인 분석
수율이 떨어졌을 때 어떤 공정 변수가 원인인지 파악하는 것이 중요합니다. SHAP 값을 활용하면 각 변수가 수율 예측에 미치는 영향을 정량화할 수 있고, 양품 배치와 불량 배치 간 파라미터 차이를 통계적으로 분석할 수 있습니다.
class YieldRootCauseAnalyzer:
"""수율 저하 원인 분석"""
def __init__(self, predictor: YieldPredictor, baseline: float = 0.95):
self.predictor = predictor
self.baseline = baseline
def analyze_batch(self, batch: ProcessBatch) -> Dict:
"""단일 배치 원인 분석"""
predicted = self.predictor.predict(batch)
contributions = self.predictor.explain(batch)
sorted_factors = sorted(contributions.items(), key=lambda x: x[1])
return {
'predicted_yield': predicted,
'gap': self.baseline - predicted,
'negative_factors': [(k, v) for k, v in sorted_factors if v < 0],
'positive_factors': [(k, v) for k, v in sorted_factors if v > 0]
}
def compare_batches(self, good: List[ProcessBatch],
bad: List[ProcessBatch]) -> Dict:
"""양품 vs 불량 비교"""
diffs = []
for name in self.predictor.feature_names:
good_vals = [self._get_value(b, name) for b in good]
bad_vals = [self._get_value(b, name) for b in bad]
diff = abs(np.mean(good_vals) - np.mean(bad_vals))
pooled_std = np.sqrt((np.std(good_vals)**2 + np.std(bad_vals)**2)/2)
if pooled_std > 0:
effect_size = diff / pooled_std
if effect_size > 0.5: # Cohen's d > 0.5
diffs.append((name, effect_size))
return {'significant_differences': sorted(diffs, key=lambda x: -x[1])}
def _get_value(self, batch: ProcessBatch, name: str) -> float:
for d in [batch.process_params, batch.raw_material, batch.environmental]:
if name in d: return d[name]
return 0.03수율 최적화 실행
수율 예측 모델을 역으로 활용하여 목표 수율을 달성할 수 있는 최적 공정 조건을 탐색합니다. Differential Evolution 같은 최적화 알고리즘으로 예측 모델을 서로게이트로 활용하고, 민감도 분석으로 각 파라미터의 영향력을 평가합니다.
from scipy.optimize import differential_evolution
class YieldOptimizer:
"""수율 최적화"""
def __init__(self, predictor: YieldPredictor,
bounds: Dict[str, Tuple[float, float]],
fixed: Dict[str, float] = None):
self.predictor = predictor
self.bounds = bounds
self.fixed = fixed or {}
self.history = []
def objective(self, params: Dict) -> float:
"""목적 함수: 예측 수율"""
all_params = {**self.fixed, **params}
batch = ProcessBatch(
batch_id='opt',
process_params={k: v for k, v in all_params.items() if 'process_' in k},
raw_material={k: v for k, v in all_params.items() if 'material_' in k},
environmental={k: v for k, v in all_params.items() if 'env_' in k},
yield_rate=0
)
return self.predictor.predict(batch)
def optimize(self, n_iter: int = 50) -> Dict:
"""최적화 실행"""
param_names = list(self.bounds.keys())
bounds_list = [self.bounds[n] for n in param_names]
def neg_obj(x):
params = dict(zip(param_names, x))
return -self.objective(params)
result = differential_evolution(neg_obj, bounds_list, maxiter=n_iter)
return {
'optimal_params': dict(zip(param_names, result.x)),
'optimal_yield': -result.fun
}
def sensitivity(self, base: Dict, pct: float = 0.1) -> Dict:
"""민감도 분석: ±10% 변화 시 수율 변화"""
base_yield = self.objective(base)
sensitivities = {}
for param, value in base.items():
if param not in self.bounds: continue
high = {**base, param: value * (1 + pct)}
low = {**base, param: value * (1 - pct)}
sensitivities[param] = (self.objective(high) - self.objective(low)) / (2 * pct * value)
return sensitivities4실시간 수율 관리 시스템
수율 예측과 최적화를 실시간으로 적용하는 통합 관리 시스템입니다. 배치 시작 전 예측, 저수율 경고, 최적 조건 제안, 배치 완료 후 분석을 자동화합니다.
class RealTimeYieldManagement:
"""실시간 수율 관리"""
def __init__(self, predictor: YieldPredictor,
analyzer: YieldRootCauseAnalyzer,
optimizer: YieldOptimizer,
threshold: float = 0.90):
self.predictor = predictor
self.analyzer = analyzer
self.optimizer = optimizer
self.threshold = threshold
self.alerts = []
def pre_batch_check(self, batch: ProcessBatch) -> Dict:
"""배치 시작 전 검사"""
predicted = self.predictor.predict(batch)
result = {
'predicted_yield': predicted,
'status': 'OK' if predicted >= self.threshold else 'WARNING',
'recommendations': []
}
if predicted < self.threshold:
analysis = self.analyzer.analyze_batch(batch)
for factor, impact in analysis['negative_factors'][:3]:
result['recommendations'].append(
f"{factor} 조정 권고 (영향: {impact:.3f})"
)
self.alerts.append({'batch': batch.batch_id, 'yield': predicted})
return result
def suggest_optimal(self, fixed: Dict) -> Dict:
"""최적 조건 제안"""
self.optimizer.fixed = fixed
result = self.optimizer.optimize()
return {
'params': result['optimal_params'],
'expected_yield': result['optimal_yield'],
'improvement': result['optimal_yield'] - self.threshold
}
def post_batch(self, batch: ProcessBatch) -> Dict:
"""배치 완료 후 분석"""
predicted = self.predictor.predict(batch)
return {
'predicted': predicted,
'actual': batch.yield_rate,
'error': abs(predicted - batch.yield_rate),
'retrain_needed': abs(predicted - batch.yield_rate) > 0.05
}
# 사용 예시
features = ['process_temp', 'process_pressure', 'material_purity', 'env_humidity']
predictor = YieldPredictor(features)
optimizer = YieldOptimizer(predictor, {
'process_temp': (180, 220),
'process_pressure': (2.0, 5.0)
}, fixed={'material_purity': 0.98, 'env_humidity': 45})
result = optimizer.optimize()
print(f"최적 조건: {result['optimal_params']}")
print(f"예상 수율: {result['optimal_yield']:.2%}")성과: 수율 AI로 1-3% 수율 향상 시 연간 수천만 원 이상 비용 절감이 가능합니다.