广东IT行业就业数据分析可视化系统 — 技术文档

一、项目概述

1.1 基本信息

项目 内容
项目编号 328
项目名称 基于Python的广东IT行业就业数据分析可视化系统
技术栈 Python + Django + Jinja2 + Bootstrap + ECharts + MySQL
运行端口 8328
数据库名 design_338_guangdong_it_employment
数据文件 ITdata.csv(GBK编码,25,581条记录,14个字段)
目标列 平均薪资(连续值,预测时二值化为薪资等级)

1.2 功能模块

模块 说明 状态
auth 用户认证(注册/登录/个人中心/修改密码) 已启用
analytics 数据可视化分析(7个分析页面) 已启用
prediction 薪资等级预测(5种机器学习算法) 已启用
data_manage 数据管理(CRUD + CSV导入 + 分页搜索) 已启用
report_export 报告导出(Excel / PDF) 已启用

1.3 角色体系

角色 权限
user 查看分析、薪资预测、浏览数据、导出报告、个人中心
admin 全部user权限 + 管理控制台 + 用户管理 + 数据增删改 + CSV导入

默认管理员账号:admin / admin123


二、环境部署

2.1 系统要求

  • Python 3.8+
  • MySQL 5.7+ / 8.0+
  • pip 包管理器

2.2 安装步骤

# 1. 创建数据库
mysql -u root -p
CREATE DATABASE design_338_guangdong_it_employment CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EXIT;

# 2. 安装Python依赖
cd F:/code/328-基于Python的广东IT行业就业数据分析可视化系统/code/
pip install -r requirements.txt

# 3. 启动系统
python run.py

# 4. 访问
# 浏览器打开 http://localhost:8328

2.3 依赖列表(requirements.txt)

依赖 用途
PyYAML 配置文件解析
pandas 数据处理与分析
numpy 数值计算
pymysql MySQL数据库驱动
django Web框架
scikit-learn 机器学习(随机森林、梯度提升、逻辑回归、SVM)
xgboost XGBoost算法
openpyxl Excel报告导出
reportlab PDF报告导出
passlib 密码哈希(PBKDF2-SHA256)

2.4 数据库配置

数据库连接参数在 config.yaml 中配置:

project:
  db_name: design_338_guangdong_it_employment
  db_host: localhost
  db_port: 3306
  db_user: root
  db_password: '123456'

2.5 项目演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、项目结构

code/
├── config.yaml              # 项目核心配置文件
├── run.py                   # 启动脚本(依赖检查 + Django runserver)
├── manage.py                # Django管理脚本
├── database.py              # 数据库操作层(用户管理/数据管理/预测历史)
├── predictor.py             # 预测器封装(二值化处理 + 模型管理)
├── requirements.txt         # Python依赖
│
├── project/                 # Django项目配置
│   ├── settings.py          # Django设置(Jinja2模板引擎配置)
│   ├── urls.py              # 根URL配置
│   └── wsgi.py              # WSGI入口
│
├── core/                    # Django应用
│   ├── urls.py              # 路由定义(45条路由)
│   ├── views.py             # 视图函数(所有业务逻辑)
│   └── jinja2_env.py        # Jinja2环境配置(全局变量注入)
│
├── shared/                  # 核心算法模块(不可修改)
│   ├── analysis_core.py     # 数据分析核心(概览/分布/相关性)
│   ├── predictor_core.py    # 机器学习预测核心(训练/预测/评估)
│   └── report_core.py       # 报告导出核心(Excel/PDF生成)
│
├── data/
│   └── ITdata.csv           # 原始数据集(GBK编码)
│
├── model/                   # 机器学习模型文件(自动生成)
│   ├── model_xgboost.pkl
│   ├── model_random_forest.pkl
│   ├── model_gradient_boosting.pkl
│   ├── model_logistic_regression.pkl
│   ├── model_svm.pkl
│   ├── scaler.pkl
│   ├── label_encoders.pkl
│   └── feature_names.pkl
│
├── templates/               # Jinja2模板文件
│   ├── base.html            # 基础布局(侧边栏+导航栏+页脚)
│   ├── login.html           # 登录页(独立页面,分屏布局)
│   ├── register.html        # 注册页(独立页面,分屏布局)
│   ├── index.html           # 首页(统计卡片+功能导航)
│   ├── predict.html         # 薪资预测页
│   ├── overview.html         # 数据概览
│   ├── city_salary.html     # 城市薪资分析
│   ├── job_category.html    # 岗位类别分析
│   ├── salary_distribution.html  # 薪资分布分析
│   ├── education_experience.html # 学历与经验分析
│   ├── company_analysis.html     # 公司维度分析
│   ├── correlation.html     # 关联分析
│   ├── guangdong_map.html   # 广东地图(ECharts地图)
│   ├── data_manage.html     # 数据管理列表
│   ├── data_manage_edit.html # 数据编辑/新增
│   ├── reports.html         # 报告导出
│   ├── profile.html         # 个人资料
│   ├── edit_profile.html    # 编辑资料
│   ├── change_password.html # 修改密码
│   └── admin/
│       ├── dashboard.html   # 管理控制台
│       └── users.html       # 用户管理
│
├── static/
│   ├── css/
│   │   ├── style.css        # 主样式表(CSS变量+组件库)
│   │   └── bootstrap-icons.css  # 图标字体(精简版~400个)
│   └── js/
│       ├── echarts.min.js   # ECharts图表库
│       ├── global.min.js    # Bootstrap + jQuery + 插件
│       ├── custom.min.js    # 骨架交互脚本
│       └── dlabnav-init.js  # 侧边栏初始化
│
├── reports/                 # 导出的报告文件存放目录
└── docs/                    # 项目文档

