feat: 初始提交 - 科创企业特有风险的识别与管理 (数智风控系统)
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
动态保险定价模型
|
||||
基于精算原理,结合六维风险评分实现"千企千面"费率计算
|
||||
"""
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 将项目根目录添加到 Python 路径
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from config import INSURANCE_PRODUCTS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# 行业风险系数
|
||||
INDUSTRY_RISK_FACTORS = {
|
||||
"芯片": 1.35, # 地缘风险+技术迭代双高
|
||||
"AI": 1.30, # 合规风险+技术竞争
|
||||
"软件": 1.05, # 相对成熟
|
||||
"医疗器械": 0.95, # 技术壁垒高但风险较稳
|
||||
"新能源": 1.15, # 技术路线之争+贸易摩擦
|
||||
"消费电子": 1.10, # 供应链风险
|
||||
}
|
||||
|
||||
# 企业规模折扣(大企业风险分散能力更强)
|
||||
SCALE_DISCOUNT = {
|
||||
"超大型": 0.85, # 营收 > 500亿
|
||||
"大型": 0.90, # 100-500亿
|
||||
"中型": 1.00, # 10-100亿
|
||||
"小型": 1.15, # 1-10亿
|
||||
"微型": 1.30, # < 1亿
|
||||
}
|
||||
|
||||
|
||||
def get_enterprise_scale(revenue: float) -> str:
|
||||
"""根据营收判断企业规模"""
|
||||
if revenue >= 50_000_000_000:
|
||||
return "超大型"
|
||||
elif revenue >= 10_000_000_000:
|
||||
return "大型"
|
||||
elif revenue >= 1_000_000_000:
|
||||
return "中型"
|
||||
elif revenue >= 100_000_000:
|
||||
return "小型"
|
||||
return "微型"
|
||||
|
||||
|
||||
def calculate_premium(
|
||||
product_key: str,
|
||||
comprehensive_risk_score: int,
|
||||
six_dimension_scores: dict,
|
||||
sector: str = "",
|
||||
revenue: float = 0,
|
||||
) -> dict:
|
||||
"""
|
||||
动态费率计算器
|
||||
|
||||
定价公式:
|
||||
实际保费 = 基础保费 × 风险系数 × 行业调整 × 规模折扣
|
||||
|
||||
风险系数由综合评分决定(分段线性):
|
||||
- [0, 30) → 0.7 ~ 0.9(优质折扣)
|
||||
- [30, 50) → 0.9 ~ 1.2(标准浮动)
|
||||
- [50, 70) → 1.2 ~ 1.8(风险上浮)
|
||||
- [70, 90) → 1.8 ~ 2.5(惩罚性费率)
|
||||
- [90,100] → 拒保或附加极高免赔额
|
||||
"""
|
||||
product = INSURANCE_PRODUCTS.get(product_key)
|
||||
if not product:
|
||||
return {"error": f"未知保险产品: {product_key}"}
|
||||
|
||||
base_premium = product["base_premium"]
|
||||
base_coverage = product["base_coverage"]
|
||||
|
||||
# 1. 计算风险系数
|
||||
risk_multiplier = _calculate_risk_multiplier(comprehensive_risk_score)
|
||||
|
||||
# 2. 行业调整系数
|
||||
industry_factor = INDUSTRY_RISK_FACTORS.get(sector, 1.0)
|
||||
|
||||
# 3. 规模折扣
|
||||
scale = get_enterprise_scale(revenue)
|
||||
scale_factor = SCALE_DISCOUNT[scale]
|
||||
|
||||
# 4. 特定险种的维度调整
|
||||
dimension_adjustment = _get_dimension_adjustment(product_key, six_dimension_scores)
|
||||
|
||||
# 5. 最终保费
|
||||
final_premium = base_premium * risk_multiplier * industry_factor * scale_factor * dimension_adjustment
|
||||
|
||||
# 6. 核保条件
|
||||
deductible_rate = _calculate_deductible(comprehensive_risk_score)
|
||||
adjusted_coverage = base_coverage * (1.0 if comprehensive_risk_score < 70 else 0.7)
|
||||
|
||||
return {
|
||||
"product_name": product["name"],
|
||||
"product_key": product_key,
|
||||
"base_premium": base_premium,
|
||||
"base_coverage": base_coverage,
|
||||
"risk_multiplier": round(risk_multiplier, 3),
|
||||
"industry_factor": round(industry_factor, 3),
|
||||
"scale_factor": round(scale_factor, 3),
|
||||
"scale_label": scale,
|
||||
"dimension_adjustment": round(dimension_adjustment, 3),
|
||||
"final_premium": round(final_premium, 2),
|
||||
"adjusted_coverage": round(adjusted_coverage, 2),
|
||||
"deductible_rate": round(deductible_rate, 3),
|
||||
"deductible_amount": round(adjusted_coverage * deductible_rate, 2),
|
||||
"comprehensive_risk_score": comprehensive_risk_score,
|
||||
"is_insurable": comprehensive_risk_score < 90,
|
||||
"pricing_breakdown": (
|
||||
f"¥{base_premium:,.0f} × {risk_multiplier:.2f}(风险) "
|
||||
f"× {industry_factor:.2f}(行业) × {scale_factor:.2f}(规模) "
|
||||
f"× {dimension_adjustment:.2f}(维度) = ¥{final_premium:,.0f}"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def _calculate_risk_multiplier(score: int) -> float:
|
||||
"""分段线性风险系数计算"""
|
||||
if score < 30:
|
||||
return 0.7 + (score / 30) * 0.2 # 0.7 ~ 0.9
|
||||
elif score < 50:
|
||||
return 0.9 + ((score - 30) / 20) * 0.3 # 0.9 ~ 1.2
|
||||
elif score < 70:
|
||||
return 1.2 + ((score - 50) / 20) * 0.6 # 1.2 ~ 1.8
|
||||
elif score < 90:
|
||||
return 1.8 + ((score - 70) / 20) * 0.7 # 1.8 ~ 2.5
|
||||
else:
|
||||
return 3.0 # 拒保级别
|
||||
|
||||
|
||||
def _get_dimension_adjustment(product_key: str, scores: dict) -> float:
|
||||
"""针对特定险种,根据相关维度得分进行微调"""
|
||||
if product_key == "ip_lawsuit":
|
||||
# 知识产权被诉险:重点看技术路线和专利
|
||||
tech_score = scores.get("tech_disruption", 50)
|
||||
return 0.8 + (tech_score / 100) * 0.4 # 0.8 ~ 1.2
|
||||
|
||||
elif product_key == "exec_departure":
|
||||
# 高管离职险:重点看人员流失风险
|
||||
talent_score = scores.get("talent_loss", 50)
|
||||
return 0.7 + (talent_score / 100) * 0.6 # 0.7 ~ 1.3
|
||||
|
||||
elif product_key == "data_compliance":
|
||||
# 数据合规险:重点看合规风险
|
||||
compliance_score = scores.get("algo_compliance", 50)
|
||||
return 0.8 + (compliance_score / 100) * 0.4 # 0.8 ~ 1.2
|
||||
|
||||
return 1.0
|
||||
|
||||
|
||||
def _calculate_deductible(score: int) -> float:
|
||||
"""计算免赔率"""
|
||||
if score < 30:
|
||||
return 0.05 # 5%
|
||||
elif score < 50:
|
||||
return 0.10 # 10%
|
||||
elif score < 70:
|
||||
return 0.15 # 15%
|
||||
elif score < 90:
|
||||
return 0.25 # 25%
|
||||
else:
|
||||
return 0.50 # 50%(惩罚性高免赔)
|
||||
|
||||
|
||||
def calculate_all_products(
|
||||
comprehensive_risk_score: int,
|
||||
six_dimension_scores: dict,
|
||||
sector: str = "",
|
||||
revenue: float = 0,
|
||||
) -> list:
|
||||
"""计算所有险种的保费"""
|
||||
results = []
|
||||
for product_key in INSURANCE_PRODUCTS:
|
||||
result = calculate_premium(
|
||||
product_key, comprehensive_risk_score,
|
||||
six_dimension_scores, sector, revenue,
|
||||
)
|
||||
results.append(result)
|
||||
return results
|
||||
Reference in New Issue
Block a user