DOCS/plans/251016_bayesian_startup_valuation.md
Claude-51124 4794e564ad 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>
2025-10-17 00:39:31 +09:00

633 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 베이지안 스타트업 가치평가 프레임워크
**날짜**: 2025-10-16
**작성자**: Claude Code
**관련 파일**:
- `/tmp/find_similar_neo4j.py`
- `/tmp/valuation_bayesian_mcmc.py`
- `/tmp/bayesian_premium_updater.py`
---
## 1. 개요
Neo4j 그래프 분석과 베이지안 MCMC를 결합한 스타트업 가치평가 프레임워크. 동적 프리미엄 학습으로 하드코딩 제거 및 시장 변화 자동 반영.
**데이터 소스**:
- K-Startup 스타트업 데이터 12,703개
- 경로: `/mnt/51123data/DATA/startup/data/startup_data_20251016.json`
**프레임워크 구성**:
1. Neo4j 그래프 기반 유사 기업 탐색
2. Bayesian MCMC 확률적 가치평가
3. 동적 프리미엄 온라인 학습 (PostgreSQL)
---
## 2. 입력 변수 및 사례
**입력 변수**:
```
기업: {company_name}
산업: {industry_tags} # 예: 협업툴, SaaS, 그룹웨어
투자단계: {stage} # seed | pre-A | series A | series B | series C | series D
직원 수: {N}명
투자금액: {disclosed / 비공개}
```
**사례 1: Seed 단계** (리버스마운틴):
```
기업: 리버스마운틴 (티키타카)
산업: 협업툴/그룹웨어, SaaS/엔터프라이즈
투자단계: seed
직원: 9명
투자: 비공개
```
**사례 2: Series A** (가상 예시):
```
기업: Example Corp
산업: AI/ML, SaaS
투자단계: series A
직원: 25명
투자: 30억원
```
---
## 3. 유사 기업 분석 (Neo4j)
### 3.1 Neo4j 구축
**설치**: neo4j Python driver 6.0.2
```bash
pip3 install neo4j --break-system-packages
docker run -d --name neo4j -p 7474:7474 -p 7687:7687 neo4j:latest
```
**데이터 로드**: find_similar_neo4j.py:21-67
- 필터링: {industry_keywords} 기반
- 대상: M개 기업 (전체 12,703개 중)
- 예시 키워드: 조직관리, 인사솔루션, 협업툴, 그룹웨어
**관계 생성**: find_similar_neo4j.py:73-81
- SIMILAR_TO 관계: 공통 태그 K개 이상 (K=3)
- 비교 기준: tagNamesKr 필드
### 3.2 유사 기업 검색
**Cypher 쿼리**:
```cypher
MATCH (target:Startup {name: {company_name}})-[r:SIMILAR_TO]-(similar:Startup)
RETURN similar.name, similar.intro, similar.stage, similar.employees,
similar.investment, r.commonTags
ORDER BY r.commonTags DESC
LIMIT {top_k}
```
**결과 형식**:
```
1. {company_1}
- 공통 태그: K개
- 투자단계: {stage}
- 직원: N명
- 투자: X억원
- 설명: {description}
```
**사례 (리버스마운틴)**: 291개 필터링, Top 5
- 1위: 마드라스체크 (5개 공통태그, Series B, 109명, 70억)
- 2위: 콜라비팀 (4개, Series A, 30.2억)
- 3위: 디웨일 (4개, Series B, 72명, 140억)
**시장 포지셔닝**:
- {industry} 시장 분석
- {stage} 단계 경쟁 강도
- 후발주자 vs 선도기업 판단
---
## 4. 가치평가 (Bayesian MCMC)
### 4.1 방법론
**파일**: valuation_bayesian_mcmc.py:28-56
**Bayesian 추론**:
```
Posterior(가치/명) = Prior(전체 유사 기업) × Likelihood(동일 stage)
```
**MCMC (Metropolis-Hastings)**:
- 반복: n_iter회 (기본 50,000)
- Burn-in: n_iter × 0.1
- Acceptance ratio 기반 샘플링
### 4.2 데이터 전처리
**유사 기업 수집**:
- 조건: {stage_range} & {industry_tags}
- 이상치 제거: IQR 기반 (Q1-3×IQR ~ Q3+3×IQR)
- 결과: L개 유효 데이터
### 4.3 Prior Distribution
**정의**: 유사 기업 전체의 직원당 가치
- 분포: N(μ_prior, σ_prior)
- 의미: {industry} 시장 평균
### 4.4 Likelihood Distribution
**정의**: {stage} 단계만의 직원당 가치
- 분포: N(μ_likelihood, σ_likelihood)
- 의미: 타겟 기업과 동일 단계 실제 가치
### 4.5 Posterior Distribution
**MCMC 결과**:
- 분포: N(μ_posterior, σ_posterior)
- 해석: Prior와 Likelihood의 베이지안 결합
### 4.6 기본 가치평가 (프리미엄 前)
**공식**:
```
기본 가치 = {N}명 × μ_posterior억/명
```
**Stage별 평가 예시**:
| Stage | μ_posterior | 사례 | 기업 수 |
|-------|-------------|------|---------|
| seed | 1.5~2.5억/명 | 리버스마운틴: 2.08억/명 | 115개 |
| pre-A | 2.5~4.0억/명 | - | - |
| series A | 4.0~7.0억/명 | - | - |
| series B | 7.0~12억/명 | - | - |
**사례 1 (seed - 리버스마운틴)**:
- Prior: N(4.01, 8.43) - 442개 기업
- Likelihood: N(1.74, 3.34) - 115개 seed
- Posterior: N(2.08, 3.08)
- 기본: 9명 × 2.08억 = 18.7억원
- 신뢰구간: [-48억, 101억] (95% CI)
**하드코딩 프리미엄 문제**:
- 특정 기능 프리미엄 (AI +20% 등)
- 실제 데이터 미반영
- ❌ 검증 필요 → 4.7로 해결
### 4.7 동적 베이지안 프리미엄 학습
**파일**: /tmp/bayesian_premium_updater.py
**문제 인식**:
- 하드코딩 프리미엄 근거 부족
- 실제 데이터 검증 필요
**온라인 베이지안 학습**:
```
Prior_premium(t) = Posterior_premium(t-1)
새 투자 데이터 → Update → Posterior_premium(t)
```
**프리미엄 계산**:
```
premium_ratio = 실제_투자금액 / 모델_기본_평가
```
**Sequential Update**:
```
1. 초기: μ=1.0, σ=1.0 (uninformative prior)
2. 데이터 수집: {industry} & {stage} 투자 공개 기업
3. Bayesian Update: μ_t, σ_t (정확도 ↑, 불확실성 ↓)
4. PostgreSQL 저장: premium_state 테이블
```
**상태 저장 스키마**:
```sql
CREATE TABLE premium_state (
industry VARCHAR,
stage VARCHAR,
mu FLOAT,
sigma FLOAT,
n_updates INT,
updated_at TIMESTAMP
);
```
**최종 가치평가**:
```
최종 가치 = 기본_가치 × μ_premium
신뢰구간 = 기본_가치 × [μ - 1.96σ, μ + 1.96σ]
```
**사례 비교** (seed 단계):
| 방법 | 프리미엄 | 평가 (9명) | 근거 |
|------|---------|-----------|------|
| 하드코딩 | 1.38배 | 25.9억 | AI+통합 가정 |
| 동적 학습 (seed) | 0.86배 | 16.0억 | 95개 seed 데이터 |
| 차이 | -38% | -9.9억 | 과대평가 방지 |
**Stage별 프리미엄**:
| Stage | μ_premium | σ | 데이터 수 |
|-------|-----------|---|----------|
| seed | 0.86배 | 0.13 | 95개 |
| pre-A | 1.0~1.2배 | - | - |
| series A | 1.2~1.5배 | - | - |
| series B+ | 1.5~2.0배 | - | - |
**검증 사례**:
- 애디터 (seed, 5명, 32.5억 실제)
- 모델: 10.3억 → 프리미엄 후 12.4억
- 비율: 2.6배 (상위 5% outlier, seed는 변동성 큼)
**장점**:
- 데이터 기반 프리미엄
- 자동 시장 반영
- 투자 뉴스 → 자동 업데이트
### 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. 시각화
**그래프 구성**:
1. MCMC Trace Plot: 수렴 확인 (Burn-in 이후)
2. Posterior Distribution: KDE, μ_posterior 표시
3. Prior vs Posterior: 분포 변화 (학습 효과)
4. Total Valuation: 박스플롯 (중앙값, 평균, CI)
**사례별 결과**:
| Stage | μ_posterior | 중앙값 (9명 기준) | 95% CI |
|-------|-------------|------------------|--------|
| seed | 2.08억/명 | 24.1억 | [-48, 101]억 |
| series A | 5.0억/명 (추정) | 45억 | [20, 70]억 (추정) |
---
## 6. 로빙 시스템 구현 가능성
### 6.1 현재 시스템 분석
**파일**: /home/admin/ivada_project/rb8001/main.py
**기존 구조**:
- FastAPI 기반 스킬 시스템
- 엔드포인트: /api/message, /complete, /api/slack/events
- 스킬 예시: startup_news_skill.py, news_posting_skill.py, dm_skill.py
### 6.2 구현 계획
**새 스킬**: app/skills/startup_analysis_skill.py
**새 엔드포인트**: main.py에 /api/analyze/startup/{company_name} 추가
**워크플로우 관리**: LangGraph
- 유사 기업 검색 → 가치평가 → 결과 생성의 순차적 흐름 관리
- 조건부 분기: 데이터 부족 시 대안 방법 자동 선택
- 상태 관리: 분석 진행 상황 추적 및 사용자 피드백
- 에러 처리: 각 단계별 실패 시 재시도 로직
### 6.3 기술적 고려사항
**장점**:
- 데이터 접근 가능: /mnt/51123data/DATA/
- Python 라이브러리: numpy, scipy 설치 가능
- 비동기 처리: FastAPI async 지원
- 캐싱: 반복 쿼리 최적화 가능
**제약사항**:
- 메모리: 256MB 제한 (MCMC 50,000회는 가능)
- Neo4j: 별도 컨테이너 필요 (또는 networkx로 대체)
- 응답 시간: MCMC 10-30초 소요 ("분석 중..." 메시지 필요)
- 계산 집약: MCMC 대신 사전 계산 결과 사용 고려
**구현 접근**:
- 경량화: networkx 그래프 (Neo4j 없이)
- 사전 계산: 주요 기업 가치평가 미리 저장
- 근사: MCMC 대신 Gaussian approximation
- 워크플로우: LangGraph로 복잡한 분석 흐름 관리
### 6.4 사용자 경험
**대화 플로우**:
```
User: "{company_name}과 유사한 기업 찾아줘"
Robeing: [t초] "Neo4j 그래프 분석 중..."
Robeing: [t+5초] "{company_1}이 가장 유사합니다.
공통 태그 {K}개, {stage} 단계, {N}명입니다."
User: "{company_name} 가치평가해줘"
Robeing: [t초] "베이지안 MCMC 분석 중..."
Robeing: [t+30초] "약 {V}억원 (95% CI: {L}~{U}억)으로 평가됩니다.
{stage} 단계 특성상 불확실성 {σ}입니다."
User: "프리미엄 근거는?"
Robeing: "동적 학습 결과 {μ_premium:.2f}배입니다.
{industry} & {stage} 기업 {n}개 데이터 기반입니다."
```
**실제 사례**:
| 사례 | Stage | 유사 기업 | 평가 | 프리미엄 |
|------|-------|----------|------|---------|
| 리버스마운틴 | seed | 마드라스체크 (5개 태그) | 16.0억 (CI: 12.5~21.4) | 0.86배 (95개 seed) |
| Example Corp | series A | - | - | 1.2배 (추정) |
---
## 7. 교훈
### 7.1 데이터 품질의 중요성
- K-Startup 데이터: 투자금액 "비공개" 다수
- 결측치 처리: 442개 중 실제 사용 가능한 데이터는 더 적음
- 교훈: 가치평가는 데이터 품질에 크게 의존
### 7.2 초기 단계의 불확실성
- 95% CI 넓음: {stage} 특성상 변동성 큼
- 음수 하한 가능: 일부 기업 투자 실패
- 교훈: 확률 분포와 신뢰구간 제시 필수
### 7.3 Neo4j vs 단순 필터링
- Neo4j 장점: 관계 중심 탐색, 확장성
- 단순 필터링: 빠르고 간단
- 교훈: 소규모(수백 개)는 필터링, 대규모(수만 개)는 그래프 DB
### 7.4 MCMC의 실용성
- 계산 시간: 50,000회 약 2-3초
- 수렴 확인: Trace plot으로 검증 필수
- 교훈: 비동기 처리와 진행 상황 UI 필요
### 7.5 하드코딩의 위험성
- 가정 기반 프리미엄 → 실제 데이터와 괴리
- 과대/과소평가 가능성
- 검증 없는 파라미터는 위험
- 교훈: 모든 가정은 데이터 검증, 동적 업데이트 필수
### 7.6 온라인 학습의 중요성
- Sequential Bayesian Update로 지속 개선
- PostgreSQL 상태 저장으로 누적 학습
- 투자 뉴스 크롤링 → 자동 프리미엄 업데이트
- 교훈: 정적 모델보다 동적 학습이 시장 반영
### 7.7 임의 경계의 문제
- Stage/Industry 범주 분할 → 정보 손실
- K=3, IQR 3배, Burn-in 10% → 근거 없는 하드코딩
- 교훈: Categorical → Feature/Embedding, Hyperparameter → Auto-tuning
---
## 8. 참고 자료
### 8.1 관련 연구
- research/bayesian_theory/ - 베이지안 추론 이론
- research/knowledge_graph/ - Neo4j 그래프 DB
### 8.2 데이터 소스
- K-Startup 공공데이터: https://www.k-startup.go.kr
- 스타트업 투자 데이터: 12,703개 기업 (2025-10-16 기준)
### 8.3 기술 스택
- Neo4j 2025.09.0: 그래프 데이터베이스
- Python neo4j driver 6.0.2
- NumPy, SciPy: 통계 계산
- Matplotlib: 시각화
- LangGraph: 워크플로우 관리 및 상태 추적
- PostgreSQL: 동적 프리미엄 상태 저장 및 온라인 학습
---
**작성 완료**: 2025-10-16
**프레임워크 버전**: 1.0
**검증 사례**:
- seed: 리버스마운틴 (9명, 협업툴), 애디터 (5명)
- series A+: 추가 검증 필요