Skip to content

About

数据子序列分析工具,用于分析和比较客户生命周期价值数据序列。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

LTV 数据子序列分析系统

项目地址,我的gitee仓库:https://gitee.com/yohoten_space/ltv_apy_subsequence

LTV (Lifetime Value) 数据子序列分析系统是一个交互式数据可视化工具,用于分析和比较客户生命周期价值数据序列。

功能特点

多种数据可视化方式

  • LTV序列对比图:直观展示不同客户群体的生命周期价值变化趋势
  • OncoPrint图:仿生物信息学中的OncoPrint图展示客户生命周期关键事件
  • 热力图:以热力图形式展示数据相关性
  • 数据表格:以传统表格形式展示原始数据

交互式操作

  • 图表缩放和平移
  • 点击查看详情
  • 多标签页切换不同视图
  • 图表导出功能

数据筛选和分析

  • 基于条件的序列筛选
  • 时间范围选择器
  • 统计指标计算功能

高级可视化功能

  • 趋势线拟合(线性 / 二次 / 三次多项式)
  • 异常检测标记(Z-Score / IQR)
  • 预测功能(ARIMA、线性回归、移动平均,后台线程执行且可取消)

子序列分析

  • MASS 形态检索:基于 FFT 的滑窗距离剖面(O(n log n)),在全表所有序列中检索与给定片段最相似的窗口
  • DTW 形态距离:弹性时间规整,按形状而非绝对水平比较序列,支持 Sakoe-Chiba 带状约束
  • Motif / Discord 发现:基于 Matrix Profile 找出重复出现的典型形态与罕见异常片段
  • SAX 符号化:PAA + SAX 把连续 LTV 曲线压缩为状态序列(如 aabbccdd),供 OncoPrint 生成真实的状态图谱

子序列分析页(第 6 个标签页)

  • 形态检索:指定查询片段(来源序列 + 起点 + 长度),在全库或单条序列中检索相似形态; 支持 MASS(快)/ DTW(抗时间伸缩)两种匹配、Top-K、以及「排除位置重叠」防伪结果
  • Motif 发现:Matrix Profile 曲线 + 重复形态对 + 异常片段三段式可视化, 一眼看出「哪些片段反复出现、哪些片段全序列找不到同类」
  • DTW 形态聚类:在 DTW 距离矩阵上做层次聚类,输出树状图 + 簇标签, 支持 average/complete/single/ward 四种连接准则与 Sakoe-Chiba 带宽约束

分析工作台

  • 统计摘要、相关性分析(含 p 值与显著性检验)、特征重要性
  • K-means / DBSCAN 聚类(按序列聚类,非按时间点)
  • DTW 形态距离矩阵、Motif 形态发现
  • 季节分解(趋势 / 季节 / 残差):周期由真实时间轴频率推导(日→7、月→12、周→52), 推导不出来会明确报错而不是硬编码 12;数据有缺口也能正确判频(周期在缺失值剔除前判定)
  • 所有结果以「表格 + 图形」沉淀,可导出 CSV

自适应设计

  • 响应式布局适配不同屏幕尺寸
  • 支持深色模式

安装和运行

环境要求

  • Python 3.8+
  • 相关依赖包(见下节)

安装步骤

  1. 克隆或下载本项目到本地

  2. 创建虚拟环境(推荐):

python -m venv .venv
  1. 激活虚拟环境:
# Windows PowerShell
.venv\Scripts\Activate.ps1

# Windows CMD
.venv\Scripts\activate.bat

# macOS/Linux
source .venv/bin/activate
  1. 安装核心依赖包:
pip install -r requirements.txt
  1. 准备数据文件:
    • 将数据文件放置在 data/sample_ltv_monthly.csv(或执行 python scripts/generate_sample_data.py 现造一份)
    • 或通过环境变量 LTV_DATA_PATH 指定数据文件路径

依赖管理说明

项目采用分层依赖管理策略,以优化安装包体积:

核心依赖(必需)

包含在 requirements.txt 中,运行程序所必需:

  • PyQt5 - GUI框架
  • pyqtgraph - 高性能绘图
  • matplotlib - 图表绘制
  • pandas, numpy - 数据处理
  • scikit-learn, scipy - 数据分析
  • seaborn - 可视化增强
  • SQLAlchemy - 数据库支持(可选)

可选依赖(按需安装)

以下功能需要额外安装包:

ARIMA预测功能:

pip install statsmodels==0.14.0

LSTM 深度学习预测:已移除。

