使用Python 和 Streamlit 构建的多维度游戏玩家数据分析

游戏玩家数据分析与可视化

概述

这是一个基于 PythonStreamlit 构建的多维度游戏玩家数据分析应用。项目旨在为游戏运营团队提供一个全面、交互式的数据分析工具,通过12个核心维度深度剖析玩家行为,帮助制定科学的运营策略,提升玩家留存和付费转化。

目标

  1. 数据洞察:从海量玩家数据中提取有价值的信息
  2. 用户分群:精细化识别不同类型玩家特征
  3. 预测分析:提前识别潜在流失风险和高价值用户
  4. 决策支持:基于数据提供可执行的运营建议

架构

技术栈全景

复制代码
┌─────────────────────────────────────────────┐
│         前端界面层 (UI Layer)                │
│  ┌─────────────────────────────────────┐    │
│  │  Streamlit + Custom CSS + Plotly    │    │
│  └─────────────────────────────────────┘    │
├─────────────────────────────────────────────┤
│          业务逻辑层 (Logic Layer)            │
│  ┌─────────────────────────────────────┐    │
│  │  Pandas + NumPy + Scikit-learn      │    │
│  │  + 数据分析算法 + 预测模型           │    │
│  └─────────────────────────────────────┘    │
├─────────────────────────────────────────────┤
│          数据处理层 (Data Layer)             │
│  ┌─────────────────────────────────────┐    │
│  │  CSV文件处理 + 数据预处理             │
│  │  + 特征工程 + 缓存机制               │
│  └─────────────────────────────────────┘    │
├─────────────────────────────────────────────┤
│          基础设施层 (Infrastructure)         │
│  ┌─────────────────────────────────────┐    │
│  │  Python 3.10+ + 依赖管理系统        │
│  │  + 开发环境配置                     │
│  └─────────────────────────────────────┘    │
└─────────────────────────────────────────────┘

详细技术栈配置

技术类别 具体组件 版本 主要用途
前端框架 Streamlit 1.28.0 构建交互式Web界面
数据处理 Pandas 2.1.4 数据加载、清洗、转换
数值计算 NumPy 1.24.3 数值运算、数组处理
可视化 Plotly 5.17.0 交互式图表、3D可视化
机器学习 Scikit-learn 1.3.2 聚类分析、预测模型
可选依赖 Seaborn 0.13.0 统计可视化(降级可用)
系统支持 Python 3.10+ 运行环境

结构设计

1. 原始数据字段 (12个维度)

字段名称 数据类型 说明 示例
用户ID Integer 玩家唯一标识 100001
玩家性别 String 性别信息 男/女
玩家年龄 Integer 实际年龄 27
所在区域 String 地理位置 华东/华南/华北
游戏段位 String 竞技水平 荣耀青铜/最强王者
日均时长 Float 平均每日游戏时长(小时) 3.9
累计消费 Float 历史总消费金额(元) 22.41
擅长位置 String 游戏角色偏好 坦克/刺客/辅助
综合胜率 Float 胜率(0-1) 0.483
KDA指数 Float 击杀/死亡/助攻综合评分 5.4
登录频率 String 活跃度指标 每天/每周3-5次
行为模式 String 玩家类型标识 竞技型/社交型

2. 衍生字段设计(通过特征工程生成)

特征工程架构
python 复制代码
# 数据预处理函数 - 特征工程核心
def preprocess_data(df):
    # 1. 离散化处理
    df['消费分段'] = pd.cut(df['累计消费'], bins=[0, 20, 100, float('inf')], 
                           labels=['低消费', '中消费', '高消费'])
    df['年龄分段'] = pd.cut(df['玩家年龄'], bins=[0, 18, 25, 30, 100],
                           labels=['青少年', '青年', '成年', '中老年'])
    
    # 2. 编码转换
    rank_order = ['荣耀青铜', '秩序白银', '尊贵铂金', '永恒钻石', '至尊星耀', '最强王者']
    df['段位等级'] = df['游戏段位'].map({r: i+1 for i, r in enumerate(rank_order)})
    
    # 3. 复合特征
    df['活跃度分数'] = (df['登录频率等级'] * 0.6 + 
                       df['日均时长'] / df['日均时长'].max() * 0.4)
    
    # 4. 分群标签
    df['活跃度分段'] = pd.qcut(df['活跃度分数'], q=[0, 0.33, 0.66, 1],
                              labels=['流失用户', '普通用户', '核心用户'])
    
    return df
衍生字段详情
衍生字段 生成方法 业务含义 数据类型
消费分段 pd.cut(累计消费) 玩家付费能力等级 Categorical
年龄分段 pd.cut(玩家年龄) 年龄段分布 Categorical
段位等级 有序编码映射 竞技水平量化 Integer
登录频率等级 频率编码 活跃度量化 Integer
活跃度分数 加权计算(0.6登录等级+0.4时长标准化) 综合活跃度评分 Float
活跃度分段 pd.qcut(活跃度分数) 活跃度分群标签 Categorical
技能分数 0.4段位等级+0.3 胜率100+0.3KDA标准化 综合技能评分 Float
技能分段 pd.qcut(技能分数) 技能水平分群 Categorical
流失风险 规则模型预测 流失可能性评分 Float
流失风险等级 pd.cut(流失风险) 流失风险等级 Categorical
付费潜力 规则模型预测 未来付费可能性 Categorical
预计晋升时间 规则模型预测 段位提升时间估计 Categorical
用户价值分 0.5消费+0.3活跃度+0.2*技能 综合价值评分 Float

功能详解

模块一:用户画像分析

1.1 人口统计画像
  • 性别分布:饼图展示男女比例
  • 年龄分段:条形图展示各年龄段人数
  • 区域分布:柱状图展示各地区用户数量
1.2 游戏能力画像
  • 段位分布:条形图展示各段位用户数
  • 位置偏好:饼图展示不同位置玩家比例
  • KDA分布:直方图展示技能水平
  • 胜率分布:直方图展示胜负情况
1.3 行为习惯画像
  • 登录频率:条形图展示活跃频率
  • 行为模式:饼图展示玩家类型
  • 日均时长:直方图展示游戏时长习惯
1.4 消费能力画像
  • 消费分段:饼图展示高/中/低消费比例
  • 累计消费:直方图展示消费金额分布

模块二:用户细分分析

2.1 价值分群
  • 高消费用户:累计消费>100元
  • 中消费用户:20元<累计消费≤100元
  • 低消费用户:累计消费≤20元
2.2 活跃度分群
  • 核心用户:活跃度分数前33%
  • 普通用户:活跃度分数中间34%
  • 流失用户:活跃度分数后33%
2.3 技能分群
  • 高手:技能分数前33%
  • 进阶玩家:技能分数中间34%
  • 新手:技能分数后33%
2.4 偏好分群
  • 基于擅长位置分析消费分布
  • 识别不同位置偏好的用户特征
2.5 行为分群
  • 按行为模式分析段位和消费分布
  • 识别竞技型、社交型、休闲型玩家特征

模块三:🔗 关联与相关性分析

3.1 消费驱动因素分析
  • 时长vs消费:散点图分析游戏时长与消费关系
  • 段位vs消费:箱线图分析不同段位消费分布
  • 胜率vs消费:散点图分析胜率与消费关联
3.2 活跃度影响因素
  • 年龄vs登录频率:热力图分析年龄与活跃度关系
  • 区域vs登录频率:热力图分析区域与活跃度关联
3.3 技能成长路径
  • 时长vsKDA:散点图分析游戏时长与技能关系
  • 段位vsKDA:箱线图分析不同段位技能水平
3.4 区域差异分析
  • 区域消费对比:柱状图展示各地区平均消费
  • 区域活跃度:柱状图展示各地区游戏时长
  • 区域段位分布:热力图分析各地区段位特征

模块四:预测性分析

4.1 用户流失预测模型
python 复制代码
def predict_churn_risk(row):
    """基于规则的流失风险预测"""
    login_score = {'每月几次': 3, '每周1-2次': 2, '每周3-5次': 1, '每天': 0}
    behavior_score = {'娱乐型': 1, '休闲型': 2, '社交型': 3, '收藏型': 2, '竞技型': 4}
    
    risk = (login_score.get(row['登录频率'], 2) * 0.4 +
            (1 if row['日均时长'] < 2 else 0) * 0.3 +
            behavior_score.get(row['行为模式'], 2) * 0.3)
    return min(risk, 3)
4.2 付费潜力预测
  • 高潜力:累计消费>100元
  • 中潜力:20元<累计消费≤100元
  • 低潜力:累计消费≤20元
4.3 段位晋升时间预测
  • 1-2周:KDA>4且胜率>0.55
  • 2-4周:KDA>3且胜率>0.5
  • 4-8周:其他情况

模块五:运营决策支持

5.1 高价值用户识别
  • TOP10用户:基于用户价值分排序
  • 价值分布:识别高价值用户特征
  • 专属福利策略:针对高价值用户制定个性化方案
5.2 流失预警干预
  • 高风险用户识别:流失风险等级=高风险
  • 召回策略:针对不同类型用户的召回方案
  • 个性化推送:基于行为模式的定向内容
5.3 匹配优化建议
  • 段位平衡算法:优化对战匹配机制
  • 技能权重调整:综合胜率、KDA、时长多维度
  • 新手保护机制:根据游戏时长调整匹配范围
5.4 内容推荐策略
  • 位置偏好推荐:基于擅长位置的个性化内容
  • 行为模式推荐:针对不同类型玩家的差异化推荐
  • 消费能力推荐:基于消费分段的商品推荐
5.5 定价策略分析
  • 区域差异定价:基于各地区平均消费水平
  • 分层定价模型:基础版/进阶版/豪华版策略
  • 促销活动优化:根据不同用户特征制定促销方案