四、数据集说明

4.1 数据概况

  • 文件:data/ITdata.csv
  • 编码:GBK
  • 总记录数:25,581 条
  • 覆盖城市:21个广东省地级市

4.2 字段定义

字段名 类型 说明 示例
城市 categorical 21个广东地级市 广州、深圳、东莞
岗位类别 text 岗位所属类别 软件工程师、产品经理
岗位id - 岗位唯一标识(未纳入分析) 163607816
岗位名 text 具体岗位名称 软件工程师(JSZX)
公司名称 text 招聘公司名称 东莞市中电爱华电子有限公司
最大薪资 numeric 岗位薪资上限(元/月) 1,500 ~ 500,000
最小薪资 numeric 岗位薪资下限(元/月) 1,000 ~ 350,000
平均薪资 numeric 岗位平均薪资(目标列) 1,250 ~ 400,000
工作年限要求 categorical 6个等级 无需经验、1年及以上、5年及以上
学历要求 categorical 6个等级 高中、大专、本科、硕士、博士
公司行业 text 所属行业 汽车、互联网、金融
公司类型 categorical 6种类型 国企、外企、民营、已上市
公司规模 categorical 7个等级 少于50人 ~ 10000人以上
是否全职 categorical 3种 全职、兼职、实习

4.3 数据加载方式

系统中数据有两种加载方式:

  1. 分析页面(analytics):通过 pd.read_csv() 直接从CSV读取,使用 AnalysisCore 处理
  2. 数据管理(data_manage):从MySQL dataset_data 表读取,首次启动自动从CSV导入

五、系统架构

5.1 整体架构

┌──────────────────────────────────────────────────┐
│                    浏览器端                        │
│  Bootstrap + ECharts + Jinja2模板                  │
└────────────────────┬─────────────────────────────┘
                     │ HTTP
┌────────────────────▼─────────────────────────────┐
│              Django Web层 (views.py)               │
│  路由分发 → 数据转换 → 模板渲染                       │
└──┬──────────┬──────────┬──────────┬───────────────┘
   │          │          │          │
   ▼          ▼          ▼          ▼
┌──────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ DB   │ │Analysis│ │Predict │ │Report  │
│ .py  │ │ Core   │ │ Core   │ │ Core   │
└──┬───┘ └────┬───┘ └────┬───┘ └────┬───┘
   │          │          │          │
   ▼          ▼          ▼          ▼
┌──────┐ ┌────────┐ ┌────────┐ ┌────────┐
│MySQL │ │CSV文件  │ │模型文件 │ │报告文件 │
└──────┘ └────────┘ └────────┘ └────────┘

5.2 模板引擎

本项目使用 Jinja2 作为模板引擎(而非Django默认模板),配置在 project/settings.py

TEMPLATES = [{
    "BACKEND": "django.template.backends.jinja2.Jinja2",
    "DIRS": [BASE_DIR / "templates"],
    "OPTIONS": {"environment": "core.jinja2_env.environment"},
}]