TensorFlow 约 500 MB,会使安装包从 ~110 MB 膨胀到无法分发的量级; ARIMA / 线性回归 / 移动平均 已覆盖本项目的预测需求。代码中的 TensorFlow 导入分支与相关宣传口径均已清理。

构建工具(仅打包时需要)

pip install pyinstaller

打包与安装程序

所有产物都由 build.py 一个脚本产出,版本号统一取自 version.py (它同时驱动命令行界面、Inno 安装脚本与软件「关于」框):

python build.py                  # 便携单文件 EXE
python build.py --onedir         # 便携目录版(启动更快,便于排查缺依赖)
python build.py --installer      # 目录版 + Inno Setup 安装包(自动调用 ISCC)
python build.py --iss-only       # 已有打包产物,只想重新生成安装脚本/安装包
python build.py --clean-only     # 只清理 dist/ build/
python build.py --installer -v   # 打印 PyInstaller / ISCC 完整输出

产物布局:

模式 产物
默认 dist/Apy_Subsequence.exe(约 110 MB 单文件)
--onedir dist/Apy_Subsequence/
--installer dist/installer/Apy_Subsequence_Setup_v<版本>.exe + 同名 .iss

说明:

  • Inno Setup:本机装了 Inno Setup 6 时会自动用 ISCC.exe 编译出安装包; 未安装则只生成 .iss 脚本(脚本随后可在装好 Inno 的机器上双击编译)。 也可由环境变量 ISCC 指定编译器路径。
  • 汉化:官方 Inno 不带简体中文语言文件,仓库内置了 assets/installer/ChineseSimplified.isl(覆盖向导可见文案,其余回退英文)。
  • 向导配图:由 Pillow 从应用图标合成 wizard_image.bmp / wizard_small_image.bmp; 没有 Pillow 时自动跳回 Inno 默认配图。
  • version.py 是单一版本源:改版本只改这一个文件,build.py、安装脚本、 窗口标题与「关于」框会同步。
  • AppId(GUID)发布后不可修改,否则系统会把它当另一个软件,留下双份卸载入口。

依赖检查工具

项目提供了依赖检查脚本,可以验证当前环境的包安装情况:

python check_dependencies.py

该工具会显示:

  • ✓ 正确安装的包
  • ⚠ 版本不匹配的包
  • ✗ 缺失的包
  • 可能不必要的大包

虚拟环境清理与重建

如需重建虚拟环境,直接删除后重建即可(仓库中不再附带重建脚本):

deactivate
rm -rf .venv
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt

预测功能依赖(可选)

要使用 ARIMA 预测,安装:

pip install statsmodels

未安装时预测会自动回退到线性回归 / 移动平均,功能不会中断。

运行测试

pip install pytest
python -m pytest tests/ -v

测试共 116 项,覆盖:

  • 领域模型(test_dataset.py):方向推断与翻转、时间轴构造与替换、频率别名换算
  • 数据接入(test_data_service.py):多格式读取、清洗、标准化、序列/时间维合并
  • 子序列算法(test_subsequence.py):MASS 与朴素滑窗计算的一致性(误差 1.15e-07)、 Motif 对插入重复波形的识别、DTW 与带状约束、层次聚类对明显分组的分离
  • 季节分解(test_data_analysis.py):不得伪造时间轴、不得在周期未知时默认取 12、 索引有缺口时仍能正确判频
  • 主窗口数据分发(test_main_window.py):在途的加载结果不得静默覆盖用户改动; 标签页标题/tooltip、Ctrl+1..6 直达、空数据态(无头环境自动跳过)
  • 模拟数据生成(test_generate_sample_data.py):同种子逐值可复现、日期列能被 自动识别为时间轴、生成的数据可驱动季节分解(周期 12)

CI 配置见 .gitee/workflows/ci.yml。

运行应用

运行桌面版本(基于PyQt5):

python main.py

如果遇到Qt平台插件错误(如Could not find the Qt platform plugin "windows"),请设置环境变量:

$env:QT_QPA_PLATFORM_PLUGIN_PATH=".venv\Lib\site-packages\PyQt5\Qt5\plugins"

然后再次运行:

python main.py

或者可以一条命令执行:

$env:QT_QPA_PLATFORM_PLUGIN_PATH=".venv\Lib\site-packages\PyQt5\Qt5\plugins"; python main.py

配置说明

配置文件

系统支持通过 config.json(与 config.py 同级)持久化配置。第一次运行时使用默认值,修改配置后自动保存。

配置优先级

  1. 环境变量 LTV_DATA_PATH(覆盖配置文件中的 DATA_PATH)
  2. config.json 中的持久化配置
  3. 代码中的默认值

