"""评价权重计算引擎。 6 轴动态权重合并 + 归一化: 1. 基金类型 × 存续期 → 基础权重模板(32 个预设) 2. 企业阶段 → 阶段系数调整(5 个预设) 3. 产业赛道 → 维度裁剪 + 专属指标注入(6 个预设) 4. 投资策略 → ±5% 微调(4 个预设) 5. 归一化 — 裁剪后剩余维度权重自动归一化到 100% 6. 修饰因子叠加 — LP 附加指标 + 地域基准校准 """ import logging from typing import Any logger = logging.getLogger(__name__) # --- 基础 14 维度权重(来自 health_calculator.py) --- BASE_WEIGHTS: dict[str, float] = { "financial": 0.15, "operational": 0.10, "ai_commercial": 0.10, "ai_cost": 0.05, "org_talent": 0.10, "product_tech": 0.10, "market_compete": 0.10, "governance": 0.05, "financing": 0.05, "synergy": 0.05, "ai_model_product": 0.05, "data_compliance": 0.05, "team_tech": 0.03, "customer_success": 0.07, } # 维度 key 映射:权重 key → 评分字段 key DIMENSION_KEY_MAP: dict[str, str] = { "financial": "financial_score", "operational": "operational_score", "ai_commercial": "ai_commercial_score", "ai_cost": "ai_cost_score", "org_talent": "org_talent_score", "product_tech": "product_tech_score", "market_compete": "market_compete_score", "governance": "governance_score", "financing": "financing_score", "synergy": "synergy_score", "ai_model_product": "ai_model_product_score", "data_compliance": "data_compliance_score", "team_tech": "team_tech_score", "customer_success": "customer_success_score", } # --- 轴 5:基金类型 × 存续期基础权重系数(32 个预设) --- FUND_LIFECYCLE_MULTIPLIERS: dict[tuple[str, str], dict[str, float]] = { ("angel", "investment"): {"financial": 0.5, "product_tech": 1.8, "org_talent": 1.5, "market": 1.2}, ("angel", "growth"): {"financial": 0.7, "product_tech": 1.5, "org_talent": 1.3, "market": 1.2}, ("angel", "exit_preparation"): {"financial": 1.0, "product_tech": 1.2, "org_talent": 1.0, "financing": 1.5}, ("angel", "liquidation"): {"financial": 1.5, "financing": 2.0, "product_tech": 0.8}, ("early_vc", "investment"): {"financial": 0.7, "product_tech": 1.5, "market": 1.2, "customer_success": 0.8}, ("early_vc", "growth"): {"financial": 0.9, "product_tech": 1.3, "market": 1.2, "customer_success": 1.0}, ("early_vc", "exit_preparation"): {"financial": 1.3, "market": 1.0, "customer_success": 1.2, "financing": 1.5}, ("early_vc", "liquidation"): {"financial": 1.8, "financing": 2.0, "product_tech": 0.6}, ("growth_vc", "investment"): {"financial": 1.0, "market": 1.3, "customer_success": 1.2}, ("growth_vc", "growth"): {"financial": 1.2, "market": 1.2, "customer_success": 1.3}, ("growth_vc", "exit_preparation"): {"financial": 1.5, "market": 1.0, "customer_success": 1.2, "financing": 1.5}, ("growth_vc", "liquidation"): {"financial": 2.0, "financing": 2.0, "market": 0.8}, ("pe", "investment"): {"financial": 1.8, "governance": 1.5, "customer_success": 1.3, "product_tech": 0.5, "ai_commercial": 0.3, "ai_cost": 0.3, "ai_model_product": 0.3}, ("pe", "growth"): {"financial": 2.0, "governance": 1.5, "customer_success": 1.3, "product_tech": 0.5, "ai_commercial": 0.3, "ai_cost": 0.3, "ai_model_product": 0.3}, ("pe", "exit_preparation"): {"financial": 2.5, "governance": 1.8, "financing": 1.5, "ai_commercial": 0.3, "ai_cost": 0.3, "ai_model_product": 0.3}, ("pe", "liquidation"): {"financial": 3.0, "financing": 2.0, "governance": 1.5, "ai_commercial": 0.3, "ai_cost": 0.3, "ai_model_product": 0.3}, ("cvc", "investment"): {"synergy": 2.0, "market": 1.3, "product_tech": 1.2, "financial": 0.7}, ("cvc", "growth"): {"synergy": 1.8, "market": 1.2, "product_tech": 1.2, "financial": 0.8}, ("cvc", "exit_preparation"): {"synergy": 1.5, "market": 1.0, "financial": 1.2, "financing": 1.3}, ("cvc", "liquidation"): {"financial": 1.5, "financing": 1.5, "synergy": 1.0}, ("distress", "investment"): {"financial": 2.5, "governance": 1.5, "product_tech": 0.5, "market": 0.5, "ai_commercial": 0.3, "ai_cost": 0.3, "ai_model_product": 0.3}, ("distress", "growth"): {"financial": 2.5, "governance": 1.5, "product_tech": 0.5, "ai_commercial": 0.3, "ai_cost": 0.3, "ai_model_product": 0.3}, ("distress", "exit_preparation"): {"financial": 3.0, "governance": 1.5, "financing": 1.5, "ai_commercial": 0.3, "ai_cost": 0.3, "ai_model_product": 0.3}, ("distress", "liquidation"): {"financial": 3.0, "financing": 2.0, "governance": 1.5, "ai_commercial": 0.3, "ai_cost": 0.3, "ai_model_product": 0.3}, ("esg", "investment"): {"governance": 1.8, "data_compliance": 1.5, "product_tech": 1.2, "financial": 0.8}, ("esg", "growth"): {"governance": 1.5, "data_compliance": 1.3, "customer_success": 1.2}, ("esg", "exit_preparation"): {"governance": 1.8, "financial": 1.3, "financing": 1.3}, ("esg", "liquidation"): {"financial": 1.5, "governance": 1.5, "financing": 1.5}, # FOF 不直接评价单企业,使用默认权重 ("fof", "investment"): {}, ("fof", "growth"): {}, ("fof", "exit_preparation"): {}, ("fof", "liquidation"): {}, } # --- 轴 2:企业阶段系数(5 个预设) --- STAGE_MULTIPLIERS: dict[str, dict[str, float]] = { "seed": {"financial": 0.6, "product_tech": 1.8, "org_talent": 1.5, "market_compete": 0.5, "governance": 0.6, "customer_success": 0.5}, "a": {"financial": 0.8, "product_tech": 1.5, "org_talent": 1.2, "market_compete": 1.0, "governance": 0.7, "customer_success": 0.8}, "b": {"financial": 1.2, "market_compete": 1.3, "customer_success": 1.3, "product_tech": 1.0, "governance": 1.0}, "c": {"financial": 1.5, "market_compete": 1.3, "governance": 1.3, "customer_success": 1.3, "product_tech": 0.8}, "pre_ipo": {"financial": 1.5, "governance": 1.8, "customer_success": 1.3, "market_compete": 1.0, "product_tech": 0.8}, } # --- 轴 3:产业赛道配置(6 个预设) --- INDUSTRY_CONFIGS: dict[str, dict[str, Any]] = { "ai": { "enabled": list(DIMENSION_KEY_MAP.keys()), "disabled": [], "custom_metrics": [ {"key": "model_accuracy", "label": "模型精度", "description": "AI 模型准确率/召回率"}, {"key": "inference_cost", "label": "推理成本", "description": "单次推理成本趋势"}, {"key": "api_call_volume", "label": "API 调用量", "description": "月度 API 调用次数"}, {"key": "poc_conversion_rate", "label": "PoC 转化率", "description": "PoC 到付费转化率"}, ], }, "saas": { "enabled": ["financial", "operational", "ai_commercial", "org_talent", "product_tech", "market_compete", "governance", "financing", "synergy", "data_compliance", "team_tech", "customer_success"], "disabled": ["ai_cost", "ai_model_product"], "custom_metrics": [ {"key": "arr_growth", "label": "ARR 增长率", "description": "年度经常性收入增长率"}, {"key": "net_revenue_retention", "label": "NRR", "description": "净收入留存率"}, {"key": "cac_payback", "label": "CAC 回收期", "description": "获客成本回收月数"}, {"key": "rule_of_40", "label": "Rule of 40", "description": "增长率 + 利润率"}, ], }, "hardware": { "enabled": ["financial", "operational", "org_talent", "product_tech", "market_compete", "governance", "financing", "synergy", "data_compliance", "team_tech", "customer_success"], "disabled": ["ai_commercial", "ai_cost", "ai_model_product"], "custom_metrics": [ {"key": "patent_count", "label": "专利数", "description": "累计授权专利数量"}, {"key": "tape_out_progress", "label": "流片进度", "description": "芯片流片里程碑进展"}, {"key": "yield_rate", "label": "良率", "description": "产品良率"}, {"key": "rd_investment_ratio", "label": "研发投入比", "description": "研发投入占营收比例"}, ], }, "biotech": { "enabled": ["financial", "operational", "org_talent", "product_tech", "governance", "financing", "synergy", "data_compliance", "team_tech"], "disabled": ["ai_commercial", "ai_cost", "ai_model_product", "market_compete", "customer_success"], "custom_metrics": [ {"key": "clinical_stage", "label": "临床阶段", "description": "当前临床试验阶段"}, {"key": "pipeline_progress", "label": "管线进度", "description": "在研管线推进情况"}, {"key": "regulatory_milestone", "label": "审批节点", "description": "监管审批里程碑"}, {"key": "patent_landscape", "label": "专利布局", "description": "核心专利布局覆盖度"}, ], }, "consumer": { "enabled": ["financial", "operational", "org_talent", "product_tech", "market_compete", "governance", "financing", "synergy", "team_tech", "customer_success"], "disabled": ["ai_commercial", "ai_cost", "ai_model_product", "data_compliance"], "custom_metrics": [ {"key": "gmv", "label": "GMV", "description": "月度交易总额"}, {"key": "repurchase_rate", "label": "复购率", "description": "客户复购率"}, {"key": "brand_index", "label": "品牌指数", "description": "品牌知名度/美誉度"}, {"key": "channel_coverage", "label": "渠道覆盖率", "description": "销售渠道覆盖广度"}, ], }, "fintech": { "enabled": ["financial", "operational", "ai_commercial", "org_talent", "product_tech", "market_compete", "governance", "financing", "synergy", "ai_model_product", "data_compliance", "team_tech", "customer_success"], "disabled": ["ai_cost"], "custom_metrics": [ {"key": "license_progress", "label": "牌照进度", "description": "金融牌照获取进展"}, {"key": "risk_control_score", "label": "风控指标", "description": "风控模型评分"}, {"key": "compliance_events", "label": "合规事件", "description": "合规事件数量"}, {"key": "npl_ratio", "label": "坏账率", "description": "不良贷款率"}, ], }, "manufacturing": { "enabled": ["financial", "operational", "org_talent", "product_tech", "market_compete", "governance", "financing", "synergy", "data_compliance", "team_tech", "customer_success"], "disabled": ["ai_commercial", "ai_cost", "ai_model_product"], "custom_metrics": [ {"key": "capacity_utilization", "label": "产能利用率", "description": "实际产能/设计产能"}, {"key": "delivery_cycle", "label": "交付周期", "description": "订单交付周期天数"}, {"key": "supply_chain_stability", "label": "供应链稳定性", "description": "供应链中断风险评分"}, {"key": "rd_investment_ratio", "label": "研发投入比", "description": "研发投入占营收比例"}, ], }, } # --- 轴 4:投资策略微调(4 个预设,±5%) --- STRATEGY_ADJUSTMENTS: dict[str, dict[str, float]] = { "growth": {"market_compete": 5, "product_tech": 5, "customer_success": 5, "financial": -5, "governance": -5}, "value": {"financial": 5, "governance": 5, "customer_success": 5, "market_compete": -5, "product_tech": -5}, "empowerment": {"synergy": 5, "org_talent": 5, "product_tech": 5, "financial": -5, "market_compete": -5}, "turnaround": {"financial": 5, "governance": 5, "market_compete": -5, "product_tech": -5}, } def compute_weights( fund_type: str, fund_lifecycle: str, company_stage: str, industry: str, strategy: str = "growth", investor_type: str = "investor", ) -> dict[str, Any]: """计算 6 轴动态权重。 Args: fund_type: 基金类型 — angel/early_vc/growth_vc/pe/cvc/fof/distress/esg fund_lifecycle: 存续期阶段 — investment/growth/exit_preparation/liquidation company_stage: 企业阶段 — seed/a/b/c/pre_ipo industry: 产业赛道 — ai/saas/hardware/biotech/consumer/fintech/manufacturing strategy: 投资策略 — growth/value/empowerment/turnaround investor_type: 投资人类型 — gp/post_invest_lead/investor(不影响权重) Returns: 包含 weights、enabled_dimensions、disabled_dimensions、custom_metrics 的字典 """ # Step 1:复制基础权重 weights = dict(BASE_WEIGHTS) # Step 2:基金类型 × 存续期系数 fund_key = (fund_type, fund_lifecycle) fund_multipliers = FUND_LIFECYCLE_MULTIPLIERS.get(fund_key, {}) for dim, multiplier in fund_multipliers.items(): if dim in weights: weights[dim] *= multiplier # Step 3:企业阶段系数 stage_multipliers = STAGE_MULTIPLIERS.get(company_stage, {}) for dim, multiplier in stage_multipliers.items(): if dim in weights: weights[dim] *= multiplier # Step 4:产业赛道 — 维度裁剪 industry_config = INDUSTRY_CONFIGS.get(industry, INDUSTRY_CONFIGS["ai"]) enabled_dims = industry_config["enabled"] disabled_dims = industry_config["disabled"] # 禁用的维度权重置零 for dim in disabled_dims: if dim in weights: weights[dim] = 0.0 # Step 5:投资策略微调(±5%,基于百分比点) strategy_adj = STRATEGY_ADJUSTMENTS.get(strategy, {}) for dim, adjustment in strategy_adj.items(): if dim in weights and weights[dim] > 0: # 将百分比点转换为权重调整量 weights[dim] += adjustment / 100.0 # 确保非负 for dim in weights: weights[dim] = max(0.0, weights[dim]) # Step 6:归一化 — 只对启用维度归一化到 1.0 enabled_weights = {dim: weights[dim] for dim in enabled_dims if dim in weights} total = sum(enabled_weights.values()) if total > 0: normalized = {dim: w / total for dim, w in enabled_weights.items()} else: # 极端情况:所有权重为零,均分 count = len(enabled_dims) if enabled_dims else 1 normalized = {dim: 1.0 / count for dim in enabled_dims} # 转换为百分比格式(保留 4 位小数) final_weights = {dim: round(w * 100, 2) for dim, w in normalized.items()} logger.info( "权重计算完成: fund_type=%s, lifecycle=%s, stage=%s, industry=%s, strategy=%s → %s", fund_type, fund_lifecycle, company_stage, industry, strategy, final_weights, ) return { "weights": final_weights, "enabled_dimensions": enabled_dims, "disabled_dimensions": disabled_dims, "custom_metrics": industry_config.get("custom_metrics", []), } def get_dimension_score_key(weight_key: str) -> str: """将权重 key 转换为评分字段 key。""" return DIMENSION_KEY_MAP.get(weight_key, f"{weight_key}_score") def calculate_weighted_score( dimension_scores: dict[str, float], weights: dict[str, float], ) -> float: """根据维度评分和权重计算加权总分。 Args: dimension_scores: 各维度评分(0-100),key 为权重 key(如 financial) weights: 各维度权重(百分比),key 为权重 key Returns: 加权总分(0-100) """ total = 0.0 weight_sum = 0.0 for dim, weight in weights.items(): score = dimension_scores.get(dim) if score is not None and weight > 0: total += score * weight weight_sum += weight if weight_sum > 0: return round(total / weight_sum, 1) return 0.0