模块六:可视化分析

6.1 用户分布分析
  • 区域热力图:展示各地区用户分布密度
  • 年龄/段位金字塔:金字塔图展示用户结构
6.2 趋势分析
  • 登录频率趋势:折线图展示活跃度变化
  • 日均时长分布:柱状图展示游戏时长趋势
6.3 对比分析
  • 性别消费对比:柱状图对比男女消费差异
  • 区域活跃度对比:柱状图对比各地区游戏时长
6.4 关联分析
  • 多维度散点图:时长vs消费、胜率vsKDA
  • 3D散点图:时长、消费、胜率三维关联分析
6.5 分群分析
  • 雷达图分群对比:各行为模式用户画像对比
  • 标准化对比图:多维度标准化后的对比分析

🔧 关键技术实现

1. 数据预处理优化

1.1 特征工程策略
python 复制代码
class FeatureEngineer:
    def __init__(self):
        self.rank_mapping = None
        self.login_mapping = None
        
    def fit(self, df):
        """学习特征转换规则"""
        # 段位有序编码
        rank_order = ['荣耀青铜', '秩序白银', '尊贵铂金', '永恒钻石', '至尊星耀', '最强王者']
        self.rank_mapping = {r: i+1 for i, r in enumerate(rank_order)}
        
        # 登录频率有序编码
        login_order = ['每月几次', '每周1-2次', '每周3-5次', '每天']
        self.login_mapping = {l: i+1 for i, l in enumerate(login_order)}
        
    def transform(self, df):
        """应用特征转换"""
        df_transformed = df.copy()
        
        # 离散化特征
        df_transformed['消费分段'] = pd.cut(df['累计消费'], 
                                          bins=[0, 20, 100, float('inf')],
                                          labels=['低消费', '中消费', '高消费'])
        
        # 有序编码
        df_transformed['段位等级'] = df['游戏段位'].map(self.rank_mapping)
        df_transformed['登录频率等级'] = df['登录频率'].map(self.login_mapping)
        
        # 复合特征
        df_transformed = self._create_composite_features(df_transformed)
        
        return df_transformed
1.2 缓存机制优化
python 复制代码
@st.cache_data(ttl=3600, max_entries=5)
def load_data(file):
    """带缓存的数据加载"""
    df = pd.read_csv(file)
    
    # 数据类型转换
    numeric_columns = ['日均时长', '累计消费', '综合胜率', 'KDA指数', '玩家年龄']
    for col in numeric_columns:
        df[col] = pd.to_numeric(df[col], errors='coerce')
    
    return df

2. 可视化架构

2.1 响应式图表系统
python 复制代码
class ResponsiveChartSystem:
    def __init__(self):
        self.theme = 'plotly_white'
        
    def create_scatter_matrix(self, df, dimensions, color_col=None):
        """创建响应式散点矩阵"""
        fig = px.scatter_matrix(df,
                                dimensions=dimensions,
                                color=color_col,
                                title="多维关联分析矩阵",
                                opacity=0.7,
                                template=self.theme)
        
        # 自适应调整
        fig.update_traces(diagonal_visible=True)
        fig.update_layout(height=800)
        
        return fig
    
    def create_animated_timeline(self, df, time_col, value_cols):
        """创建动画时间线"""
        fig = px.line(df, x=time_col, y=value_cols,
                     title="时间趋势分析",
                     template=self.theme)
        
        fig.update_layout(
            hovermode='x unified',
            xaxis=dict(title="时间轴"),
            yaxis=dict(title="指标值")
        )
        
        return fig
2.2 交互式组件
python 复制代码
class InteractiveComponents:
    def __init__(self):
        self.filters = {}
        
    def create_dynamic_filter(self, df, column_name):
        """创建动态过滤器"""
        unique_values = df[column_name].unique()
        
        filter_widget = st.multiselect(
            f"筛选 {column_name}",
            options=unique_values,
            default=unique_values[:5] if len(unique_values) > 5 else unique_values
        )
        
        self.filters[column_name] = filter_widget
        return filter_widget
    
    def apply_filters(self, df):
        """应用过滤器"""
        filtered_df = df.copy()
        
        for col, values in self.filters.items():
            if values:
                filtered_df = filtered_df[filtered_df[col].isin(values)]
        
        return filtered_df

3. 机器学习应用

3.1 K-means聚类分析
python 复制代码
class PlayerClustering:
    def __init__(self, n_clusters=4):
        self.n_clusters = n_clusters
        self.scaler = StandardScaler()
        self.kmeans = KMeans(n_clusters=n_clusters, random_state=42)
        self.cluster_labels = None
        
    def fit_transform(self, df):
        """聚类分析"""
        # 特征选择
        features = ['段位等级', '日均时长', '累计消费', '综合胜率', 'KDA指数']
        X = df[features].fillna(0)
        
        # 标准化
        X_scaled = self.scaler.fit_transform(X)
        
        # K-means聚类
        self.cluster_labels = self.kmeans.fit_predict(X_scaled)
        
        # 分析聚类特征
        self._analyze_clusters(df, self.cluster_labels)
        
        return self.cluster_labels
3.2 预测模型架构
python 复制代码
class PredictiveModels:
    def __init__(self):
        self.churn_model = RandomForestClassifier()
        self.value_model = RandomForestRegressor()
        
    def train_churn_model(self, X_train, y_train):
        """训练流失预测模型"""
        X_train_encoded = self._encode_features(X_train)
        self.churn_model.fit(X_train_encoded, y_train)
        
        # 模型评估
        scores = cross_val_score(self.churn_model, X_train_encoded, y_train, cv=5)
        return scores.mean()
    
    def predict_user_value(self, user_features):
        """预测用户价值"""
        return self.value_model.predict([user_features])[0]

UI/UX 设计架构

1. 视觉设计系统