环境变量

变量名 说明 默认值
LTV_DATA_PATH 数据文件路径 data/sample_ltv_monthly.csv
QT_QPA_PLATFORM_PLUGIN_PATH Qt平台插件路径 .venv\Lib\site-packages\PyQt5\Qt5\plugins

使用指南

主要界面

应用启动后显示六个标签页:

  1. LTV序列比对图:显示各序列的生命周期价值变化
  2. OncoPrint图:以OncoPrint形式展示客户生命周期状态图谱(SAX 符号化)
  3. 热力图:以热力图展示数据相关性
  4. 数据表格:以表格形式展示原始数据(分页)
  5. 分析工作台:统计摘要 / 相关性(含显著性)/ 特征重要性 / 聚类 / DTW 形态距离 / Motif 发现 / 季节分解,结果可导出
  6. 子序列分析:形态检索 / Motif 发现 / DTW 形态聚类三个子视图

交互操作

  • 点击查看:在LTV序列比对图上点击数据点可查看详细信息
  • 缩放平移:使用鼠标滚轮缩放,拖拽平移视图
  • 图表导出:使用图表工具栏中的相机图标导出图片
  • 加载新数据:使用"加载数据"按钮可以选择新的数据文件
  • 拖放载入:把数据文件直接拖到窗口上即可加载(多文件请用「批量加载并合并」)
  • 内置样例:Ctrl+Shift+L 一键载入随包样例数据,无需先找数据文件
  • 视图切换:Ctrl+1 … Ctrl+6 直达六个标签页,标签本身也有悬浮说明; 切换时状态栏会回显该视图"看的是什么"
  • 主题切换:在"视图"菜单中可以切换深色/浅色模式

所有操作结果都走同一套状态栏提示(成功 ✓ / 警告 ⚠ / 错误 ✗ 三级配色承载), 错误与警告同时写入日志,可在「帮助 → 打开日志目录」回看详情;状态栏右侧 常驻当前数据集摘要(时间点数 × 序列数 / 行列方向 / 时间轴类型),无需回去 对照加载对话框确认解读方式。加载期间工具栏按钮禁用,避免并发读取互相覆盖。

没有载入数据时,六个标签页会各显示一句常驻提示,而不是留一片空白画布。

数据筛选和分析

在"LTV序列比对图"标签页中,提供了丰富的数据分析功能:

  1. 序列筛选:在"序列筛选"输入框中输入关键词,点击"应用筛选"按钮筛选包含关键词的序列
  2. 时间范围选择:在"开始时间"和"结束时间"输入框中输入时间索引,点击"应用时间范围"按钮限定显示的时间范围
  3. 统计指标计算:点击"计算统计指标"按钮计算并显示各序列的基本统计信息(均值、标准差、最小值、最大值)
  4. 趋势线拟合:点击"应用趋势线"按钮为序列添加线性/二次/三次多项式趋势线
  5. 异常检测:点击"检测异常"按钮使用 Z-Score 或 IQR 方法检测并标记异常点

样例数据

仓库自带两份可直接使用的样例:

文件 形状 说明
data/sample_ltv_monthly.csv 36 期 × 24 序列 默认。首列 stat_month 为真实日期,月频,季节周期 12
data/sample_ltv_weekly.csv 104 期 × 12 序列 周频,首列 stat_week
data/transposed_data.csv 24 × 23 旧样例,纯整数下标,用作对照

需要其他规模或频率时,用生成器现场造一份(同一种子逐字节可复现):

python scripts/generate_sample_data.py                             # 默认月频 36×24
python scripts/generate_sample_data.py --freq week --periods 104 --sequences 12
python scripts/generate_sample_data.py --missing 0.01              # 注入 1% 缺失值
python scripts/generate_sample_data.py --periods 60 --sequences 40 --out data/big.csv

数值是当期生命周期价值贡献(元/人/期)而非累计值——生命周期有起有落, 子序列分析、异常检测与 OncoPrint 阶段划分才有意义。每条序列从六种形态原型 (健康增长 / 自然流失 / 强季节性 / 早期流失 / 阶梯跃迁 / 成熟留存)中取样, 再叠加市场级季节性、缓慢增长、一次行业回落与 AR(1) 噪声,并注入若干尖峰异常。

数据方向

数据的「行=时间点、列=序列」方向由导入时自动推断。若推断错误 (例如你的 CSV 是序列在行上),可通过菜单 编辑 → 翻转数据方向 (Ctrl+T)一键纠正,无需修改源文件。

