Spaces:
Sleeping
Sleeping
""" | |
用户输入数据模型定义 | |
使用Pydantic进行数据验证 | |
""" | |
from pydantic import BaseModel, Field | |
from typing import Optional, List | |
from enum import Enum | |
class RiskLevel(str, Enum): | |
"""风险等级枚举""" | |
LOW = "low" | |
MEDIUM = "medium" | |
HIGH = "high" | |
class ModelType(str, Enum): | |
"""模型类型枚举""" | |
SARCO_I = "sarcoI" | |
SARCO_II = "sarcoII" | |
class UserInput(BaseModel): | |
"""用户输入数据模型""" | |
# 基本信息 (注意:本系统适用于18-55岁成年人群) | |
age_years: float = Field(..., ge=16, le=120, description="年龄(岁) - 推荐18-55岁") | |
race_ethnicity: int = Field(..., ge=0, le=4, description="种族/民族编码(0-4)") | |
# 身体指标 | |
body_mass_index: float = Field(..., ge=10, le=80, description="体质量指数BMI") | |
WWI: float = Field(..., ge=3, le=50, description="腰围重量指数") | |
# NHANES PAQ 原始问卷数据 | |
# 工作相关活动 | |
PAQ605: int = Field(..., ge=1, le=2, description="工作高强度活动(1=是,2=否)") | |
PAQ610: Optional[int] = Field(0, ge=0, le=7, description="工作高强度活动天数/周") | |
PAD615: Optional[float] = Field(0, ge=0, le=1440, description="工作高强度活动分钟数/天") | |
PAQ620: int = Field(..., ge=1, le=2, description="工作中等强度活动(1=是,2=否)") | |
PAQ625: Optional[int] = Field(0, ge=0, le=7, description="工作中等强度活动天数/周") | |
PAD630: Optional[float] = Field(0, ge=0, le=1440, description="工作中等强度活动分钟数/天") | |
# 交通相关活动 | |
PAQ635: int = Field(..., ge=1, le=2, description="步行/骑车通勤(1=是,2=否)") | |
PAQ640: Optional[int] = Field(0, ge=0, le=7, description="步行/骑车通勤天数/周") | |
PAD645: Optional[float] = Field(0, ge=0, le=1440, description="步行/骑车通勤分钟数/天") | |
# 休闲运动活动 | |
PAQ650: int = Field(..., ge=1, le=2, description="休闲高强度活动(1=是,2=否)") | |
PAQ655: Optional[int] = Field(0, ge=0, le=7, description="休闲高强度活动天数/周") | |
PAD660: Optional[float] = Field(0, ge=0, le=1440, description="休闲高强度活动分钟数/天") | |
PAQ665: int = Field(..., ge=1, le=2, description="休闲中等强度活动(1=是,2=否)") | |
PAQ670: Optional[int] = Field(0, ge=0, le=7, description="休闲中等强度活动天数/周") | |
PAD675: Optional[float] = Field(0, ge=0, le=1440, description="休闲中等强度活动分钟数/天") | |
# 久坐行为 | |
PAD680: float = Field(..., ge=0, le=1440, description="每日久坐时间(分钟)") | |
# 医疗史 (筛查模型必需) | |
arthritis: Optional[int] = Field(0, ge=0, le=1, description="关节炎史(0=无,1=有)") | |
diabetes: Optional[int] = Field(0, ge=0, le=1, description="糖尿病史(0=无,1=有)") | |
# 计算得出的衍生特征 (前端计算后传入) | |
Activity_Sedentary_Ratio: Optional[float] = Field(None, ge=0, le=100, description="久坐活动比例") | |
Total_Moderate_Minutes_week: Optional[float] = Field(None, ge=0, le=10080, description="每周中等强度运动时间(分钟)") | |
Total_Moderate_Equivalent_Minutes: Optional[float] = Field(None, ge=0, le=10080, description="每周中等强度等效运动时间(分钟)") | |
Avg_Vigorous_Duration_Per_Bout: Optional[float] = Field(None, ge=0, le=1440, description="平均高强度运动时长每次(分钟)") | |
Vigorous_MET_Ratio: Optional[float] = Field(None, ge=0, le=10, description="高强度运动比例") | |
Activity_Diversity_Index: Optional[float] = Field(None, ge=0, le=5, description="活动多样性指数(0-5)") | |
sedentary_minutes: Optional[float] = Field(None, ge=0, le=1440, description="每日久坐时间(分钟,同PAD680)") | |
class Config: | |
json_schema_extra = { | |
"example": { | |
"age_years": 45, | |
"race_ethnicity": 2, | |
"body_mass_index": 28.5, | |
"WWI": 11.2, | |
"PAQ605": 2, | |
"PAQ620": 1, | |
"PAQ625": 3, | |
"PAD630": 60, | |
"PAQ635": 1, | |
"PAQ640": 5, | |
"PAD645": 30, | |
"PAQ650": 1, | |
"PAQ655": 2, | |
"PAD660": 45, | |
"PAQ665": 1, | |
"PAQ670": 3, | |
"PAD675": 60, | |
"PAD680": 480, | |
"arthritis": 0, | |
"diabetes": 0, | |
"Activity_Sedentary_Ratio": 0.6, | |
"Total_Moderate_Minutes_week": 150, | |
"Total_Moderate_Equivalent_Minutes": 150, | |
"Avg_Vigorous_Duration_Per_Bout": 30, | |
"Vigorous_MET_Ratio": 0.3, | |
"Activity_Diversity_Index": 3, | |
"sedentary_minutes": 480 | |
} | |
} | |
class ScreeningRequest(BaseModel): | |
"""筛查请求模型""" | |
user_data: UserInput | |
models: List[ModelType] = [ModelType.SARCO_I, ModelType.SARCO_II] | |
class AdvisoryRequest(BaseModel): | |
"""建议请求模型""" | |
user_data: UserInput | |
risk_types: List[ModelType] = [] | |
num_recommendations: int = Field(default=3, ge=1, le=5, description="建议数量") | |
language: str = Field(default="zh", description="语言设置 (zh/en)") | |
class ScreeningResponse(BaseModel): | |
"""筛查响应模型""" | |
# 筛查模型结果 (高召回率) | |
sarcoI_risk: RiskLevel | |
sarcoI_probability: float | |
sarcoI_threshold: float | |
sarcoII_risk: RiskLevel | |
sarcoII_probability: float | |
sarcoII_threshold: float | |
# 建议模型结果 (高精确率) | |
sarcoI_advisory_risk: Optional[RiskLevel] = None | |
sarcoI_advisory_probability: Optional[float] = None | |
sarcoI_advisory_threshold: Optional[float] = None | |
sarcoII_advisory_risk: Optional[RiskLevel] = None | |
sarcoII_advisory_probability: Optional[float] = None | |
sarcoII_advisory_threshold: Optional[float] = None | |
# 综合结果 | |
overall_risk: RiskLevel | |
confidence: float | |
processing_time: float | |
class RecommendationItem(BaseModel): | |
"""单个建议项""" | |
title: str | |
description: str | |
priority: str | |
target_change: Optional[str] = None | |
expected_impact: Optional[str] = None | |
class AdvisoryResponse(BaseModel): | |
"""建议响应模型""" | |
sarcoI_recommendations: List[RecommendationItem] | |
sarcoII_recommendations: List[RecommendationItem] | |
recommendations: Optional[List[RecommendationItem]] = None # 合并的建议列表,用于前端显示 | |
priority_actions: List[str] | |
target_metrics: dict | |
processing_time: float | |
success: bool | |
fallback_used: bool = False | |
class ErrorResponse(BaseModel): | |
"""错误响应模型""" | |
error: str | |
detail: str | |
timestamp: str |