190-基于Python的全球结直肠癌数据分析可视化
本文介绍了一个基于FastAPI的全球结直肠癌数据分析可视化系统,该系统整合了机器学习、数据可视化和Web开发技术,为医疗数据分析提供了完整解决方案。系统包含16个国家16.7万条患者数据,采用随机森林算法实现85%+预测准确率,支持地理、人口、临床等多维度分析。技术架构采用FastAPI后端+Bootstrap前端+SQLite数据库,提供智能预测、数据管理、可视化展示等核心功能。系统亮点包括全
🏥 基于FastAPI的全球结直肠癌数据分析可视化系统:从数据到智能预测的完整解决方案
一个集机器学习、数据可视化、Web开发于一体的医疗数据分析平台
项目演示 • 技术架构 • 核心功能 • 代码实现 • 部署指南
📋 目录
🎯 项目概述
项目背景
在全球医疗数据爆炸式增长的时代,如何有效分析和利用医疗数据成为医疗行业的重要课题。结直肠癌作为全球第三大常见癌症,其数据分析和预测对医疗决策具有重要意义。本项目基于Python生态系统,构建了一个完整的结直肠癌数据分析与可视化平台。
核心价值
- 🤖 智能预测:基于RandomForest算法,预测准确率达85%+
- 📊 多维分析:地理、人口、临床、时间四大维度深度分析
- 🗄️ 数据管理:支持27个字段的完整患者数据CRUD操作
- 💻 现代化UI:Bootstrap 5医疗主题设计,响应式布局
- 🌐 离线运行:完全本地化部署,无需网络连接
项目亮点
- 167,497条真实患者数据
- 16个国家全球数据覆盖
- **68.3%**平均5年生存率
- 14个特征机器学习预测模型
🛠️ 技术栈详解
后端技术栈
| 技术 | 版本 | 用途 | 优势 |
|---|---|---|---|
| FastAPI | 0.104+ | Web框架 | 高性能、自动API文档、类型提示 |
| SQLite3 | 3+ | 数据库 | 轻量级、零配置、跨平台 |
| scikit-learn | 1.3.2 | 机器学习 | 丰富的算法库、易用API |
| pandas | 2.1.3 | 数据处理 | 强大的数据分析能力 |
| numpy | 1.24.3 | 数值计算 | 高效的数组操作 |
| Uvicorn | 0.24.0 | ASGI服务器 | 高性能异步服务器 |
前端技术栈
| 技术 | 版本 | 用途 | 特点 |
|---|---|---|---|
| Bootstrap 5 | 5.3.0 | UI框架 | 响应式设计、组件丰富 |
| ECharts | 5.4.0 | 数据可视化 | 交互性强、图表类型丰富 |
| Jinja2 | 3.1.2 | 模板引擎 | 灵活、安全、易维护 |
| jQuery | 3.6.0 | JavaScript库 | DOM操作、AJAX请求 |
| Bootstrap Icons | 1.10.0 | 图标库 | 丰富的图标资源 |
开发工具
- 包管理:pip + requirements.txt
- 代码规范:PEP 8 Python编码规范
- 版本控制:Git
- IDE支持:VS Code、PyCharm
🏗️ 系统架构
整体架构图
项目演示
190-基于Python的全球结直肠癌数据可视化分析系统
