时间轴设置

菜单 编辑 → 时间轴与数据方向...(Ctrl+Shift+T)打开时间轴向导,一次性确认:

  1. 数据方向:强制纠正自动推断的方向;
  2. 时间轴三种取法:
    • 整数下标(保持现状)
    • 指定起点与频率:如「2023-01-01 起、按月」,生成等间距真实日期轴
    • 使用数据中的日期列:把被误当作序列的日期列提取为时间轴 (支持文本日期与 20240101 这类整数日期,后者是自动嗅探识别不到的)

设置后底部会显示推断出的频率与季节周期。为什么必须设置:改造前时间轴只有 整数下标,季节分解为此伪造了一段 2020-01-01 起的日频轴并把周期硬编码为 12, 用户看到的"季节性"没有实际依据;现在周期只能来自真实时间轴,判不出来就明确报错。

多文件合并

文件 → 批量加载并合并 会询问这些文件代表"多条序列"还是"多个时间段", 并按选择做一致性校验(改造前是无条件纵向堆叠,多文件代表多条序列时会破坏结构)。

预测功能

在菜单栏的"分析"菜单中提供时间序列预测(后台线程执行,可取消):

  1. 自动:ARIMA → 线性回归 → 移动平均 依次回退
  2. ARIMA:基于 ARIMA 模型(需要 statsmodels)
  3. 线性回归:最小二乘趋势外推
  4. 移动平均:带趋势项的朴素基线

聚类、相关性分析、特征重要性的结果会沉淀到「分析工作台」标签页。

技术架构

主要技术栈

代码结构

LTV_apy_subsequence/
├── main.py                    # 程序入口(唯一调用 setup_logging 的位置)
├── config.py                  # 配置管理(支持 config.json 持久化)
├── config.json                # 持久化配置文件(自动生成)
├── core/                      # 领域模型层(禁止 import PyQt5)
│   └── dataset.py             # SequenceDataset / DatasetSchema / TimeAxis
├── analysis/                  # 算法层(禁止 import PyQt5)
│   └── subsequence.py         # MASS / DTW / Motif / PAA / SAX 内核
├── data/                      # 数据接入层
│   ├── loader.py              # 按扩展名分发的统一读取入口 read_any()
│   ├── extended_loader.py     # 兼容层(已弃用,委托 loader)
│   ├── sample_ltv_monthly.csv # 默认样例:月频 36 期 × 24 序列(含真实日期列)
│   ├── sample_ltv_weekly.csv  # 周频 104 期 × 12 序列
│   └── transposed_data.csv    # 旧样例:24×23,整数下标(对照用)
├── services/                  # 应用服务层
│   ├── data_service.py        # 唯一数据门面:读/校验/清洗/标准化/合并
│   ├── task_service.py        # 后台任务封装(预测与分析均走这里)
│   └── theme_service.py       # matplotlib 主题同步
├── gui/                       # 展示层
│   ├── main_window.py         # 主窗口
│   ├── dialogs/
│   │   ├── time_axis.py       # 时间轴与数据方向向导
│   ├── tabs/                  # 标签页
│   │   ├── ltv_tab.py         # LTV 序列比对图(pyqtgraph)
│   │   ├── oncoprint_tab.py   # OncoPrint 状态图谱(SAX + imshow)
│   │   ├── subsequence_tab.py # 形态检索 / Motif / DTW 形态聚类
│   │   ├── heatmap_tab.py     # 相关性热力图
│   │   ├── table_tab.py       # 数据表格(分页)
│   │   └── analysis_tab.py    # 分析工作台
│   ├── dialogs/               # 数据处理 / 导出 / 预测对话框
│   └── widgets/config_dialog.py
├── utils/                     # 工具
│   ├── logging_setup.py       # 日志(Qt 应用数据目录 + 轮转)
│   ├── theme.py               # QSS 主题
│   ├── font_manager.py        # 中文字体
│   ├── chart_style.py         # 色板与 pyqtgraph 主题
│   └── data_analysis.py       # 统计/聚类/预测算法
├── scripts/                   # 命令行脚本
│   └── generate_sample_data.py  # 生成确定性 LTV 模拟数据
├── tests/                     # 单元测试(pytest)
├── assets/                    # 落地页静态资源
│   ├── site.css               # index.html 样式(原内嵌 <style>)
│   └── site.js                # index.html 交互(原内嵌 <script>)
├── index.html                 # 项目落地页(语义标记 + 外链资源)
├── .gitee/workflows/ci.yml    # CI
├── build.py                   # 构建脚本
├── LTV_apy_subsequence.spec   # PyInstaller spec
├── README.md
├── requirements.txt
└── LTV_apy_subsequence.ico