注意事项(Jinja2 vs Django模板语法差异):

功能 Django模板 Jinja2(本项目)
空列表备选 {% empty %} {% else %}
默认值 {{ x|default_if_none:'-' }} {{ x if x else '-' }}
数学运算 {{ x|add:1 }} {{ x + 1 }}
字符串拼接 {{ 'a'|add:b }} {{ 'a' ~ b }}
循环计数 {{ forloop.counter }} {{ loop.index }}
CSRF Token {% csrf_token %} 不需要(已禁用CSRF)

5.3 会话管理

使用Django签名Cookie会话(无需额外数据库表):

SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"

六、路由与接口

6.1 路由总览

公开页面
方法 路径 说明
GET/POST /login 登录
GET/POST /register 注册
需登录(user/admin)
方法 路径 说明
GET / 首页
GET /logout 退出登录
GET /profile 个人资料
GET/POST /edit_profile 编辑资料
GET/POST /change_password 修改密码
GET/POST /predict 薪资预测
GET /analytics/<page_route> 数据分析页
GET /guangdong_map 广东地图
GET /data_manage 数据列表
GET /reports 报告导出
GET /reports/download/<filename> 下载报告
需管理员(admin)
方法 路径 说明
GET /admin/dashboard 管理控制台
GET /admin/users 用户管理
POST /admin/users/<id>/role 修改角色
POST /admin/users/<id>/status 修改状态
POST /admin/users/<id>/reset_password 重置密码
POST /admin/users/<id>/delete 删除用户
POST /admin/users/create 创建用户
GET/POST /data_manage/add 新增数据
GET/POST /data_manage/edit/<id> 编辑数据
POST /data_manage/delete/<id> 删除数据
POST /data_manage/import_csv 导入CSV
POST /reports/generate 生成报告

6.2 分析页面路由

统一路由 GET /analytics/<page_route>,根据 page_route 分发到不同分析逻辑:

page_route 页面标题 分析列 图表类型
overview 数据概览 全部 统计表格 + 缺失数据柱状图
city_salary 城市薪资分析 城市/薪资 柱状图×4(岗位数/平均薪/对比/TOP10)
job_category 岗位类别分析 岗位/薪资 横向柱状图 + 饼图 + 薪资对比
salary_distribution 薪资分布分析 三个薪资列 直方图 + 饼图 + 分组对比
education_experience 学历与经验分析 学历/经验/薪资 饼图 + 柱状图×3
company_analysis 公司维度分析 公司属性/薪资 饼图 + 柱状图×3
correlation 关联分析 三个薪资列 热力图 + 排名表 + 散点图

七、核心模块详解

7.1 database.py — 数据库操作层

数据库表结构

users 表

字段 类型 说明
id INT PK AUTO_INCREMENT 用户ID
username VARCHAR(100) UNIQUE 用户名
email VARCHAR(200) UNIQUE 邮箱
password_hash VARCHAR(255) PBKDF2-SHA256密码哈希
role VARCHAR(20) 角色(user/admin)
status VARCHAR(20) 状态(active/disabled)
full_name VARCHAR(100) 姓名
phone VARCHAR(30) 电话
gender VARCHAR(20) 性别
age INT 年龄
bio TEXT 简介
last_login_at DATETIME 最后登录时间
created_at TIMESTAMP 创建时间

predictions 表

字段 类型 说明
id INT PK 记录ID
user_id INT FK→users 用户ID
(各特征列) DOUBLE/VARCHAR 从config动态生成
prediction_result DOUBLE 预测概率
risk_level VARCHAR(50) 薪资等级
algorithm VARCHAR(50) 使用算法
created_at TIMESTAMP 预测时间

dataset_data 表

字段 类型 说明
id INT PK 记录ID
(各特征列) DOUBLE/VARCHAR 从config动态生成
created_at TIMESTAMP 创建时间
核心方法
方法 功能
init_database() 初始化表结构,创建默认管理员,空表时自动导入CSV
authenticate_user() 用户认证(验证密码+更新登录时间)
register_user() 用户注册(唯一性校验+密码哈希)
get_dataset_data(page, per_page, search) 分页查询数据(支持城市/岗位/公司搜索)
import_csv() 批量导入CSV到数据库(500条/批次)
get_today_login_count() 今日登录人数(基于last_login_at)
get_active_user_count(days) N天内活跃用户数