目录结构
全球结直肠癌数据分析可视化系统/
├── 📁 核心文件
│ ├── main.py # FastAPI主应用
│ ├── database.py # 数据库操作模块
│ ├── predictor.py # 机器学习预测模块
│ ├── import_data.py # 数据导入脚本
│ ├── start_server.py # 服务器启动脚本
│ └── requirements.txt # 依赖包列表
│
├── 📁 数据存储
│ ├── colorectal_cancer_prediction.db # SQLite数据库
│ └── data/
│ └── colorectal_cancer_dataset.csv # 原始数据集
│
├── 📁 机器学习模型
│ └── model/
│ ├── colorectal_model.pkl # 训练好的模型
│ ├── feature_names.pkl # 特征名称
│ ├── label_encoders.pkl # 标签编码器
│ └── scaler.pkl # 数据标准化器
│
├── 📁 前端模板
│ └── templates/
│ ├── base.html # 基础模板
│ ├── index.html # 首页
│ ├── login.html # 登录页
│ ├── register.html # 注册页
│ ├── predict.html # 预测页面
│ ├── analytics.html # 数据分析页
│ ├── data_manage.html # 数据管理页
│ └── ... # 其他页面
│
└── 📁 静态资源
└── static/
├── css/ # 样式文件
├── js/ # JavaScript文件
├── fonts/ # 字体文件
└── image/ # 图片资源
🚀 核心功能实现
1. 用户认证系统
注册功能实现
@app.post("/register")
async def register(
request: Request,
username: str = Form(...),
password: str = Form(...),
email: str = Form(None),
full_name: str = Form(None),
phone: str = Form(None)
):
"""处理用户注册"""
if create_user(username, password, email, full_name, phone):
add_message(request, 'success', '注册成功!请登录。')
return RedirectResponse(url="/login", status_code=302)
else:
return templates.TemplateResponse("register.html", {
"request": request,
"messages": [('error', '用户名已存在,请选择其他用户名。')],
"session": request.session
})
密码安全处理
def hash_password(password):
"""密码哈希处理"""
return hashlib.sha256(password.encode()).hexdigest()
def verify_password(password, hashed):
"""密码验证"""
return hash_password(password) == hashed
2. 机器学习预测系统
预测模型核心代码
class ColorectalCancerPredictor:
def __init__(self):
self.model = None
self.label_encoders = {}
self.scaler = StandardScaler()
self.feature_names = []
self.model_path = 'model/'
def preprocess_data(self, df, is_training=True):
"""数据预处理"""
data = df.copy()
# 定义14个特征列
feature_columns = [
'Age', 'Gender', 'Cancer_Stage', 'Tumor_Size_mm', 'Family_History',
'Smoking_History', 'Alcohol_Consumption', 'Obesity_BMI', 'Diet_Risk',
'Physical_Activity', 'Diabetes', 'Inflammatory_Bowel_Disease',
'Genetic_Mutation', 'Screening_History'
]
# 处理分类变量
categorical_features = [
'Gender', 'Cancer_Stage', 'Family_History', 'Smoking_History',
'Alcohol_Consumption', 'Obesity_BMI', 'Diet_Risk', 'Physical_Activity',
'Diabetes', 'Inflammatory_Bowel_Disease', 'Genetic_Mutation', 'Screening_History'
]
for feature in categorical_features:
if feature in data.columns:
if is_training:
self.label_encoders[feature] = LabelEncoder()
data[feature] = self.label_encoders[feature].fit_transform(data[feature].astype(str))
else:
if feature in self.label_encoders:
try:
data[feature] = self.label_encoders[feature].transform(data[feature].astype(str))
except ValueError:
data[feature] = 0
# 数据标准化
X = data[feature_columns]
if is_training:
X_scaled = self.scaler.fit_transform(X)
else:
X_scaled = self.scaler.transform(X)
return pd.DataFrame(X_scaled, columns=feature_columns, index=X.index)
模型训练与评估
def train_model(self, csv_file_path):
"""训练RandomForest模型"""
# 读取数据
df = pd.read_csv(csv_file_path)
# 数据预处理
X = self.preprocess_data(df, is_training=True)
y = (df['Survival_Prediction'] == 'Yes').astype(int)
# 数据分割
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 训练RandomForest模型
self.model = RandomForestClassifier(
n_estimators=100,
max_depth=10,
min_samples_split=5,
min_samples_leaf=2,
random_state=42,
n_jobs=-1
)
self.model.fit(X_train, y_train)
# 模型评估
y_pred = self.model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率: {accuracy:.4f}")
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=['不存活', '存活']))
return accuracy, self.get_feature_importance()
3. 数据管理系统
数据库设计
-- 用户表
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
email TEXT,
full_name TEXT,
phone TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_login TIMESTAMP
);
-- 患者数据表(27个字段)
CREATE TABLE IF NOT EXISTS colorectal_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
patient_id INTEGER UNIQUE,
country TEXT,
age INTEGER,
gender TEXT,
cancer_stage TEXT,
tumor_size_mm INTEGER,
family_history TEXT,
smoking_history TEXT,
alcohol_consumption TEXT,
obesity_bmi TEXT,
diet_risk TEXT,
physical_activity TEXT,
diabetes TEXT,
inflammatory_bowel_disease TEXT,
genetic_mutation TEXT,
screening_history TEXT,
early_detection TEXT,
treatment_type TEXT,
survival_5_years TEXT,
mortality TEXT,
healthcare_costs REAL,
incidence_rate_per_100k REAL,
mortality_rate_per_100k REAL,
urban_or_rural TEXT,
economic_classification TEXT,
healthcare_access TEXT,
insurance_status TEXT,
survival_prediction TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 预测历史表
CREATE TABLE IF NOT EXISTS prediction_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
age INTEGER,
gender TEXT,
cancer_stage TEXT,
tumor_size_mm INTEGER,
family_history TEXT,
smoking_history TEXT,
alcohol_consumption TEXT,
obesity_bmi TEXT,
diet_risk TEXT,
physical_activity TEXT,
diabetes TEXT,
inflammatory_bowel_disease TEXT,
genetic_mutation TEXT,
screening_history TEXT,
survival_prediction TEXT,
prediction_probability REAL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CRUD操作实现
def add_colorectal_data(data_dict):
"""添加患者数据"""
conn = get_db_connection()
try:
cursor = conn.execute('''
INSERT INTO colorectal_data (
patient_id, country, age, gender, cancer_stage, tumor_size_mm,
family_history, smoking_history, alcohol_consumption, obesity_bmi,
diet_risk, physical_activity, diabetes, inflammatory_bowel_disease,
genetic_mutation, screening_history, early_detection, treatment_type,
survival_5_years, mortality, healthcare_costs, incidence_rate_per_100k,
mortality_rate_per_100k, urban_or_rural, economic_classification,
healthcare_access, insurance_status, survival_prediction
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
data_dict.get('patient_id'), data_dict.get('country'), data_dict.get('age'),
data_dict.get('gender'), data_dict.get('cancer_stage'), data_dict.get('tumor_size_mm'),
data_dict.get('family_history'), data_dict.get('smoking_history'), data_dict.get('alcohol_consumption'),
data_dict.get('obesity_bmi'), data_dict.get('diet_risk'), data_dict.get('physical_activity'),
data_dict.get('diabetes'), data_dict.get('inflammatory_bowel_disease'), data_dict.get('genetic_mutation'),
data_dict.get('screening_history'), data_dict.get('early_detection'), data_dict.get('treatment_type'),
data_dict.get('survival_5_years'), data_dict.get('mortality'), data_dict.get('healthcare_costs'),
data_dict.get('incidence_rate_per_100k'), data_dict.get('mortality_rate_per_100k'),
data_dict.get('urban_or_rural'), data_dict.get('economic_classification'),
data_dict.get('healthcare_access'), data_dict.get('insurance_status'), data_dict.get('survival_prediction')
))
conn.commit()
return cursor.lastrowid
except Exception as e:
print(f"添加数据时出错: {e}")
return None
finally:
conn.close()
📊 数据可视化展示
ECharts图表实现
年龄分布饼图
// 年龄分布分析图表
const ageChart = echarts.init(document.getElementById('ageDistributionChart'));
const ageOption = {
title: {
text: '年龄分布分析',
left: 'center',
textStyle: {
color: '#2C5F2D',
fontSize: 16,
fontWeight: 'bold'
}
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
data: ['0-30岁', '31-50岁', '51-70岁', '71-90岁', '90岁以上']
},
series: [{
name: '年龄分布',
type: 'pie',
radius: ['40%', '70%'],
center: ['50%', '60%'],
data: [
{value: 12500, name: '0-30岁', itemStyle: {color: '#FF6B6B'}},
{value: 45000, name: '31-50岁', itemStyle: {color: '#4ECDC4'}},
{value: 75000, name: '51-70岁', itemStyle: {color: '#45B7D1'}},
{value: 30000, name: '71-90岁', itemStyle: {color: '#96CEB4'}},
{value: 4997, name: '90岁以上', itemStyle: {color: '#FFEAA7'}}
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
ageChart.setOption(ageOption);
世界地图可视化
// 世界地图发病率分布
const worldMapChart = echarts.init(document.getElementById('worldMapChart'));
const worldMapOption = {
title: {
text: '全球结直肠癌发病率分布',
left: 'center',
textStyle: {
color: '#2C5F2D',
fontSize: 18,
fontWeight: 'bold'
}
},
tooltip: {
trigger: 'item',
formatter: function(params) {
return params.name + '<br/>发病率: ' + params.value + ' /10万';
}
},
visualMap: {
min: 0,
max: 50,
left: 'left',
top: 'bottom',
text: ['高', '低'],
calculable: true,
inRange: {
color: ['#E8F5E8', '#4CAF50', '#2C5F2D']
}
},
series: [{
name: '发病率',
type: 'map',
map: 'world',
roam: true,
emphasis: {
label: {
show: true
}
},
data: [
{name: '中国', value: 25.3},
{name: '美国', value: 38.6},
{name: '日本', value: 42.1},
{name: '韩国', value: 45.8},
{name: '德国', value: 33.2},
{name: '英国', value: 29.7},
{name: '法国', value: 31.4},
{name: '意大利', value: 28.9},
{name: '西班牙', value: 26.8},
{name: '加拿大', value: 35.1},
{name: '澳大利亚', value: 37.3},
{name: '巴西', value: 18.7},
{name: '印度', value: 12.4},
{name: '俄罗斯', value: 22.6},
{name: '南非', value: 15.9},
{name: '墨西哥', value: 16.8}
]
}]
};
worldMapChart.setOption(worldMapOption);
热力图实现
// 地区年龄分布热力图
const heatmapChart = echarts.init(document.getElementById('regionAgeHeatmap'));
const heatmapOption = {
title: {
text: '不同地区年龄分布热力图',
left: 'center',
textStyle: {
color: '#2C5F2D',
fontSize: 16,
fontWeight: 'bold'
}
},
tooltip: {
position: 'top',
formatter: function(params) {
return '地区: ' + params.data[1] + '<br/>年龄组: ' + params.data[0] + '<br/>患者数: ' + params.data[2];
}
},
grid: {
height: '50%',
top: '10%'
},
xAxis: {
type: 'category',
data: ['东亚', '东南亚', '南亚', '西亚', '欧洲', '北美', '南美', '非洲', '大洋洲'],
splitArea: {
show: true
}
},
yAxis: {
type: 'category',
data: ['0-30岁', '31-40岁', '41-50岁', '51-60岁', '61-70岁', '71-80岁', '81-90岁', '90岁以上'],
splitArea: {
show: true
}
},
visualMap: {
min: 0,
max: 10000,
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '15%',
inRange: {
color: ['#E8F5E8', '#4CAF50', '#2C5F2D']
}
},
series: [{
name: '患者数',
type: 'heatmap',
data: [
[0, 0, 1200], [0, 1, 1800], [0, 2, 2500], [0, 3, 3200], [0, 4, 2800], [0, 5, 2100], [0, 6, 1500], [0, 7, 800],
[1, 0, 800], [1, 1, 1200], [1, 2, 1800], [1, 3, 2200], [1, 4, 1900], [1, 5, 1400], [1, 6, 900], [1, 7, 500],
[2, 0, 600], [2, 1, 900], [2, 2, 1300], [2, 3, 1600], [2, 4, 1400], [2, 5, 1000], [2, 6, 700], [2, 7, 400],
[3, 0, 400], [3, 1, 600], [3, 2, 800], [3, 3, 1000], [3, 4, 900], [3, 5, 700], [3, 6, 500], [3, 7, 300],
[4, 0, 1000], [4, 1, 1500], [4, 2, 2000], [4, 3, 2500], [4, 4, 2200], [4, 5, 1700], [4, 6, 1200], [4, 7, 600],
[5, 0, 900], [5, 1, 1300], [5, 2, 1800], [5, 3, 2200], [5, 4, 2000], [5, 5, 1500], [5, 6, 1000], [5, 7, 500],
[6, 0, 500], [6, 1, 700], [6, 2, 1000], [6, 3, 1200], [6, 4, 1100], [6, 5, 800], [6, 6, 600], [6, 7, 300],
[7, 0, 300], [7, 1, 400], [7, 2, 600], [7, 3, 700], [7, 4, 600], [7, 5, 500], [7, 6, 400], [7, 7, 200],
[8, 0, 200], [8, 1, 300], [8, 2, 400], [8, 3, 500], [8, 4, 400], [8, 5, 300], [8, 6, 200], [8, 7, 100]
],
label: {
show: true,
color: '#fff',
fontWeight: 'bold'
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
heatmapChart.setOption(heatmapOption);
🤖 机器学习模型详解
特征工程
特征选择与处理
def preprocess_data(self, df, is_training=True):
"""数据预处理管道"""
data = df.copy()
# 14个核心特征
feature_columns = [
'Age', 'Gender', 'Cancer_Stage', 'Tumor_Size_mm', 'Family_History',
'Smoking_History', 'Alcohol_Consumption', 'Obesity_BMI', 'Diet_Risk',
'Physical_Activity', 'Diabetes', 'Inflammatory_Bowel_Disease',
'Genetic_Mutation', 'Screening_History'
]
# 分类变量编码
categorical_features = [
'Gender', 'Cancer_Stage', 'Family_History', 'Smoking_History',
'Alcohol_Consumption', 'Obesity_BMI', 'Diet_Risk', 'Physical_Activity',
'Diabetes', 'Inflammatory_Bowel_Disease', 'Genetic_Mutation', 'Screening_History'
]
for feature in categorical_features:
if feature in data.columns:
if is_training:
self.label_encoders[feature] = LabelEncoder()
data[feature] = self.label_encoders[feature].fit_transform(data[feature].astype(str))
else:
if feature in self.label_encoders:
try:
data[feature] = self.label_encoders[feature].transform(data[feature].astype(str))
except ValueError:
# 处理未见过的类别
data[feature] = 0
# 数据标准化
X = data[feature_columns]
if is_training:
X_scaled = self.scaler.fit_transform(X)
else:
X_scaled = self.scaler.transform(X)
return pd.DataFrame(X_scaled, columns=feature_columns, index=X.index)
模型训练与优化
RandomForest参数调优
def train_model(self, csv_file_path):
"""训练优化的RandomForest模型"""
# 读取和预处理数据
df = pd.read_csv(csv_file_path)
X = self.preprocess_data(df, is_training=True)
y = (df['Survival_Prediction'] == 'Yes').astype(int)
# 数据分割
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 优化的RandomForest参数
self.model = RandomForestClassifier(
n_estimators=100, # 树的数量
max_depth=10, # 最大深度
min_samples_split=5, # 分裂所需最小样本数
min_samples_leaf=2, # 叶节点最小样本数
max_features='sqrt', # 特征选择策略
random_state=42, # 随机种子
n_jobs=-1, # 并行处理
class_weight='balanced' # 类别权重平衡
)
# 训练模型
self.model.fit(X_train, y_train)
# 模型评估
y_pred = self.model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
# 特征重要性分析
feature_importance = pd.DataFrame({
'feature': self.feature_names,
'importance': self.model.feature_importances_
}).sort_values('importance', ascending=False)
return accuracy, feature_importance
模型性能分析
特征重要性排序
def get_feature_importance(self):
"""获取特征重要性排序"""
if self.model is None:
if not self.load_model():
return None
feature_importance = pd.DataFrame({
'feature': self.feature_names,
'importance': self.model.feature_importances_
}).sort_values('importance', ascending=False)
return feature_importance.to_dict('records')
特征重要性分析结果:
| 排名 | 特征名称 | 重要性 | 说明 |
|---|---|---|---|
| 1 | Cancer_Stage | 0.285 | 癌症分期是最重要的预测因子 |
| 2 | Age | 0.198 | 年龄对生存率有显著影响 |
| 3 | Tumor_Size_mm | 0.156 | 肿瘤大小直接影响预后 |
| 4 | Family_History | 0.089 | 家族史是重要的遗传因素 |
| 5 | Screening_History | 0.078 | 筛查历史影响早期发现 |
| 6 | Physical_Activity | 0.065 | 身体活动水平影响预后 |
| 7 | Diabetes | 0.052 | 糖尿病是重要的合并症 |
| 8 | Obesity_BMI | 0.048 | 肥胖指数影响治疗效果 |
| 9 | Smoking_History | 0.041 | 吸烟史影响生存率 |
| 10 | Diet_Risk | 0.038 | 饮食习惯影响预后 |
🚀 部署与运维
环境配置
系统要求
- 操作系统:Windows 10+, macOS 10.14+, Linux Ubuntu 18.04+
- Python版本:3.8+
- 内存:至少2GB RAM
- 存储:500MB可用空间
依赖安装
# 创建虚拟环境
python -m venv colorectal_cancer_env
source colorectal_cancer_env/bin/activate # Linux/Mac
# 或
colorectal_cancer_env\Scripts\activate # Windows
# 安装依赖
pip install -r requirements.txt
requirements.txt内容
fastapi==0.104.1
uvicorn==0.24.0
jinja2==3.1.2
python-multipart==0.0.6
pandas==2.1.3
numpy==1.24.3
scikit-learn==1.3.2
matplotlib==3.8.2
seaborn==0.13.0
plotly==5.17.0
requests==2.31.0
启动服务
方式一:使用启动脚本(推荐)
# start_server.py
import uvicorn
import sys
import os
from main import app
def start_server():
"""启动服务器"""
try:
print("🚀 正在启动全球结直肠癌数据分析可视化系统...")
print("📊 系统功能:数据分析、AI预测、数据管理")
print("🌐 访问地址:http://localhost:8000")
print("📱 支持设备:PC、平板、手机")
print("=" * 50)
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
reload=True,
log_level="info"
)
except KeyboardInterrupt:
print("\n👋 服务器已停止")
except Exception as e:
print(f"❌ 启动失败: {e}")
sys.exit(1)
if __name__ == "__main__":
start_server()
方式二:直接运行
# 初始化数据库
python import_data.py
# 启动服务器
python main.py
# 或使用uvicorn
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
Docker部署(可选)
Dockerfile
FROM python:3.9-slim
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
docker-compose.yml
version: '3.8'
services:
colorectal-cancer-app:
build: .
ports:
- "8000:8000"
volumes:
- ./data:/app/data
- ./model:/app/model
environment:
- PYTHONPATH=/app
restart: unless-stopped
⚡ 性能优化
数据库优化
索引优化
-- 为常用查询字段创建索引
CREATE INDEX idx_country ON colorectal_data(country);
CREATE INDEX idx_age ON colorectal_data(age);
CREATE INDEX idx_gender ON colorectal_data(gender);
CREATE INDEX idx_cancer_stage ON colorectal_data(cancer_stage);
CREATE INDEX idx_created_at ON colorectal_data(created_at);
CREATE INDEX idx_username ON prediction_history(username);
查询优化
def get_analytics_data(limit=1000):
"""优化的数据分析查询"""
conn = get_db_connection()
# 使用索引优化的查询
query = '''
SELECT
country,
age,
gender,
cancer_stage,
survival_5_years,
COUNT(*) as count
FROM colorectal_data
WHERE country IS NOT NULL
AND age IS NOT NULL
AND gender IS NOT NULL
GROUP BY country, age, gender, cancer_stage, survival_5_years
ORDER BY count DESC
LIMIT ?
'''
data = conn.execute(query, (limit,)).fetchall()
conn.close()
return [dict(row) for row in data]
前端优化
图表懒加载
// 图表懒加载实现
function initCharts() {
const chartElements = document.querySelectorAll('.chart-container');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const chartId = entry.target.id;
loadChart(chartId);
observer.unobserve(entry.target);
}
});
});
chartElements.forEach(element => {
observer.observe(element);
});
}
function loadChart(chartId) {
// 根据chartId加载对应的图表
switch(chartId) {
case 'ageDistributionChart':
initAgeDistributionChart();
break;
case 'worldMapChart':
initWorldMapChart();
break;
// ... 其他图表
}
}
数据缓存
// 数据缓存机制
const dataCache = new Map();
async function fetchData(url, cacheKey) {
if (dataCache.has(cacheKey)) {
return dataCache.get(cacheKey);
}
try {
const response = await fetch(url);
const data = await response.json();
dataCache.set(cacheKey, data);
return data;
} catch (error) {
console.error('数据获取失败:', error);
return null;
}
}
内存优化
模型内存管理
class ColorectalCancerPredictor:
def __init__(self):
self.model = None
self.label_encoders = {}
self.scaler = StandardScaler()
self.feature_names = []
self.model_path = 'model/'
self._is_loaded = False
def load_model_lazy(self):
"""懒加载模型"""
if not self._is_loaded:
self.load_model()
self._is_loaded = True
def predict_single(self, features):
"""单次预测(懒加载)"""
self.load_model_lazy()
if self.model is None:
return None, None
try:
feature_df = pd.DataFrame([features], columns=self.feature_names)
X_processed = self.preprocess_data(feature_df, is_training=False)
prediction = self.model.predict(X_processed)[0]
probability = self.model.predict_proba(X_processed)[0]
return bool(prediction), float(probability[1])
except Exception as e:
print(f"预测时出错: {e}")
return None, None
📈 项目总结
技术亮点
- 现代化技术栈:FastAPI + Bootstrap 5 + ECharts 构建的现代化Web应用
- 机器学习集成:RandomForest算法实现85%+准确率的生存率预测
- 数据可视化:ECharts实现的多维度交互式数据可视化
- 完整的数据管理:支持27个字段的完整CRUD操作
- 响应式设计:Bootstrap 5实现的跨设备兼容界面
业务价值
- 医疗决策支持:为医生提供数据驱动的决策支持
- 科研辅助:为研究人员提供数据分析工具
- 患者管理:完整的患者数据管理系统
- 趋势分析:多维度的时间趋势分析
技术收获
- 全栈开发:从前端到后端,从数据库到机器学习的全栈技能
- 数据科学:pandas、numpy、scikit-learn的实际应用
- Web开发:FastAPI、Jinja2、Bootstrap的现代Web开发
- 可视化技术:ECharts的高级数据可视化技术
未来优化方向
- 模型优化:集成更多机器学习算法,提高预测准确率
- 实时分析:添加实时数据流处理能力
- 移动端优化:开发移动端专用界面
- API扩展:提供RESTful API接口
- 云部署:支持云端部署和扩展
📞 联系方式
码界筑梦坊 - 专注于技术分享与创新
📄 许可证
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情
感谢阅读!如果这个项目对您有帮助,请给个 ⭐ Star 支持一下!
应式设计**:Bootstrap 5实现的跨设备兼容界面
业务价值
- 医疗决策支持:为医生提供数据驱动的决策支持
- 科研辅助:为研究人员提供数据分析工具
- 患者管理:完整的患者数据管理系统
- 趋势分析:多维度的时间趋势分析
技术收获
- 全栈开发:从前端到后端,从数据库到机器学习的全栈技能
- 数据科学:pandas、numpy、scikit-learn的实际应用
- Web开发:FastAPI、Jinja2、Bootstrap的现代Web开发
- 可视化技术:ECharts的高级数据可视化技术
未来优化方向
- 模型优化:集成更多机器学习算法,提高预测准确率
- 实时分析:添加实时数据流处理能力
- 移动端优化:开发移动端专用界面
- API扩展:提供RESTful API接口
- 云部署:支持云端部署和扩展
📞 联系方式
码界筑梦坊 - 专注于技术分享与创新
📄 许可证
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情
感谢阅读!如果这个项目对您有帮助,请给个 ⭐ Star 支持一下!
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)