分层约束:core/ 与 analysis/ 禁止 import PyQt5,因此可单测、 可复用为 CLI/库。依赖方向严格单向向下:gui → services → analysis/core → io。

性能优化措施

大数据处理

  • 使用多线程加载数据,避免阻塞UI线程
  • 对超过阈值的数据序列进行分页处理
  • 限制同时显示的序列数量

渲染优化

  • 图表采用增量渲染策略
  • 合理设置图表分辨率

内存管理

  • 及时释放不需要的数据对象
  • 使用高效的数据结构存储中间结果

故障排除

常见问题

  1. 数据文件未找到

    Exception: 文件未找到,请确保文件路径正确
    

    解决方法:

    • 检查数据文件是否存在
    • 确认环境变量 LTV_DATA_PATH 设置正确
    • 确保有文件读取权限
  2. 数据格式错误

    Exception: 数据文件格式错误,请检查CSV文件格式
    

    解决方法:

    • 检查CSV文件格式是否正确
    • 确保文件编码为UTF-8
  3. Qt平台插件错误

    qt.qpa.plugin: Could not find the Qt platform plugin "windows" in ""
    

    解决方法:

    • 设置环境变量 QT_QPA_PLATFORM_PLUGIN_PATH 指向正确的插件目录
    • 通常路径为 .venv\Lib\site-packages\PyQt5\Qt5\plugins
  4. 中文显示为方框或乱码

    RuntimeWarning: Glyph XXXX missing from current font
    

    解决方法:

    • 确保系统已安装中文字体(如黑体、微软雅黑等)
    • 程序会自动配置中文字体支持,如仍有问题可手动设置系统字体
  5. 趋势线或异常检测功能报错

    TypeError: 'NoneType' object is not callable
    

    解决方法:

    • 此问题已在最新版本中修复,请确保使用最新的代码版本
  6. 选择了 Excel 文件却提示无法读取 解决方法:

    • 安装 pip install openpyxl
    • 未安装时文件对话框会自动隐藏 Excel 选项,不会出现"能选却读不了"
  7. 日志在哪里

    • 菜单 帮助 → 打开日志目录 可直接打开
    • Windows 默认位于 %LOCALAPPDATA%\LTVSubsequence\...\logs\app.log
    • 日志单文件上限 2 MB,保留 3 个历史文件

开发计划

  • 深色模式支持(含 pyqtgraph 主图同步)
  • 数据筛选和分析功能
  • 配置持久化(config.json)
  • 导出功能完整实现(按视图能力过滤格式,矢量/位图/数据分流)
  • 预测功能(ARIMA / 线性回归 / 移动平均,异步可取消)
  • 单元测试覆盖(领域模型 / 数据接入 / 子序列算法 / 季节分解 / 主窗口 / 数据生成器,116 项)
  • 子序列分析内核(MASS / DTW / Motif / SAX)
  • 分析结果沉淀(分析工作台)
  • 数据方向显式化(orientation + 一键翻转)
  • 子序列检索 / Motif / DTW 聚类的独立视图页
  • 时间轴导入向导(真实日期起点/频率/日期列,含整数型 20240101)
  • 时间轴感知的季节分解与预测(不再伪造时间轴、不再硬编码周期 12)
  • 确定性模拟数据生成器(含真实日期列,六种形态原型)
  • 落地页重构(样式/脚本外置,内容同步至当前版本,支持深色模式与打印)
  • 空数据态提示、文件拖放载入、Ctrl+1..6 视图直达
  • 统一构建脚本:便携单文件 / 目录版 / Inno Setup 安装包(自动调用 ISCC)
  • 安装向导汉化(内置 assets/installer/ChineseSimplified.isl)与向导配图合成
  • 版本号单一来源 version.py(打包、安装脚本、界面标题、关于框共用)
  • Ctrl+Shift+L 内置样例数据、状态栏三级提示、数据集摘要胶囊、忙碌态防重入
  • 工作区持久化(.ltvproj)
  • 图表插件化注册表
  • 自动更新检查
  • 打包体积优化(现状:目录版 294 MB → 安装包 70.9 MB、单文件约 110 MB)

贡献指南

欢迎提交Issue和Pull Request来帮助改进本项目。

许可证

本项目仅供学习交流使用。

About

数据子序列分析工具,用于分析和比较客户生命周期价值数据序列。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages