Add comprehensive dynamic learning system (4.8)
포괄적 동적 학습 시스템 추가: **4.8.1 Feature Engineering**: - Stage → Continuous/Embedding (categorical split 제거) - Industry → TF-IDF/Word2Vec embedding - 연속 변수 추가: founding_year, total_funding, location **4.8.2 Hyperparameter Learning**: - K_min_tags, IQR_multiplier, burn_in_ratio 자동 최적화 - Cross-validation + MAPE - 데이터 100개마다 재최적화 **4.8.3 Hierarchical Bayesian**: - μ_base + stage_effect + industry_effect - 모든 데이터(442개) 함께 사용 - Stage 간 관계 학습, shrinkage **4.8.4 PostgreSQL 스키마**: - learned_parameters 테이블 - investment_data 테이블 **4.8.5 자동 재학습**: - PostgreSQL Trigger (10개 추가마다) - pg_notify + asyncpg LISTEN - Async 재학습 플로우 **교훈 7.7 추가**: 임의 경계의 문제 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
cb7861cddb
commit
4794e564ad
@ -246,6 +246,229 @@ CREATE TABLE premium_state (
|
||||
- 자동 시장 반영
|
||||
- 투자 뉴스 → 자동 업데이트
|
||||
|
||||
### 4.8 포괄적 동적 학습 시스템
|
||||
|
||||
**현재 문제점**:
|
||||
- Stage, Industry, K=3, IQR multiplier, Burn-in 10% 등 **하드코딩**
|
||||
- 임의 경계: seed/pre-A/series A 구분, 공통 태그 3개
|
||||
- 새 데이터 → 수동 재학습 필요
|
||||
|
||||
**해결: 모든 파라미터를 학습 가능하게**
|
||||
|
||||
#### 4.8.1 Feature Engineering
|
||||
|
||||
**Stage → Continuous/Embedding**:
|
||||
```python
|
||||
# 현재: categorical split (정보 손실)
|
||||
if stage == 'seed':
|
||||
μ = 2.08
|
||||
elif stage == 'series A':
|
||||
μ = 5.0
|
||||
|
||||
# 개선: learnable encoding
|
||||
stage_encoding = {
|
||||
'seed': 0.0,
|
||||
'pre-A': 0.2,
|
||||
'series A': 0.4,
|
||||
'series B': 0.6
|
||||
}
|
||||
# 또는 embedding: stage → R^d
|
||||
stage_embedding = learn_embedding(stage, dim=8)
|
||||
```
|
||||
|
||||
**Industry → Embedding**:
|
||||
```python
|
||||
# 현재: 키워드 매칭 (중복 처리 어려움)
|
||||
keywords = ['협업툴', 'SaaS', '그룹웨어']
|
||||
|
||||
# 개선: 태그 embedding
|
||||
industry_vector = TF-IDF(tags) or Word2Vec(tags)
|
||||
# 차원: R^d (d=16~64)
|
||||
```
|
||||
|
||||
**연속 변수 추가**:
|
||||
```python
|
||||
features = [
|
||||
N, # 직원 수
|
||||
stage_embedding, # Stage (학습됨)
|
||||
industry_embedding, # Industry (학습됨)
|
||||
founding_year, # 설립 연도
|
||||
total_funding, # 총 투자액
|
||||
round_count, # 라운드 수
|
||||
location_encoding # 지역 (서울/지방/글로벌)
|
||||
]
|
||||
```
|
||||
|
||||
#### 4.8.2 Hyperparameter Learning
|
||||
|
||||
**자동 최적화 대상**:
|
||||
```python
|
||||
learnable_params = {
|
||||
'K_min_tags': [2, 3, 4, 5], # 현재 3 고정
|
||||
'IQR_multiplier': [2.0, 2.5, 3.0, 5.0], # 현재 3.0 고정
|
||||
'burn_in_ratio': [0.05, 0.1, 0.15, 0.2], # 현재 0.1 고정
|
||||
'n_iter': [10000, 50000, 100000], # 현재 50000 고정
|
||||
'top_k': [3, 5, 10] # 유사 기업 개수
|
||||
}
|
||||
```
|
||||
|
||||
**최적화 방법**:
|
||||
- Cross-validation: 훈련/검증 분리
|
||||
- Metric: 실제 투자액 vs 예측 MAPE (Mean Absolute Percentage Error)
|
||||
- 자동 재최적화: 데이터 100개 추가마다
|
||||
|
||||
#### 4.8.3 Hierarchical Bayesian Model
|
||||
|
||||
**현재 접근** (데이터 분할):
|
||||
```
|
||||
seed 데이터 115개 → μ_seed = 2.08
|
||||
series A 데이터 87개 → μ_A = 5.0
|
||||
```
|
||||
|
||||
**개선 접근** (Hierarchical):
|
||||
```python
|
||||
# Level 1: Global
|
||||
μ_base ~ N(3.0, 5.0) # 전체 평균
|
||||
|
||||
# Level 2: Stage effect
|
||||
stage_effect['seed'] ~ N(0, 1.0)
|
||||
stage_effect['series A'] ~ N(0, 1.0)
|
||||
|
||||
# Level 3: Industry effect
|
||||
industry_effect[i] ~ N(0, 0.5)
|
||||
|
||||
# Final model
|
||||
value = N × (μ_base + stage_effect[stage] + industry_effect[industry])
|
||||
```
|
||||
|
||||
**장점**:
|
||||
- 모든 데이터 (442개) 함께 사용
|
||||
- Stage 간 관계 학습 (series A는 seed보다 평균적으로 높다)
|
||||
- 데이터 적은 stage도 추정 가능 (shrinkage)
|
||||
|
||||
#### 4.8.4 PostgreSQL 스키마
|
||||
|
||||
```sql
|
||||
-- 학습된 파라미터 저장
|
||||
CREATE TABLE learned_parameters (
|
||||
param_name VARCHAR(50), -- stage_effect, industry_effect, K_min_tags 등
|
||||
param_value FLOAT,
|
||||
category VARCHAR(50), -- seed, series A, 협업툴 등
|
||||
n_samples INT,
|
||||
mape FLOAT, -- 검증 오차
|
||||
updated_at TIMESTAMP,
|
||||
PRIMARY KEY (param_name, category)
|
||||
);
|
||||
|
||||
-- 예시 데이터
|
||||
INSERT INTO learned_parameters VALUES
|
||||
('μ_base', 3.2, NULL, 442, 0.35, NOW()),
|
||||
('stage_effect', -0.45, 'seed', 115, 0.42, NOW()),
|
||||
('stage_effect', 0.28, 'series A', 87, 0.31, NOW()),
|
||||
('industry_effect', 0.15, '협업툴', 95, 0.38, NOW()),
|
||||
('K_min_tags', 3.2, NULL, 442, 0.35, NOW()),
|
||||
('IQR_multiplier', 2.8, NULL, 442, 0.35, NOW());
|
||||
|
||||
-- 투자 데이터 (학습 소스)
|
||||
CREATE TABLE investment_data (
|
||||
company_id VARCHAR,
|
||||
company_name VARCHAR,
|
||||
stage VARCHAR,
|
||||
industry VARCHAR,
|
||||
employees INT,
|
||||
investment_amount FLOAT,
|
||||
founding_year INT,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
#### 4.8.5 자동 재학습 트리거
|
||||
|
||||
**트리거 조건**:
|
||||
```sql
|
||||
CREATE OR REPLACE FUNCTION check_retraining()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
-- 데이터 10개 추가마다
|
||||
IF (SELECT COUNT(*) FROM investment_data) % 10 = 0 THEN
|
||||
PERFORM pg_notify('retrain_model', 'trigger');
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER investment_insert
|
||||
AFTER INSERT ON investment_data
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION check_retraining();
|
||||
```
|
||||
|
||||
**재학습 플로우**:
|
||||
```
|
||||
새 투자 데이터 입력
|
||||
↓
|
||||
PostgreSQL Trigger
|
||||
↓
|
||||
pg_notify('retrain_model')
|
||||
↓
|
||||
Python Listener (asyncpg LISTEN)
|
||||
↓
|
||||
Async Task:
|
||||
1. 데이터 로드 (investment_data)
|
||||
2. Feature engineering
|
||||
3. Hyperparameter optimization (CV)
|
||||
4. Hierarchical Bayesian Update
|
||||
5. learned_parameters UPDATE
|
||||
↓
|
||||
다음 가치평가에 자동 적용
|
||||
```
|
||||
|
||||
#### 4.8.6 동적 평가 예시
|
||||
|
||||
**API 호출**:
|
||||
```python
|
||||
valuation = evaluate_startup(
|
||||
name="NewCo",
|
||||
N=15,
|
||||
stage="pre-A", # 경계 모호해도 OK
|
||||
industry=["AI", "SaaS"],
|
||||
founding_year=2023
|
||||
)
|
||||
```
|
||||
|
||||
**내부 동작**:
|
||||
```python
|
||||
# 1. PostgreSQL에서 최신 파라미터 로드
|
||||
μ_base = get_param('μ_base') # 3.2
|
||||
stage_effect = get_param('stage_effect', 'pre-A') # 0.1
|
||||
industry_embedding = get_embedding(['AI', 'SaaS'])
|
||||
|
||||
# 2. 예측
|
||||
predicted_value_per_emp = (
|
||||
μ_base +
|
||||
stage_effect +
|
||||
np.dot(industry_embedding, learned_weights)
|
||||
)
|
||||
|
||||
# 3. 프리미엄 적용
|
||||
premium = get_param('μ_premium', stage='pre-A', industry='AI')
|
||||
final = N × predicted_value_per_emp × premium
|
||||
|
||||
return {
|
||||
'valuation': final,
|
||||
'base': N × predicted_value_per_emp,
|
||||
'premium': premium,
|
||||
'params_updated_at': last_update_time,
|
||||
'n_samples': total_samples
|
||||
}
|
||||
```
|
||||
|
||||
**장점**:
|
||||
- 하드코딩 0개
|
||||
- 새 stage/industry 자동 지원
|
||||
- 데이터 쌓일수록 정확도 ↑
|
||||
- 파라미터 근거 명확 (n_samples, mape)
|
||||
|
||||
---
|
||||
|
||||
## 5. 시각화
|
||||
@ -374,6 +597,12 @@ Robeing: "동적 학습 결과 {μ_premium:.2f}배입니다.
|
||||
- 투자 뉴스 크롤링 → 자동 프리미엄 업데이트
|
||||
- 교훈: 정적 모델보다 동적 학습이 시장 반영
|
||||
|
||||
### 7.7 임의 경계의 문제
|
||||
|
||||
- Stage/Industry 범주 분할 → 정보 손실
|
||||
- K=3, IQR 3배, Burn-in 10% → 근거 없는 하드코딩
|
||||
- 교훈: Categorical → Feature/Embedding, Hyperparameter → Auto-tuning
|
||||
|
||||
---
|
||||
|
||||
## 8. 참고 자료
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user