7.2 predictor.py — 预测器封装

数据预处理流程
原始CSV (GBK) → 读取为DataFrame → 二值化平均薪资 → 保存为UTF-8 CSV
                                    ↓
                           中位数分割: >= 中位数 → 1(高薪)
                                      < 中位数  → 0(低薪)
特征处理
处理 说明
排除列 岗位名、公司名称(高基数文本,不适合编码)
排除列 平均薪资(目标列,不作为特征)
text→categorical 岗位类别、公司行业改为categorical触发LabelEncoder
numeric StandardScaler标准化
categorical LabelEncoder编码
支持算法
算法 中文名
xgboost XGBoost (极端梯度提升) XGBClassifier
random_forest 随机森林 RandomForestClassifier
gradient_boosting 梯度提升树 GradientBoostingClassifier
logistic_regression 逻辑回归 LogisticRegression
svm 支持向量机 SVC(probability=True)
模型文件

首次启动自动训练,模型保存在 model/ 目录:

  • model_{algorithm}.pkl — 训练好的模型
  • scaler.pkl — StandardScaler
  • label_encoders.pkl — 各列的LabelEncoder
  • feature_names.pkl — 特征列名列表

7.3 shared/analysis_core.py — 数据分析核心

方法 输入 返回
overview() {total_samples, missing_values, ...}
category_distribution(columns) 列名列表 {col: {value: count, ...}, ...}
numeric_distribution(column, bins=20) 列名 {labels: [...], counts: [...], mean, median}
correlation_matrix(columns) 列名列表 {columns: [...], matrix: [[...]]}
数据结构转换(views.py中完成)
模块返回 模板期望
{labels, counts} {type: "numeric", labels, values}
{col: {val: count}} {type: "categorical", labels, values}
{columns, matrix} 嵌套字典 {col1: {col2: value}}

7.4 shared/report_core.py — 报告导出核心

方法 功能
generate_excel(output_dir, title) 生成Excel报告(概览+统计+数据表)
generate_pdf(output_dir, title) 生成PDF报告(中文字体+数据概览+统计表格)
list_reports(output_dir) 列出已生成的报告文件

报告内容:

  • 数据概览(总记录数、字段数、缺失值统计)
  • 描述性统计(计数、均值、标准差、最小值、最大值等)
  • 数据明细(前100条记录)

八、前端技术