1.1 色彩体系
css 复制代码
/* 主色调 - 游戏科技感 */
:root {
  --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  --success-gradient: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
  --warning-gradient: linear-gradient(135deg, #f39c12 0%, #e74c3c 100%);
  --info-gradient: linear-gradient(135deg, #3498db 0%, #2c3e50 100%);
}
1.2 组件设计规范
python 复制代码
class UIConstants:
    # 字体系统
    FONT_PRIMARY = "'Segoe UI', 'Microsoft YaHei', sans-serif"
    HEADER_FONT_SIZE = "3rem"
    SECTION_FONT_SIZE = "1.8rem"
    
    # 间距系统
    SPACING_UNIT = "15px"
    SECTION_MARGIN = "25px"
    CARD_PADDING = "20px"
    
    # 圆角系统  
    BORDER_RADIUS_SM = "10px"
    BORDER_RADIUS_MD = "15px"
    BORDER_RADIUS_LG = "20px"

2. 布局系统

2.1 响应式布局
python 复制代码
class LayoutManager:
    def __init__(self):
        self.breakpoints = {
            'xs': 576,
            'sm': 768,
            'md': 992,
            'lg': 1200
        }
    
    def create_responsive_columns(self, num_cols):
        """创建响应式列布局"""
        col_widths = [f"{100/num_cols}%" for _ in range(num_cols)]
        return st.columns(col_widths)
    
    def adaptive_grid(self, items, cols_per_row=3):
        """自适应网格布局"""
        rows = (len(items) + cols_per_row - 1) // cols_per_row
        
        for row in range(rows):
            cols = st.columns(cols_per_row)
            start_idx = row * cols_per_row
            end_idx = min(start_idx + cols_per_row, len(items))
            
            for i, item in enumerate(items[start_idx:end_idx]):
                with cols[i]:
                    # 渲染项目
                    pass

3. 交互设计

3.1 用户流设计
复制代码
用户流程:
1. 打开应用 → 2. 上传数据 → 3. 查看总览指标 → 4. 选择分析模块
   ↓
5. 交互式分析 → 6. 查看可视化 → 7. 获取建议 → 8. 导出结果
3.2 反馈机制
python 复制代码
class FeedbackSystem:
    def show_loading_state(self):
        """显示加载状态"""
        with st.spinner("正在处理数据..."):
            # 执行耗时操作
            pass
    
    def show_progress_bar(self, current, total, label="进度"):
        """显示进度条"""
        progress = current / total
        st.progress(progress, text=f"{label}: {current}/{total}")
    
    def show_notification(self, message, level="info"):
        """显示通知"""
        if level == "success":
            st.success(message)
        elif level == "warning":
            st.warning(message)
        elif level == "error":
            st.error(message)
        else:
            st.info(message)

部署

1. 环境配置

1.1 依赖管理
bash 复制代码
# requirements.txt 详细说明
streamlit==1.28.0          # 核心Web框架
pandas==2.1.4              # 数据处理
numpy==1.24.3              # 数值计算
plotly==5.17.0             # 交互式可视化
scikit-learn==1.3.2        # 机器学习
seaborn==0.13.0            # 统计可视化(可选)

# 环境设置脚本
python -m venv venv
source venv/bin/activate   # Linux/Mac
venv\Scripts\activate      # Windows
pip install -r requirements.txt
1.2 配置管理
python 复制代码
# config.py
import os
from pathlib import Path

class AppConfig:
    # 路径配置
    BASE_DIR = Path(__file__).parent
    DATA_DIR = BASE_DIR / "data"
    
    # 应用配置
    APP_TITLE = "游戏玩家数据分析平台"
    APP_ICON = "🎮"
    LAYOUT = "wide"
    
    # 数据处理配置
    CACHE_TTL = 3600  # 缓存时间(秒)
    MAX_ROWS = 10000  # 最大处理行数
    
    @classmethod
    def setup_directories(cls):
        """创建必要的目录"""
        os.makedirs(cls.DATA_DIR, exist_ok=True)

2. 性能优化

2.1 数据缓存策略
python 复制代码
class CacheManager:
    def __init__(self, ttl=3600):
        self.cache = {}
        self.ttl = ttl
        
    def get_or_compute(self, key, compute_func):
        """缓存或计算数据"""
        if key in self.cache:
            cached_item = self.cache[key]
            if time.time() - cached_item['timestamp'] < self.ttl:
                return cached_item['data']
        
        # 计算并缓存
        data = compute_func()
        self.cache[key] = {
            'data': data,
            'timestamp': time.time()
        }
        return data
2.2 内存优化
python 复制代码
class MemoryOptimizer:
    @staticmethod
    def optimize_dataframe(df):
        """优化DataFrame内存使用"""
        df_optimized = df.copy()
        
        # 数值类型优化
        for col in df.select_dtypes(include=['int64']).columns:
            df_optimized[col] = pd.to_numeric(df[col], downcast='integer')
        
        # 字符串类型优化
        for col in df.select_dtypes(include=['object']).columns:
            df_optimized[col] = df[col].astype('category')
        
        return df_optimized

3. 监控与日志

3.1 日志系统
python 复制代码
import logging

class LoggingSystem:
    def __init__(self, log_level=logging.INFO):
        logging.basicConfig(
            level=log_level,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('app.log'),
                logging.StreamHandler()
            ]
        )
        
        self.logger = logging.getLogger(__name__)
    
    def log_performance(self, operation, duration):
        """记录性能日志"""
        self.logger.info(f"{operation} 完成,耗时: {duration:.2f}秒")
    
    def log_data_stats(self, df):
        """记录数据统计日志"""
        self.logger.info(f"数据形状: {df.shape}")
        self.logger.info(f"列: {list(df.columns)}")
3.2 监控指标
python 复制代码
class PerformanceMonitor:
    def __init__(self):
        self.metrics = {
            'data_loading_time': [],
            'preprocessing_time': [],
            'analysis_time': []
        }
    
    def track_performance(self, metric_name, duration):
        """跟踪性能指标"""
        if metric_name in self.metrics:
            self.metrics[metric_name].append(duration)
            
            # 记录统计信息
            avg_time = np.mean(self.metrics[metric_name])
            self._log_metric(metric_name, duration, avg_time)
    
    def get_performance_report(self):
        """生成性能报告"""
        report = {}
        for metric, values in self.metrics.items():
            if values:
                report[metric] = {
                    'count': len(values),
                    'avg': np.mean(values),
                    'min': np.min(values),
                    'max': np.max(values)
                }
        return report

代码

复制代码
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.cluster import KMeans
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')

# 可选导入seaborn
try:
    import seaborn as sns
    seaborn_available = True
except ImportError:
    seaborn_available = False
    # 提供一个替代的sns模块占位符
    class SnsStub:
        def __getattr__(self, name):
            def stub_function(*args, **kwargs):
                # 静默返回None或空值
                return None
            return stub_function
    sns = SnsStub()

# 页面配置
st.set_page_config(page_title="游戏玩家数据分析平台", page_icon="🎮", layout="wide")

# 自定义CSS
st.markdown("""
<style>
    .main-header {
        font-size: 3rem;
        font-weight: 800;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        text-align: center;
        padding: 30px 0;
        margin-bottom: 20px;
    }
    .metric-card {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        padding: 20px;
        border-radius: 15px;
        color: white;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
        transition: transform 0.3s ease;
    }
    .metric-card:hover {
        transform: translateY(-5px);
    }
    .stMetric [data-baseweb="metric-label"] {
        color: white;
        font-weight: 600;
        font-size: 0.9rem;
        opacity: 0.9;
    }
    .stMetric [data-baseweb="metric-value"] {
        color: white;
        font-size: 2.2rem;
        font-weight: 700;
    }
    .section-header {
        font-size: 1.8rem;
        font-weight: 700;
        color: #2c3e50;
        margin: 25px 0 15px 0;
        padding-bottom: 10px;
        border-bottom: 3px solid #3498db;
    }
    .info-card {
        background: linear-gradient(135deg, #3498db 0%, #2c3e50 100%);
        padding: 25px;
        border-radius: 15px;
        color: white;
        margin: 15px 0;
        box-shadow: 0 4px 15px rgba(52, 152, 219, 0.2);
    }
    .warning-card {
        background: linear-gradient(135deg, #f39c12 0%, #e74c3c 100%);
        padding: 25px;
        border-radius: 15px;
        color: white;
        margin: 15px 0;
        box-shadow: 0 4px 15px rgba(243, 156, 18, 0.2);
    }
    .success-card {
        background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
        padding: 25px;
        border-radius: 15px;
        color: white;
        margin: 15px 0;
        box-shadow: 0 4px 15px rgba(46, 204, 113, 0.2);
    }
    .sidebar .sidebar-content {
        background: linear-gradient(180deg, #2c3e50 0%, #1a252f 100%);
    }
    .stSelectbox, .stRadio, .stExpander {
        margin-bottom: 15px;
    }
    .stExpander > div {
        border-radius: 10px !important;
        border: 1px solid #e0e0e0;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
    }
    .stTab {
        margin-top: 20px;
    }
    .feature-icon {
        font-size: 2.5rem;
        margin-bottom: 10px;
    }
    .feature-title {
        font-size: 1.3rem;
        font-weight: 600;
        margin-bottom: 10px;
    }
    .feature-description {
        font-size: 0.95rem;
        color: #666;
        line-height: 1.5;
    }
</style>
""", unsafe_allow_html=True)

# 数据加载与处理
@st.cache_data
def load_data(file):
    df = pd.read_csv(file)
    df['日均时长'] = pd.to_numeric(df['日均时长'], errors='coerce')
    df['累计消费'] = pd.to_numeric(df['累计消费'], errors='coerce')
    df['综合胜率'] = pd.to_numeric(df['综合胜率'], errors='coerce')
    df['KDA指数'] = pd.to_numeric(df['KDA指数'], errors='coerce')
    df['玩家年龄'] = pd.to_numeric(df['玩家年龄'], errors='coerce')
    return df

@st.cache_data
def preprocess_data(df):
    df_processed = df.copy()

    # 段位编码
    rank_order = ['荣耀青铜', '秩序白银', '尊贵铂金', '永恒钻石', '至尊星耀', '最强王者']
    df_processed['段位等级'] = df_processed['游戏段位'].map({r: i+1 for i, r in enumerate(rank_order)})

    # 登录频率编码
    login_order = ['每月几次', '每周1-2次', '每周3-5次', '每天']
    df_processed['登录频率等级'] = df_processed['登录频率'].map({l: i+1 for i, l in enumerate(login_order)})

    # 年龄分段
    df_processed['年龄分段'] = pd.cut(df_processed['玩家年龄'], 
                                       bins=[0, 18, 25, 30, 100], 
                                       labels=['青少年', '青年', '成年', '中老年'])

    # 消费分段 - 在预处理阶段创建,确保所有函数都能访问
    df_processed['消费分段'] = pd.cut(df_processed['累计消费'],
                                      bins=[0, 20, 100, float('inf')],
                                      labels=['低消费', '中消费', '高消费'])

    # 时长分段
    df_processed['时长分段'] = pd.cut(df_processed['日均时长'],
                                     bins=[0, 2, 4, 6, float('inf')],
                                     labels=['0-2小时', '2-4小时', '4-6小时', '6+小时'])

    # 活跃度分数 - 在预处理阶段计算
    df_processed['活跃度分数'] = (
        df_processed['登录频率等级'] * 0.6 +
        (df_processed['日均时长'] / df_processed['日均时长'].max()) * 0.4
    )

    # 活跃度分段
    df_processed['活跃度分段'] = pd.qcut(df_processed['活跃度分数'],
                                        q=[0, 0.33, 0.66, 1],
                                        labels=['流失用户', '普通用户', '核心用户'])

    # 技能分数
    df_processed['技能分数'] = (
        df_processed['段位等级'] * 0.4 +
        df_processed['综合胜率'] * 100 * 0.3 +
        (df_processed['KDA指数'] / df_processed['KDA指数'].max()) * 30
    )

    # 技能分段
    df_processed['技能分段'] = pd.qcut(df_processed['技能分数'],
                                      q=[0, 0.33, 0.66, 1],
                                      labels=['新手', '进阶', '高手'])

    return df_processed

def calculate_metrics(df):
    metrics = {
        '总玩家数': len(df),
        '平均年龄': round(df['玩家年龄'].mean(), 1),
        '平均日均时长': round(df['日均时长'].mean(), 1),
        '总累计消费': round(df['累计消费'].sum(), 2),
        '平均累计消费': round(df['累计消费'].mean(), 2),
        '平均胜率': round(df['综合胜率'].mean() * 100, 1),
        '平均KDA': round(df['KDA指数'].mean(), 1),
    }
    return metrics

def predict_churn_risk(row):
    """预测流失风险评分"""
    login_score = {'每月几次': 3, '每周1-2次': 2, '每周3-5次': 1, '每天': 0}
    behavior_score = {'娱乐型': 1, '休闲型': 2, '社交型': 3, '收藏型': 2, '竞技型': 4}

    risk = (login_score.get(row['登录频率'], 2) * 0.4 +
            (1 if row['日均时长'] < 2 else 0) * 0.3 +
            behavior_score.get(row['行为模式'], 2) * 0.3)
    return min(risk, 3)

def predict_pay_potential(row):
    """预测付费潜力"""
    if row['累计消费'] > 100:
        return '高'
    elif row['累计消费'] > 20:
        return '中'
    else:
        return '低'

def predict_promotion_time(row):
    """预测段位晋升时间"""
    if row['游戏段位'] == '最强王者':
        return '已达巅峰'
    elif row['KDA指数'] > 4 and row['综合胜率'] > 0.55:
        return '1-2周'
    elif row['KDA指数'] > 3 and row['综合胜率'] > 0.5:
        return '2-4周'
    else:
        return '4-8周'

# 用户画像分析
def user_profile_analysis(df, df_processed):
    st.markdown("## 📊 用户画像分析")

    # 1. 人口统计画像
    with st.expander("👥 人口统计画像", expanded=True):
        col1, col2, col3 = st.columns(3)

        with col1:
            gender_dist = df['玩家性别'].value_counts()
            fig_gender = px.pie(gender_dist, values=gender_dist.values, names=gender_dist.index,
                                 title='玩家性别分布', hole=0.5,
                                 color_discrete_sequence=px.colors.qualitative.Set3)
            st.plotly_chart(fig_gender, use_container_width=True)

        with col2:
            age_dist = df_processed['年龄分段'].value_counts().sort_index()
            fig_age = px.bar(age_dist, x=age_dist.index, y=age_dist.values,
                            title='年龄分段分布',
                            labels={'x': '年龄段', 'y': '人数'},
                            color=age_dist.values,
                            color_continuous_scale='Blues')
            st.plotly_chart(fig_age, use_container_width=True)

        with col3:
            region_dist = df['所在区域'].value_counts()
            fig_region = px.bar(region_dist, x=region_dist.index, y=region_dist.values,
                               title='区域分布',
                               labels={'x': '区域', 'y': '人数'},
                               color=region_dist.values,
                               color_continuous_scale='Viridis')
            st.plotly_chart(fig_region, use_container_width=True)

    # 2. 游戏能力画像
    with st.expander("⚔️ 游戏能力画像", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            rank_dist = df['游戏段位'].value_counts().sort_index()
            fig_rank = px.bar(rank_dist, x=rank_dist.index, y=rank_dist.values,
                             title='段位分布',
                             labels={'x': '段位', 'y': '人数'},
                             color=rank_dist.values,
                             color_continuous_scale='RdYlGn_r')
            fig_rank.update_xaxes(tickangle=45)
            st.plotly_chart(fig_rank, use_container_width=True)

        with col2:
            position_dist = df['擅长位置'].value_counts()
            fig_position = px.pie(position_dist, values=position_dist.values, names=position_dist.index,
                                  title='擅长位置分布', hole=0.4,
                                  color_discrete_sequence=px.colors.qualitative.Pastel)
            st.plotly_chart(fig_position, use_container_width=True)

        # KDA和胜率分布
        col1, col2 = st.columns(2)
        with col1:
            fig_kda = px.histogram(df, x='KDA指数', nbins=50,
                                  title='KDA指数分布',
                                  color_discrete_sequence=['#3498db'])
            st.plotly_chart(fig_kda, use_container_width=True)

        with col2:
            fig_winrate = px.histogram(df, x='综合胜率', nbins=50,
                                      title='综合胜率分布',
                                      color_discrete_sequence=['#2ecc71'])
            st.plotly_chart(fig_winrate, use_container_width=True)

    # 3. 行为习惯画像
    with st.expander("🎯 行为习惯画像", expanded=True):
        col1, col2, col3 = st.columns(3)

        with col1:
            login_dist = df['登录频率'].value_counts()
            login_order = ['每天', '每周3-5次', '每周1-2次', '每月几次']
            login_dist = login_dist.reindex(login_order)
            fig_login = px.bar(login_dist, x=login_dist.index, y=login_dist.values,
                              title='登录频率分布',
                              labels={'x': '登录频率', 'y': '人数'},
                              color=login_dist.values,
                              color_continuous_scale='YlOrRd')
            st.plotly_chart(fig_login, use_container_width=True)

        with col2:
            behavior_dist = df['行为模式'].value_counts()
            fig_behavior = px.pie(behavior_dist, values=behavior_dist.values, names=behavior_dist.index,
                                  title='行为模式分布', hole=0.5,
                                  color_discrete_sequence=px.colors.qualitative.Bold)
            st.plotly_chart(fig_behavior, use_container_width=True)

        with col3:
            fig_duration = px.histogram(df, x='日均时长', nbins=50,
                                       title='日均时长分布',
                                       color_discrete_sequence=['#9b59b6'])
            st.plotly_chart(fig_duration, use_container_width=True)

    # 4. 消费能力画像
    with st.expander("💰 消费能力画像", expanded=True):
        col1, col2 = st.columns(2)

        # 直接使用预处理阶段创建的消费分段
        spend_dist = df_processed['消费分段'].value_counts()

        with col1:
            fig_spend = px.pie(spend_dist, values=spend_dist.values, names=spend_dist.index,
                              title='消费能力分布', hole=0.5,
                              color_discrete_sequence=['#95a5a6', '#f39c12', '#e74c3c'])
            st.plotly_chart(fig_spend, use_container_width=True)

        with col2:
            fig_spend_hist = px.histogram(df, x='累计消费', nbins=50,
                                          title='累计消费金额分布',
                                          color_discrete_sequence=['#16a085'])
            st.plotly_chart(fig_spend_hist, use_container_width=True)

# 用户细分分析
def segmentation_analysis(df, df_processed):
    st.markdown("## 🎯 用户细分/分群分析")

    # 1. 按价值分群
    with st.expander("💎 按价值分群", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            spend_segment = df_processed['消费分段'].value_counts()
            fig_spend_seg = px.bar(spend_segment, x=spend_segment.index, y=spend_segment.values,
                                   title='价值分群(按累计消费)',
                                   labels={'x': '消费级别', 'y': '人数'},
                                   color=spend_segment.index,
                                   color_discrete_map={'低消费': '#95a5a6', '中消费': '#f39c12', '高消费': '#e74c3c'})
            st.plotly_chart(fig_spend_seg, use_container_width=True)

        with col2:
            # 高价值用户特征分析
            high_value = df_processed[df_processed['消费分段'] == '高消费']
            if len(high_value) > 0:
                st.markdown("### 高价值用户特征")
                col1, col2, col3 = st.columns(3)
                with col1:
                    st.metric("人数", len(high_value))
                with col2:
                    st.metric("平均胜率", f"{high_value['综合胜率'].mean()*100:.1f}%")
                with col3:
                    st.metric("平均KDA", f"{high_value['KDA指数'].mean():.1f}")

    # 2. 按活跃度分群
    with st.expander("🔥 按活跃度分群", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            active_dist = df_processed['活跃度分段'].value_counts()
            fig_active = px.bar(active_dist, x=active_dist.index, y=active_dist.values,
                               title='活跃度分群',
                               labels={'x': '活跃度级别', 'y': '人数'},
                               color=active_dist.values,
                               color_continuous_scale='RdYlGn')
            st.plotly_chart(fig_active, use_container_width=True)

        with col2:
            # 活跃度与消费关系
            fig_active_spend = px.box(df_processed, x='活跃度分段', y='累计消费',
                                     title='不同活跃度用户的消费分布',
                                     color='活跃度分段')
            st.plotly_chart(fig_active_spend, use_container_width=True)

    # 3. 按技能分群
    with st.expander("🎮 按技能分群", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            skill_dist = df_processed['技能分段'].value_counts()
            fig_skill = px.pie(skill_dist, values=skill_dist.values, names=skill_dist.index,
                              title='技能水平分群', hole=0.5,
                              color_discrete_sequence=['#3498db', '#f39c12', '#e74c3c'])
            st.plotly_chart(fig_skill, use_container_width=True)

        with col2:
            # 技能与活跃度关系
            fig_skill_active = px.scatter(df_processed, x='技能分数', y='活跃度分数',
                                          color='技能分段',
                                          title='技能分数 vs 活跃度分数',
                                          labels={'技能分数': '技能分数', '活跃度分数': '活跃度分数'},
                                          hover_data=['游戏段位', '综合胜率'])
            st.plotly_chart(fig_skill_active, use_container_width=True)

    # 4. 按偏好分群
    with st.expander("⭐ 按偏好分群", expanded=True):
        # 确保df_processed中有消费分段字段
        if '消费分段' in df_processed.columns:
            # 创建一个包含擅长位置和消费分段的DataFrame用于分组
            temp_df = df_processed[['擅长位置', '消费分段']].copy()
            position_analysis = temp_df.groupby(['擅长位置', '消费分段']).size().unstack(fill_value=0)

            fig_position_spend = px.bar(position_analysis.reset_index().melt(id_vars=['擅长位置'],
                                                                              var_name='消费级别',
                                                                              value_name='人数'),
                                         x='擅长位置', y='人数', color='消费级别',
                                         title='不同位置偏好的消费分布',
                                         barmode='stack',
                                         color_discrete_map={'低消费': '#95a5a6', '中消费': '#f39c12', '高消费': '#e74c3c'})
            st.plotly_chart(fig_position_spend, use_container_width=True)
        else:
            st.warning("消费分段字段不存在,无法进行偏好分群分析")

    # 5. 按行为分群
    with st.expander("🎭 按行为分群", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            behavior_rank = df.groupby(['行为模式', '游戏段位']).size().unstack(fill_value=0)
            fig_behavior_rank = px.bar(behavior_rank.reset_index().melt(id_vars=['行为模式'],
                                                                         var_name='段位',
                                                                         value_name='人数'),
                                      x='行为模式', y='人数', color='段位',
                                      title='不同行为模式的段位分布',
                                      barmode='stack')
            st.plotly_chart(fig_behavior_rank, use_container_width=True)

        with col2:
            # 确保df_processed中有消费分段字段
            if '消费分段' in df_processed.columns:
                # 创建一个包含行为模式和消费分段的DataFrame用于分组
                temp_df = df_processed[['行为模式', '消费分段']].copy()
                behavior_spend = temp_df.groupby(['行为模式', '消费分段']).size().unstack(fill_value=0)
                fig_behavior_spend = px.bar(behavior_spend.reset_index().melt(id_vars=['行为模式'],
                                                                               var_name='消费级别',
                                                                               value_name='人数'),
                                           x='行为模式', y='人数', color='消费级别',
                                           title='不同行为模式的消费分布',
                                           barmode='stack',
                                           color_discrete_map={'低消费': '#95a5a6', '中消费': '#f39c12', '高消费': '#e74c3c'})
                st.plotly_chart(fig_behavior_spend, use_container_width=True)
            else:
                st.warning("消费分段字段不存在,无法进行行为模式的消费分布分析")

# 关联与相关性分析
def correlation_analysis(df, df_processed):
    st.markdown("## 🔗 关联与相关性分析")

    # 1. 消费驱动因素
    with st.expander("💰 消费驱动因素分析", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            # 创建一个包含所需字段的DataFrame用于散点图
            scatter_df = df_processed[['日均时长', '累计消费']].copy()
            if '消费分段' in df_processed.columns:
                scatter_df['消费分段'] = df_processed['消费分段']
                fig_spend_duration = px.scatter(scatter_df, x='日均时长', y='累计消费',
                                               title='日均时长 vs 累计消费',
                                               color='消费分段',
                                               labels={'日均时长': '日均时长(小时)', '累计消费': '累计消费(元)'})
            else:
                fig_spend_duration = px.scatter(scatter_df, x='日均时长', y='累计消费',
                                               title='日均时长 vs 累计消费',
                                               labels={'日均时长': '日均时长(小时)', '累计消费': '累计消费(元)'})
            st.plotly_chart(fig_spend_duration, use_container_width=True)

        with col2:
            fig_spend_rank = px.box(df, x='游戏段位', y='累计消费',
                                   title='不同段位的消费分布',
                                   labels={'游戏段位': '段位', '累计消费': '累计消费(元)'})
            fig_spend_rank.update_xaxes(tickangle=45)
            st.plotly_chart(fig_spend_rank, use_container_width=True)

        with col1:
            fig_spend_winrate = px.scatter(df, x='综合胜率', y='累计消费',
                                          title='综合胜率 vs 累计消费',
                                          labels={'综合胜率': '胜率', '累计消费': '累计消费(元)'})
            st.plotly_chart(fig_spend_winrate, use_container_width=True)

    # 2. 活跃度影响因素
    with st.expander("📊 活跃度影响因素分析", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            login_age = df.groupby(['玩家年龄', '登录频率']).size().unstack(fill_value=0)
            login_age.columns.name = '登录频率'
            fig_login_age = px.imshow(login_age.values,
                                     x=login_age.columns,
                                     y=login_age.index,
                                     title='年龄 vs 登录频率热力图',
                                     labels=dict(x="登录频率", y="年龄", color="人数"),
                                     aspect="auto")
            st.plotly_chart(fig_login_age, use_container_width=True)

        with col2:
            login_region = df.groupby(['所在区域', '登录频率']).size().unstack(fill_value=0)
            login_region.columns.name = '登录频率'
            fig_login_region = px.imshow(login_region.values,
                                        x=login_region.columns,
                                        y=login_region.index,
                                        title='区域 vs 登录频率热力图',
                                        labels=dict(x="登录频率", y="区域", color="人数"))
            st.plotly_chart(fig_login_region, use_container_width=True)

    # 3. 技能成长路径
    with st.expander("📈 技能成长路径分析", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            fig_kda_duration = px.scatter(df, x='日均时长', y='KDA指数',
                                        title='日均时长 vs KDA指数',
                                        color='游戏段位',
                                        labels={'日均时长': '日均时长(小时)', 'KDA指数': 'KDA指数'})
            st.plotly_chart(fig_kda_duration, use_container_width=True)

        with col2:
            fig_kda_rank = px.box(df, x='游戏段位', y='KDA指数',
                                title='不同段位的KDA分布',
                                labels={'游戏段位': '段位', 'KDA指数': 'KDA指数'})
            fig_kda_rank.update_xaxes(tickangle=45)
            st.plotly_chart(fig_kda_rank, use_container_width=True)

    # 4. 区域差异分析
    with st.expander("🗺️ 区域差异分析", expanded=True):
        col1, col2, col3 = st.columns(3)

        with col1:
            region_spend = df.groupby('所在区域')['累计消费'].mean().sort_values(ascending=False)
            fig_region_spend = px.bar(x=region_spend.index, y=region_spend.values,
                                     title='各区域平均消费',
                                     labels={'x': '区域', 'y': '平均消费(元)'},
                                     color=region_spend.values,
                                     color_continuous_scale='Plasma')
            st.plotly_chart(fig_region_spend, use_container_width=True)

        with col2:
            region_active = df_processed.groupby('所在区域')['日均时长'].mean().sort_values(ascending=False)
            fig_region_active = px.bar(x=region_active.index, y=region_active.values,
                                      title='各区域平均日均时长',
                                      labels={'x': '区域', 'y': '平均时长(小时)'},
                                      color=region_active.values,
                                      color_continuous_scale='Blues')
            st.plotly_chart(fig_region_active, use_container_width=True)

        with col3:
            # 段位分布
            region_rank = pd.crosstab(df['所在区域'], df['游戏段位'])
            fig_region_rank = px.imshow(region_rank.values,
                                       x=region_rank.columns,
                                       y=region_rank.index,
                                       title='区域 vs 段位分布热力图',
                                       labels=dict(x="段位", y="区域", color="人数"))
            st.plotly_chart(fig_region_rank, use_container_width=True)

# 预测性分析
def predictive_analysis(df, df_processed):
    st.markdown("## 🔮 预测性分析")

    # 1. 用户流失预测
    with st.expander("⚠️ 用户流失预测", expanded=True):
        df_processed['流失风险'] = df_processed.apply(predict_churn_risk, axis=1)
        df_processed['流失风险等级'] = pd.cut(df_processed['流失风险'],
                                              bins=[0, 1, 2, 3],
                                              labels=['低风险', '中风险', '高风险'])

        col1, col2 = st.columns(2)

        with col1:
            churn_dist = df_processed['流失风险等级'].value_counts()
            fig_churn = px.pie(churn_dist, values=churn_dist.values, names=churn_dist.index,
                              title='流失风险分布', hole=0.5,
                              color_discrete_sequence=['#2ecc71', '#f39c12', '#e74c3c'])
            st.plotly_chart(fig_churn, use_container_width=True)

        with col2:
            # 确保使用df_processed中包含消费分段字段的数据
            if '消费分段' in df_processed.columns:
                # 创建一个包含登录频率和消费分段的DataFrame用于分组
                temp_df = df_processed[['登录频率', '消费分段']].copy()
                churn_login = temp_df.groupby(['登录频率', '消费分段']).size().reset_index(name='人数')
                fig_churn_login = px.bar(churn_login, x='登录频率', y='人数', color='消费分段',
                                        title='登录频率与消费关系',
                                        barmode='stack')
                st.plotly_chart(fig_churn_login, use_container_width=True)
            else:
                # 如果消费分段不存在,使用游戏段位
                temp_df = df_processed[['登录频率', '游戏段位']].copy()
                churn_login = temp_df.groupby(['登录频率', '游戏段位']).size().reset_index(name='人数')
                fig_churn_login = px.bar(churn_login, x='登录频率', y='人数', color='游戏段位',
                                        title='登录频率与段位关系',
                                        barmode='stack')
                st.plotly_chart(fig_churn_login, use_container_width=True)

        # 流失用户详细分析
        st.markdown("### 高流失风险用户特征")
        high_churn = df_processed[df_processed['流失风险等级'] == '高风险']
        if len(high_churn) > 0:
            col1, col2, col3, col4 = st.columns(4)
            with col1:
                st.metric("高风险人数", len(high_churn))
            with col2:
                st.metric("平均日均时长", f"{high_churn['日均时长'].mean():.1f}h")
            with col3:
                st.metric("平均累计消费", f"¥{high_churn['累计消费'].mean():.1f}")
            with col4:
                st.metric("平均胜率", f"{high_churn['综合胜率'].mean()*100:.1f}%")

    # 2. 付费潜力预测
    with st.expander("💎 付费潜力预测", expanded=True):
        df_processed['付费潜力'] = df_processed.apply(predict_pay_potential, axis=1)

        col1, col2 = st.columns(2)

        with col1:
            potential_dist = df_processed['付费潜力'].value_counts()
            fig_potential = px.pie(potential_dist, values=potential_dist.values, names=potential_dist.index,
                                  title='付费潜力分布', hole=0.5,
                                  color_discrete_sequence=['#3498db', '#f39c12', '#e74c3c'])
            st.plotly_chart(fig_potential, use_container_width=True)

        with col2:
            potential_rank = df_processed.groupby(['付费潜力', '游戏段位']).size().reset_index(name='人数')
            fig_potential_rank = px.bar(potential_rank, x='游戏段位', y='人数', color='付费潜力',
                                       title='不同段位的付费潜力分布',
                                       barmode='stack')
            fig_potential_rank.update_xaxes(tickangle=45)
            st.plotly_chart(fig_potential_rank, use_container_width=True)

    # 3. 段位晋升预测
    with st.expander("🏆 段位晋升预测", expanded=True):
        df_processed['预计晋升时间'] = df_processed.apply(predict_promotion_time, axis=1)

        col1, col2 = st.columns(2)

        with col1:
            promotion_dist = df_processed['预计晋升时间'].value_counts()
            fig_promotion = px.bar(promotion_dist, x=promotion_dist.index, y=promotion_dist.values,
                                  title='段位晋升时间预测分布',
                                  labels={'x': '预计晋升时间', 'y': '人数'},
                                  color=promotion_dist.values,
                                  color_continuous_scale='RdYlGn_r')
            st.plotly_chart(fig_promotion, use_container_width=True)

        with col2:
            promotion_kda = df_processed[df_processed['预计晋升时间'] != '已达巅峰'].groupby(
                ['预计晋升时间', '游戏段位']).size().reset_index(name='人数')
            if len(promotion_kda) > 0:
                fig_promotion_rank = px.bar(promotion_kda, x='游戏段位', y='人数', color='预计晋升时间',
                                           title='不同段位的晋升时间预测',
                                           barmode='stack')
                fig_promotion_rank.update_xaxes(tickangle=45)
                st.plotly_chart(fig_promotion_rank, use_container_width=True)

# 运营决策支持
def decision_support(df, df_processed):
    st.markdown("## 📋 运营决策支持")

    # 1. 高价值用户识别
    with st.expander("💎 高价值用户识别", expanded=True):
        df_processed['用户价值分'] = (
            (df_processed['累计消费'] / df_processed['累计消费'].max()) * 100 * 0.5 +
            df_processed['活跃度分数'] / df_processed['活跃度分数'].max() * 50 * 0.3 +
            df_processed['技能分数'] / df_processed['技能分数'].max() * 20 * 0.2
        )
        top_users = df_processed.nlargest(10, '用户价值分')

        st.markdown("### TOP 10 高价值用户")
        user_display = top_users[['用户ID', '游戏段位', '累计消费', '日均时长', '综合胜率', 'KDA指数', '登录频率']].copy()
        user_display['综合胜率'] = (user_display['综合胜率'] * 100).round(1).astype(str) + '%'
        st.dataframe(user_display, use_container_width=True)

        st.markdown("### 📌 运营建议")
        st.info("""
        **针对高价值用户的专属福利策略:**
        - 发放专属限量皮肤/道具
        - 提供优先客服通道
        - 邀请参与内测和赛事
        - 定期推送个性化内容推荐
        - 设置VIP专属活动日
        """)

    # 2. 流失预警干预
    with st.expander("⚠️ 流失预警干预", expanded=True):
        # 如果流失风险等级字段不存在,先创建它
        if '流失风险等级' not in df_processed.columns:
            df_processed['流失风险'] = df_processed.apply(predict_churn_risk, axis=1)
            df_processed['流失风险等级'] = pd.cut(df_processed['流失风险'],
                                                  bins=[0, 1, 2, 3],
                                                  labels=['低风险', '中风险', '高风险'])
        
        high_churn = df_processed[df_processed['流失风险等级'] == '高风险'].nlargest(10, '累计消费')

        if len(high_churn) > 0:
            st.markdown("### 需要重点召回的高价值流失风险用户")
            churn_display = high_churn[['用户ID', '游戏段位', '累计消费', '日均时长', '登录频率', '行为模式']].copy()
            st.dataframe(churn_display, use_container_width=True)
        else:
            st.info("未发现高风险流失用户")

        st.markdown("### 📌 召回策略")
        st.warning("""
        **对登录频率下降用户的召回活动:**
        - 发送回归礼包和专属福利
        - 推送好友互动提醒
        - 邀请参与回归专属活动
        - 根据行为模式推送个性化内容
        - 设置连续登录奖励
        """)

    # 3. 匹配优化建议
    with st.expander("⚔️ 匹配优化建议", expanded=True):
        # 段位KDA统计
        rank_stats = df.groupby('游戏段位').agg({
            '综合胜率': 'mean',
            'KDA指数': 'mean',
            '日均时长': 'mean'
        }).round(3)

        st.markdown("### 各段位平均数据")
        st.dataframe(rank_stats, use_container_width=True)

        st.markdown("### 📌 匹配建议")
        st.success("""
        **根据段位、胜率、KDA优化对战匹配算法:**
        - 扩大匹配考虑维度:综合胜率 + KDA指数 + 日均时长
        - 设置动态匹配范围:活跃时间短的玩家匹配更接近水平的对手
        - 引入段位保护机制:连续败北时适当降低匹配难度
        - 组队匹配优化:综合计算队伍平均实力
        - 避免新手对老手:根据注册时间和游戏时长增加匹配权重
        """)

    # 4. 内容推荐
    with st.expander("🎯 内容推荐", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            st.markdown("#### 按位置偏好推荐")
            position_rec = df.groupby('擅长位置').agg({
                '累计消费': 'mean',
                '日均时长': 'mean',
                '综合胜率': 'mean'
            }).round(2)
            st.dataframe(position_rec, use_container_width=True)

        with col2:
            st.markdown("#### 按行为模式推荐")
            behavior_rec = df.groupby('行为模式').agg({
                '累计消费': 'mean',
                '日均时长': 'mean',
                '玩家年龄': 'mean'
            }).round(2)
            st.dataframe(behavior_rec, use_container_width=True)

        st.markdown("### 📌 推荐策略")
        st.info("""
        **根据擅长位置和行为模式推荐游戏内容:**

        **竞技型玩家:**
        - 推荐排位赛活动和赛事
        - 新英雄/技能攻略
        - 高段位对局回放

        **社交型玩家:**
        - 推荐组队开黑活动
        - 好友系统功能
        - 公会/战队内容

        **休闲型玩家:**
        - 推荐娱乐模式活动
        - 皮肤和外观内容
        - 成就任务系统

        **收藏型玩家:**
        - 推荐限定皮肤和道具
        - 收集成就系统
        - 稀有道具活动
        """)

    # 5. 定价策略
    with st.expander("💰 定价策略", expanded=True):
        region_pricing = df.groupby('所在区域').agg({
            '累计消费': ['mean', 'median', 'std']
        }).round(2)
        region_pricing.columns = ['平均消费', '中位数消费', '消费标准差']

        fig_region_pricing = px.bar(region_pricing, x=region_pricing.index, y='平均消费',
                                   title='各区域平均消费对比',
                                   labels={'x': '区域', '平均消费': '平均消费(元)'},
                                   color='平均消费',
                                   color_continuous_scale='Viridis')
        st.plotly_chart(fig_region_pricing, use_container_width=True)

        st.dataframe(region_pricing, use_container_width=True)

        st.markdown("### 📌 定价建议")
        st.info("""
        **基于区域消费差异制定差异化定价:**

        - **高消费区域**:可推出更多高价值礼包,提供会员专属服务
        - **中等消费区域**:平衡定价策略,推出性价比优惠组合
        - **低消费区域**:增加小额多次消费选项,降低单次消费门槛
        - **区域性促销**:针对不同区域节日和特点推出活动
        - **分层定价**:同一产品提供基础版、进阶版、豪华版
        """)

# 可视化分析
def visualization_analysis(df, df_processed):
    st.markdown("## 📊 可视化分析")

    # 1. 用户分布
    with st.expander("🗺️ 用户分布分析", expanded=True):
        tab1, tab2 = st.tabs(["区域热力图", "年龄/段位金字塔"])

        with tab1:
            # 区域分布热力
            region_age = pd.crosstab(df['所在区域'], df_processed['年龄分段'])
            fig_region_heat = px.imshow(region_age.values,
                                       x=region_age.columns,
                                       y=region_age.index,
                                       title='区域 × 年龄分布热力图',
                                       labels=dict(x="年龄段", y="区域", color="人数"),
                                       color_continuous_scale='YlOrRd',
                                       aspect="auto")
            st.plotly_chart(fig_region_heat, use_container_width=True)

        with tab2:
            # 年龄段位金字塔
            rank_order = ['荣耀青铜', '秩序白银', '尊贵铂金', '永恒钻石', '至尊星耀', '最强王者']
            age_order = ['青少年', '青年', '成年', '中老年']

            pyramid_data = []
            for age in age_order:
                for rank in rank_order:
                    count = len(df_processed[(df_processed['年龄分段'] == age) & (df_processed['游戏段位'] == rank)])
                    pyramid_data.append({'年龄段': age, '段位': rank, '人数': count})

            pyramid_df = pd.DataFrame(pyramid_data)
            fig_pyramid = px.bar(pyramid_df, x='人数', y='段位',
                               color='年龄段',
                               orientation='h',
                               title='年龄×段位分布金字塔',
                               labels={'人数': '人数', '段位': '段位'},
                               barmode='stack',
                               color_discrete_map={'青少年': '#3498db', '青年': '#2ecc71',
                                                   '成年': '#f39c12', '中老年': '#e74c3c'})
            st.plotly_chart(fig_pyramid, use_container_width=True)

    # 2. 趋势分析
    with st.expander("📈 趋势分析", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            login_order = ['每月几次', '每周1-2次', '每周3-5次', '每天']
            login_freq = df['登录频率'].value_counts().reindex(login_order)
            fig_login_trend = px.line(x=login_freq.index, y=login_freq.values,
                                     title='登录频率趋势',
                                     labels={'x': '登录频率', 'y': '人数'},
                                     markers=True)
            fig_login_trend.update_traces(line_color='#3498db', marker_size=10)
            st.plotly_chart(fig_login_trend, use_container_width=True)

        with col2:
            # 日均时长分段
            df_processed['时长分段'] = pd.cut(df_processed['日均时长'],
                                             bins=[0, 2, 4, 6, float('inf')],
                                             labels=['0-2小时', '2-4小时', '4-6小时', '6+小时'])
            duration_dist = df_processed['时长分段'].value_counts()
            fig_duration_trend = px.bar(x=duration_dist.index, y=duration_dist.values,
                                       title='日均时长分布',
                                       labels={'x': '时长分段', 'y': '人数'},
                                       color=duration_dist.values,
                                       color_continuous_scale='Blues')
            st.plotly_chart(fig_duration_trend, use_container_width=True)

    # 3. 对比分析
    with st.expander("📊 对比分析", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            gender_spend = df.groupby('玩家性别')['累计消费'].mean().reset_index()
            fig_gender_spend = px.bar(gender_spend, x='玩家性别', y='累计消费',
                                      title='性别消费对比',
                                      labels={'玩家性别': '性别', '累计消费': '平均消费(元)'},
                                      color='累计消费',
                                      color_continuous_scale='RdYlGn')
            st.plotly_chart(fig_gender_spend, use_container_width=True)

        with col2:
            region_active = df_processed.groupby('所在区域')['日均时长'].mean().sort_values(ascending=False).reset_index()
            fig_region_active = px.bar(region_active, x='所在区域', y='日均时长',
                                       title='区域活跃度对比',
                                       labels={'所在区域': '区域', '日均时长': '平均日均时长(小时)'},
                                       color='日均时长',
                                       color_continuous_scale='YlOrRd')
            st.plotly_chart(fig_region_active, use_container_width=True)

        # 性别段位对比
        col1, col2 = st.columns(2)
        with col1:
            gender_rank = pd.crosstab(df['玩家性别'], df['游戏段位'])
            fig_gender_rank = px.imshow(gender_rank.values,
                                       x=gender_rank.columns,
                                       y=gender_rank.index,
                                       title='性别 × 段位分布热力图',
                                       labels=dict(x="段位", y="性别", color="人数"),
                                       color_continuous_scale='Viridis',
                                       aspect="auto")
            st.plotly_chart(fig_gender_rank, use_container_width=True)

        with col2:
            gender_kda = df.groupby('玩家性别')[['KDA指数', '综合胜率']].mean()
            gender_kda['综合胜率'] = gender_kda['综合胜率'] * 100
            fig_gender_kda = px.bar(gender_kda.reset_index().melt(id_vars=['玩家性别']),
                                   x='玩家性别', y='value', color='variable',
                                   title='性别 × 技能指标对比',
                                   labels={'玩家性别': '性别', 'value': '数值', 'variable': '指标'},
                                   barmode='group')
            st.plotly_chart(fig_gender_kda, use_container_width=True)

    # 4. 关联分析(散点图)
    with st.expander("🔗 关联分析", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            fig_scatter1 = px.scatter(df, x='日均时长', y='累计消费',
                                     title='日均时长 vs 累计消费',
                                     labels={'日均时长': '日均时长(小时)', '累计消费': '累计消费(元)'},
                                     color='游戏段位',
                                     opacity=0.6)
            st.plotly_chart(fig_scatter1, use_container_width=True)

        with col2:
            fig_scatter2 = px.scatter(df, x='综合胜率', y='KDA指数',
                                     title='综合胜率 vs KDA指数',
                                     labels={'综合胜率': '胜率', 'KDA指数': 'KDA指数'},
                                     color='游戏段位',
                                     opacity=0.6)
            st.plotly_chart(fig_scatter2, use_container_width=True)

        # 3D散点图
        fig_3d = px.scatter_3d(df, x='日均时长', y='累计消费', z='综合胜率',
                              color='游戏段位',
                              title='多维度关联分析(3D)',
                              labels={'日均时长': '日均时长', '累计消费': '累计消费', '综合胜率': '胜率'},
                              opacity=0.7)
        st.plotly_chart(fig_3d, use_container_width=True)

    # 5. 分群分析(雷达图)
    with st.expander("🎯 分群分析 - 用户画像雷达图", expanded=True):
        col1, col2 = st.columns(2)

        with col1:
            # 按行为模式分群
            behavior_radar = df.groupby('行为模式').agg({
                '玩家年龄': 'mean',
                '日均时长': 'mean',
                '累计消费': 'mean',
                '综合胜率': 'mean',
                'KDA指数': 'mean'
            }).reset_index()

            behavior_radar['综合胜率'] = behavior_radar['综合胜率'] * 100

            fig_radar1 = px.line_polar(behavior_radar, r='综合胜率', theta='行为模式',
                                      line_close=True, title='各行为模式胜率对比')
            st.plotly_chart(fig_radar1, use_container_width=True)

        with col2:
            # 按段位分群
            rank_radar = df.groupby('游戏段位').agg({
                '日均时长': 'mean',
                '累计消费': 'mean',
                '综合胜率': 'mean',
                'KDA指数': 'mean'
            }).reset_index()

            rank_radar['综合胜率'] = rank_radar['综合胜率'] * 100

            # 标准化数据用于雷达图
            radar_data = rank_radar.melt(id_vars=['游戏段位'], var_name='指标', value_name='数值')
            for col in ['日均时长', '累计消费', '综合胜率', 'KDA指数']:
                max_val = radar_data[radar_data['指标'] == col]['数值'].max()
                radar_data.loc[radar_data['指标'] == col, '数值'] = radar_data.loc[
                    radar_data['指标'] == col, '数值'] / max_val * 100

            fig_radar2 = px.line_polar(radar_data[radar_data['游戏段位'] == '最强王者'],
                                      r='数值', theta='指标',
                                      line_close=True, title='最强王者玩家画像')
            st.plotly_chart(fig_radar2, use_container_width=True)

        # 多行为模式对比雷达图
        st.markdown("### 各行为模式综合画像对比")
        fig_radar_compare = go.Figure()

        categories = ['年龄', '日均时长', '累计消费', '胜率', 'KDA']
        for behavior in ['竞技型', '社交型', '休闲型', '娱乐型', '收藏型']:
            if behavior in behavior_radar['行为模式'].values:
                data = behavior_radar[behavior_radar['行为模式'] == behavior].iloc[0]
                values = [
                    (data['玩家年龄'] / behavior_radar['玩家年龄'].max()) * 100,
                    (data['日均时长'] / behavior_radar['日均时长'].max()) * 100,
                    (data['累计消费'] / behavior_radar['累计消费'].max()) * 100,
                    data['综合胜率'],
                    (data['KDA指数'] / behavior_radar['KDA指数'].max()) * 100
                ]
                fig_radar_compare.add_trace(go.Scatterpolar(
                    r=values,
                    theta=categories,
                    fill='toself',
                    name=behavior
                ))

        fig_radar_compare.update_layout(
            polar=dict(radialaxis=dict(visible=True, range=[0, 100])),
            showlegend=True,
            title="各行为模式综合画像对比(标准化后)"
        )
        st.plotly_chart(fig_radar_compare, use_container_width=True)

# 主函数
def main():
    # 标题
    st.markdown('<div class="main-header">🎮 游戏玩家数据分析平台</div>', unsafe_allow_html=True)

    # 侧边栏
    with st.sidebar:
        st.header("📂 数据上传")

        # 文件上传
        uploaded_file = st.file_uploader("上传CSV文件", type=['csv'])

        if uploaded_file:
            st.success(f"✅ 已加载: {uploaded_file.name}")
        else:
            st.info("💡 请上传包含玩家数据的CSV文件")
            st.markdown("""
            **数据格式要求:**
            - 用户ID
            - 玩家性别
            - 玩家年龄
            - 所在区域
            - 游戏段位
            - 日均时长
            - 累计消费
            - 擅长位置
            - 综合胜率
            - KDA指数
            - 登录频率
            - 行为模式
            """)

        # 默认使用示例数据
        if uploaded_file is None:
            try:
                import os
                default_file = r"d:\daku\游戏玩家数据分析\player_behavior_data.csv"
                if os.path.exists(default_file):
                    uploaded_file = open(default_file, 'rb', encoding=None)
                    st.info(f"使用默认数据: {os.path.basename(default_file)}")
            except:
                pass

    # 数据加载
    if uploaded_file:
        df = load_data(uploaded_file)
        df_processed = preprocess_data(df)

        # 显示关键指标
        metrics = calculate_metrics(df)
        st.markdown("---")
        col1, col2, col3, col4, col5, col6, col7 = st.columns(7)
        with col1:
            st.metric("👥 总玩家数", metrics['总玩家数'])
        with col2:
            st.metric("🎂 平均年龄", f"{metrics['平均年龄']}岁")
        with col3:
            st.metric("⏱️ 平均日均时长", f"{metrics['平均日均时长']}h")
        with col4:
            st.metric("💰 总累计消费", f"¥{metrics['总累计消费']:,.0f}")
        with col5:
            st.metric("💵 平均消费", f"¥{metrics['平均累计消费']:.1f}")
        with col6:
            st.metric("🏆 平均胜率", f"{metrics['平均胜率']}%")
        with col7:
            st.metric("⚔️ 平均KDA", metrics['平均KDA'])

        st.markdown("---")

        # 分析模块选择
        analysis_type = st.radio(
            "📊 选择分析模块",
            ["📈 用户画像分析", "🎯 用户细分/分群分析", "🔗 关联与相关性分析",
             "🔮 预测性分析", "📋 运营决策支持", "📊 可视化分析"],
            horizontal=True,
            label_visibility="collapsed"
        )

        # 执行对应分析
        if analysis_type == "📈 用户画像分析":
            user_profile_analysis(df, df_processed)
        elif analysis_type == "🎯 用户细分/分群分析":
            segmentation_analysis(df, df_processed)
        elif analysis_type == "🔗 关联与相关性分析":
            correlation_analysis(df, df_processed)
        elif analysis_type == "🔮 预测性分析":
            predictive_analysis(df, df_processed)
        elif analysis_type == "📋 运营决策支持":
            decision_support(df, df_processed)
        elif analysis_type == "📊 可视化分析":
            visualization_analysis(df, df_processed)

    else:
        # 欢迎页面
        st.markdown("""
        <div style="text-align: center; padding: 40px 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 20px; color: white; margin-bottom: 40px;">
            <h1 style="font-size: 3.5rem; margin-bottom: 20px;">🎮 游戏玩家数据分析平台</h1>
            <p style="font-size: 1.5rem; margin-bottom: 30px;">基于Python与Streamlit构建的多维度数据分析应用</p>
            <div style="background: rgba(255,255,255,0.2); padding: 20px; border-radius: 15px; display: inline-block;">
                <p style="font-size: 1.2rem; margin: 0;">📁 请在左侧上传CSV文件开始分析</p>
            </div>
        </div>
        """, unsafe_allow_html=True)

        # 平台特色介绍
        st.markdown('<div class="section-header">🌟 平台特色</div>', unsafe_allow_html=True)
        
        col1, col2, col3, col4 = st.columns(4)
        with col1:
            st.markdown("""
            <div style="text-align: center; padding: 25px; background: #f8f9fa; border-radius: 15px; height: 280px;">
                <div class="feature-icon">📊</div>
                <div class="feature-title">多维度分析</div>
                <div class="feature-description">
                    基于12个玩家维度的全面分析,涵盖人口统计、游戏能力、行为习惯和消费能力
                </div>
            </div>
            """, unsafe_allow_html=True)
        with col2:
            st.markdown("""
            <div style="text-align: center; padding: 25px; background: #f8f9fa; border-radius: 15px; height: 280px;">
                <div class="feature-icon">🎯</div>
                <div class="feature-title">智能分群</div>
                <div class="feature-description">
                    支持5种用户细分方式:价值、活跃度、技能、偏好、行为模式分群
                </div>
            </div>
            """, unsafe_allow_html=True)
        with col3:
            st.markdown("""
            <div style="text-align: center; padding: 25px; background: #f8f9fa; border-radius: 15px; height: 280px;">
                <div class="feature-icon">🔮</div>
                <div class="feature-title">预测分析</div>
                <div class="feature-description">
                    提供流失预测、付费潜力预测、段位晋升预测等智能分析功能
                </div>
            </div>
            """, unsafe_allow_html=True)
        with col4:
            st.markdown("""
            <div style="text-align: center; padding: 25px; background: #f8f9fa; border-radius: 15px; height: 280px;">
                <div class="feature-icon">💡</div>
                <div class="feature-title">决策支持</div>
                <div class="feature-description">
                    基于数据分析结果,提供可执行的运营策略和决策建议
                </div>
            </div>
            """, unsafe_allow_html=True)

        # 功能介绍卡片
        st.markdown('<div class="section-header">📋 功能模块</div>', unsafe_allow_html=True)
        
        # 第一行功能
        col1, col2, col3 = st.columns(3)
        with col1:
            with st.container():
                st.markdown('<div class="info-card">', unsafe_allow_html=True)
                st.markdown("### 📈 用户画像分析")
                st.markdown("- 👥 **人口统计画像**: 性别、年龄、区域分布")
                st.markdown("- ⚔️ **游戏能力画像**: 段位、胜率、KDA、位置")
                st.markdown("- 🎯 **行为习惯画像**: 时长、登录频率、行为模式")
                st.markdown("- 💰 **消费能力画像**: 消费分布、消费能力评估")
                st.markdown('</div>', unsafe_allow_html=True)
        
        with col2:
            with st.container():
                st.markdown('<div class="info-card">', unsafe_allow_html=True)
                st.markdown("### 🎯 用户细分分析")
                st.markdown("- 💎 **按价值分群**: 高/中/低消费用户")
                st.markdown("- 🔥 **按活跃度分群**: 核心/普通/流失用户")
                st.markdown("- 🎮 **按技能分群**: 新手/进阶/高手")
                st.markdown("- ⭐ **按偏好分群**: 不同位置偏好")
                st.markdown("- 🎭 **按行为分群**: 社交/竞技/休闲型")
                st.markdown('</div>', unsafe_allow_html=True)
        
        with col3:
            with st.container():
                st.markdown('<div class="info-card">', unsafe_allow_html=True)
                st.markdown("### 🔗 关联性分析")
                st.markdown("- 💰 **消费驱动因素**: 时长、段位、胜率与消费关系")
                st.markdown("- 📊 **活跃度影响因素**: 年龄、区域对活跃度影响")
                st.markdown("- 📈 **技能成长路径**: 时长、段位与KDA关联")
                st.markdown("- 🗺️ **区域差异分析**: 各区域消费、段位、活跃度对比")
                st.markdown('</div>', unsafe_allow_html=True)

        # 第二行功能
        col4, col5, col6 = st.columns(3)
        with col4:
            with st.container():
                st.markdown('<div class="warning-card">', unsafe_allow_html=True)
                st.markdown("### 🔮 预测性分析")
                st.markdown("- ⚠️ **用户流失预测**: 基于登录频率、时长、行为模式")
                st.markdown("- 💎 **付费潜力预测**: 基于段位、活跃度、行为模式")
                st.markdown("- 🏆 **段位晋升预测**: 基于KDA、胜率、游戏时长")
                st.markdown('</div>', unsafe_allow_html=True)
        
        with col5:
            with st.container():
                st.markdown('<div class="success-card">', unsafe_allow_html=True)
                st.markdown("### 📋 运营决策支持")
                st.markdown("- 💎 **高价值用户识别**: TOP10用户及运营策略")
                st.markdown("- ⚠️ **流失预警干预**: 需要召回的用户及策略")
                st.markdown("- ⚔️ **匹配优化建议**: 优化对战匹配算法")
                st.markdown("- 🎯 **内容推荐**: 基于位置偏好推荐")
                st.markdown("- 💰 **定价策略**: 区域差异化定价")
                st.markdown('</div>', unsafe_allow_html=True)
        
        with col6:
            with st.container():
                st.markdown('<div class="info-card">', unsafe_allow_html=True)
                st.markdown("### 📊 可视化分析")
                st.markdown("- 🗺️ **用户分布**: 区域热力图、年龄/段位金字塔")
                st.markdown("- 📈 **趋势分析**: 登录频率、日均时长趋势")
                st.markdown("- 📊 **对比分析**: 性别消费、区域活跃度对比")
                st.markdown("- 🔗 **关联分析**: 时长vs消费、胜率vs段位散点图")
                st.markdown("- 🎯 **分群分析**: 用户画像雷达图")
                st.markdown('</div>', unsafe_allow_html=True)

        # 数据格式要求
        st.markdown('<div class="section-header">📁 数据格式要求</div>', unsafe_allow_html=True)
        
        data_format = """
        <div style="background: #f8f9fa; padding: 20px; border-radius: 15px; border-left: 5px solid #3498db;">
        <h4>CSV文件需包含以下12个维度:</h4>
        <table style="width: 100%; border-collapse: collapse; margin-top: 15px;">
            <tr style="background: #3498db; color: white;">
                <th style="padding: 12px; text-align: left;">字段</th>
                <th style="padding: 12px; text-align: left;">说明</th>
                <th style="padding: 12px; text-align: left;">示例</th>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">用户ID</td>
                <td style="padding: 10px;">玩家唯一标识</td>
                <td style="padding: 10px;">100001</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">玩家性别</td>
                <td style="padding: 10px;">性别</td>
                <td style="padding: 10px;">男/女</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">玩家年龄</td>
                <td style="padding: 10px;">年龄</td>
                <td style="padding: 10px;">27</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">所在区域</td>
                <td style="padding: 10px;">区域</td>
                <td style="padding: 10px;">华东/华南/华北</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">游戏段位</td>
                <td style="padding: 10px;">段位</td>
                <td style="padding: 10px;">荣耀青铜/尊贵铂金/最强王者</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">日均时长</td>
                <td style="padding: 10px;">平均每日游戏时长(小时)</td>
                <td style="padding: 10px;">3.9</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">累计消费</td>
                <td style="padding: 10px;">累计消费金额(元)</td>
                <td style="padding: 10px;">22.41</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">擅长位置</td>
                <td style="padding: 10px;">擅长的游戏位置</td>
                <td style="padding: 10px;">坦克/刺客/辅助/射手</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">综合胜率</td>
                <td style="padding: 10px;">综合胜率(0-1之间)</td>
                <td style="padding: 10px;">0.483</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">KDA指数</td>
                <td style="padding: 10px;">KDA指数</td>
                <td style="padding: 10px;">5.4</td>
            </tr>
            <tr style="border-bottom: 1px solid #ddd;">
                <td style="padding: 10px;">登录频率</td>
                <td style="padding: 10px;">登录频率</td>
                <td style="padding: 10px;">每天/每周3-5次/每月几次</td>
            </tr>
            <tr>
                <td style="padding: 10px;">行为模式</td>
                <td style="padding: 10px;">行为模式类型</td>
                <td style="padding: 10px;">竞技型/社交型/休闲型</td>
            </tr>
        </table>
        </div>
        """
        st.markdown(data_format, unsafe_allow_html=True)

if __name__ == "__main__":
    main()
相关推荐
xushichao19892 小时前
Python Web爬虫入门:使用Requests和BeautifulSoup
jvm·数据库·python
qq_416018722 小时前
开发一个简单的Python计算器
jvm·数据库·python
智算菩萨2 小时前
OpenCV几何图形绘制工具全栈开发:从中文路径支持到交互式GUI的完整实战(附源码)
开发语言·图像处理·人工智能·python·opencv·计算机视觉
二闹2 小时前
变量世界的“通行证”:理解Python中的global与nonlocal
后端·python
AI-小柒2 小时前
DataEyes聚合平台新API接入实战指南:从0到1打通实时数据链路
大数据·运维·开发语言·人工智能·python·自动化·lua
m0_726965982 小时前
关于文件上传
开发语言·python
二闹2 小时前
解锁Python的隐藏管家:with语句的原理与用法
后端·python·设计
干啥啥不行,秃头第一名2 小时前
实战:用Python开发一个简单的区块链
jvm·数据库·python
qwehjk20082 小时前
使用Scikit-learn构建你的第一个机器学习模型
jvm·数据库·python