8.1 页面布局

  • 基础框架:moban5757 后台模板(#main-wrapper 侧边栏布局)
  • CSS框架:Bootstrap 5(通过style.css集成)
  • 图标库:Bootstrap Icons(精简版,约400个图标)
  • 图表库:ECharts 5.x

8.2 设计系统

CSS变量 用途
--primary #1E40AF 主色(深蓝)
--primary-hover #1E3A8A 主色悬停
--primary-dark #172554 深色背景
--secondary #475569 辅助色
--title #0F172A 标题文字色

ECharts配色数组(每个分析页面顶部统一定义):

var chartColors = [
    '#1E40AF', '#3B82F6', '#F59E0B', '#10B981', '#8B5CF6',
    '#EC4899', '#06B6D4', '#F97316', '#6366F1', '#14B8A6'
];

8.3 中文标签系统

所有分析页面使用 fieldMapping + cn() 函数实现字段名中文化:

var fieldMapping = {{ field_mapping|safe }};  // {"城市":"城市", "最大薪资":"最大薪资", ...}
function cn(col) { return fieldMapping[col] || col; }

图表标题、轴标签、表头、Tooltip均使用 cn(col) 显示中文。

8.4 页面结构

登录/注册页(独立页面,不继承base.html):

  • 分屏布局:左侧深蓝渐变面板(品牌信息+功能特性)+ 右侧白色表单卡片
  • 密码输入框支持显示/隐藏切换
  • 响应式:移动端隐藏左侧面板

后台页面(继承base.html):

  • 左侧侧边栏(可折叠,含二级菜单)
  • 顶部导航栏(用户下拉菜单)
  • 内容区域(卡片式布局)
  • 底部版权栏

九、关键业务流程

9.1 用户认证流程

浏览器 → GET /login → 渲染登录页
      → POST /login → authenticate_user()
          ├── 成功 → session写入user_id/role → 重定向到角色首页
          └── 失败 → 重新渲染登录页(显示错误)

密码存储:PBKDF2-SHA256(passlib库),每次登录更新 last_login_at

9.2 薪资预测流程

用户填写岗位信息 → POST /predict
    → _parse_form_data() 解析表单
    → predictor.predict(algorithm, input_data)
        → _preprocess_input() 特征编码+标准化
        → model.predict_proba() 获取概率
    → get_risk_level(probability) 映射薪资等级
        < 0.3 → 低薪
        0.3~0.6 → 中等
        > 0.6 → 高薪
    → save_prediction() 保存预测历史
    → 渲染结果(等级+概率+算法名)

9.3 数据分析流程

GET /analytics/city_salary
    → 匹配 analysis_pages 配置
    → _make_analyzer() 创建 AnalysisCore(注入GBK DataFrame)
    → 根据 page_route 分发到不同分析逻辑
    → 数据结构转换(shared返回 → 模板期望格式)
    → json.dumps() 序列化
    → 渲染模板(JS解析JSON → ECharts图表)

9.4 数据管理流程

GET /data_manage?page=1&search=深圳
    → db.get_dataset_data(page=1, per_page=20, search="深圳")
    → SQL: SELECT * FROM dataset_data WHERE 城市 LIKE '%深圳%' ... LIMIT 20 OFFSET 0
    → 渲染分页表格(窗口式分页,当前页±2页)

首次启动自动导入:init_database() 检测 dataset_data 表为空时自动执行 import_csv()


十、配置说明

10.1 config.yaml 结构

project:          # 项目基本信息(名称/端口/数据库)
roles:            # 角色列表 [user, admin]
modules:          # 功能模块开关
dataset:          # 数据集配置
  file:           # CSV文件名
  encoding:       # 文件编码
  target_column:  # 目标列名
  features:       # 特征定义列表
    - key:        # 列名(必须与CSV完全一致)
      label:      # 中文显示名
      type:       # numeric / categorical / text / binary
      options:    # categorical类型的选项列表
      range:      # numeric类型的取值范围
analysis_pages:   # 分析页面配置
  - route:        # 路由名(URL路径)
    title:        # 页面标题
    icon:         # 图标类名
    columns:      # 参与分析的列名列表
algorithms:       # 预测算法列表

10.2 特征类型说明

类型 存储 表单控件 分析方式 预测处理
numeric DOUBLE 数字输入框 直方图/统计 StandardScaler
categorical VARCHAR(100) 下拉选择 饼图/柱状图 LabelEncoder
text VARCHAR(200) 文本输入框 分类分布 LabelEncoder(低基数)或排除
binary INT 数字输入框 分类分布 直接使用

十一、安全设计

措施 实现
密码存储 PBKDF2-SHA256哈希(passlib),不存储明文
会话管理 Django签名Cookie,HttpOnly标记
权限控制 require_login() / require_admin_user() 装饰检查
SQL注入防护 全部使用参数化查询(%s占位符)
XSS防护 Jinja2默认自动转义
账号安全 支持禁用账号(status=disabled)

十二、薪资分布特殊处理

由于薪资数据存在极端长尾分布(范围1,250400,000,95%数据集中在1,50026,425),直方图采用自定义分段:

0-3000, 3000-5000, 5000-8000, 8000-10000,
10000-15000, 15000-20000, 20000-30000, 30000-50000, 50000+

关联分析散点图过滤1%和99%分位数以外的极端值,防止坐标轴被拉伸。


十三、常见问题

Q1: 启动报错 “Unknown MySQL server host”

检查 config.yamldb_hostdb_port 配置,确认MySQL服务已启动。

Q2: 数据管理页面无数据

首次启动会自动从CSV导入数据到MySQL。如仍无数据,手动点击页面上的"导入CSV"按钮。

Q3: 预测结果概率为0

删除 model/ 目录下所有 .pkl 文件和 data/ITdata_binary.csv,重启系统自动重新训练。

Q4: 图表不显示 / 轴标签截断

确认 ECharts 的 grid.top 值足够(推荐 ≥ 10%),以容纳Y轴名称标签。

Q5: 图标不显示

本项目使用精简版 bootstrap-icons.css(约400个图标),部分图标不可用。使用前需确认 .bi-xxx::before 在CSS中有定义。

Q6: 报告导出PDF中文乱码

系统自动查找系统中文字体(SimSun/SimHei/微软雅黑),如均未找到则回退为默认字体。确保系统安装了中文字体。

更多推荐