跳转至

Step1 报告:邮政对话筛选

邮政相关对话筛选与向量空间可视化结果报告

本报告汇总 week1/filter/outputs/vis 目录下的全部可视化结果,重点说明邮政相关对话的筛选流程、向量空间分布特征,以及不同类型对话在长度维度上的差异。

filter 模块的整体流程是:

  1. 先把每条完整对话编码成 embedding
  2. 再使用 gpt-oss:20b 判断该对话是否和快递 / 邮政相关
  3. 最后把全部对话 embedding 降到二维空间中做可视化
  4. 同时比较“相关对话”和“其他对话”的 token 长度分布

这些图主要围绕两个问题展开:

  1. 被筛出来的快递 / 邮政相关对话,在 embedding 空间中是否形成聚类
  2. 相关对话与其他对话,在长度分布上是否存在差异

1. 方法概述

1.1 Embedding

当前实现以:

  • 单条完整对话 = 一个编码单位

也就是说,一整段用户与客服的多轮对话会先拼起来,再送进 embedding 模型。
这样得到的向量更接近整段对话的主题,而不是某一句局部表述。

实现细节:

  • 编码粒度固定为“单条完整对话”
  • 每条对话会被整理成带 speaker: utterance 结构的完整文本
  • embedding 结果会分 train / val / test 写入同一个 HDF5 文件
  • HDF5 存储采用 gzip 压缩,压缩等级为 1
  • 写入方式采用断点续跑友好的追加方案,并通过 completed 属性记录当前 split 已完成样本数

1.2 LLM Filter

在得到 embedding 之后,并不会直接生成类别标签,而是先用 gpt-oss:20b 搭了一个二分类 agent,对每条完整对话做一次相关性判断。
这个 agent 只做一件事:

  • 该对话是否和快递 / 邮政主题相关

当前实现中,agent 的 system prompt 为:

你是一个严格的中文客服数据分类器。判断给定对话是否和快递、物流、配送、邮政、EMS、运费、签收、揽收、退费、地址修改等相关。如果相关,只输出 true。如果不相关,只输出 false。禁止输出其他任何内容。

实际调用时:

  • system prompt 只放分类规则和输出约束
  • user prompt 只放完整对话文本
  • 输出被严格限制为 true / false

实现细节:

  • 调用模型为 gpt-oss:20b
  • 请求接口使用的是 Ollama chat 接口
  • temperature 固定为 0
  • 单条对话最多重试 3
  • 重试间隔为 1
  • 结果会周期性写入 postal_filter_results.json
  • 当前保存频率为每 32 条样本落盘一次,支持断点续跑

所以这一步最后得到的是一个很明确的二分类结果:

  • True:快递 / 邮政相关对话
  • False:其他对话

1.3 PCA

PCA 是线性降维方法。
其基本原理是:在高维空间中寻找能够最大程度保留数据方差信息的正交投影方向,再将原始向量映射到这些主成分构成的低维空间。
在本实验中,PCA 的主要特点包括:

  • 稳定
  • 结果容易重复
  • 更适合观察整体分布趋势

局限是:

  • 对复杂非线性结构不够敏感

分析目的:

  • PCA 先给出一个线性视角下的整体分布图。
  • 它主要看的是:被筛出来的邮政相关对话,在整体空间里有没有集中到某些区域。

采用该可视化步骤的原因:

  • embedding 本身是高维向量,人没法直接从原始数值里看出分布结构。
  • 不做降维的话,虽然向量都在,但很难直观看到样本是不是聚在一起、是不是有分界。
  • 所以这里必须先降到低维;PCA 先给出一个整体视角。

实施口径:

  • 使用 sklearn.decomposition.PCA
  • 降维目标固定为二维,即 n_components=2
  • 随机种子固定为 42

参数说明:

  • n_components=2 的含义是把高维 embedding 压到二维平面,目的不是保留全部信息,而是为了获得人能直接观察的可视化结果。这里选二维,是因为报告中的散点图需要落在平面上,便于直观看聚集趋势。
  • random_state=42 的作用是固定随机性,保证多次运行时结果更稳定,避免每次图像结构都发生明显变化,影响前后版本比较。

1.4 t-SNE

t-SNE 是非线性降维方法,擅长把局部邻近结构在二维平面上拉开。
其基本原理是:先在高维空间中把样本之间的相似关系转成概率分布,再在低维空间中寻找另一组概率分布,使两者尽可能接近,从而保留高维空间中的局部近邻关系。
在本实验中,t-SNE 的主要特点包括:

  • 更适合观察局部聚类
  • 对近邻结构较敏感
  • 可视化聚类感通常更强

它更适合用来看:

  • 某些局部簇是否清晰

但它也更容易受参数影响,并且全局距离解释性不如 PCA。

分析目的:

  • t-SNE 主要看局部邻域结构,判断邮政相关对话会不会形成更清晰的小簇。
  • 如果 PCA 只能看到比较弱的整体趋势,那么 t-SNE 往往更容易把局部结构拉出来。

补充这一方法的原因:

  • PCA 更适合看整体线性趋势,但对复杂非线性结构不够敏感。
  • 如果相关对话在高维空间里主要体现为局部邻域上的靠近,而不是全局线性分离,那么只看 PCA 往往不够。
  • 因此这里再做 t-SNE,是为了把局部近邻关系展开,看看是否存在更清晰的局部聚类。

实施口径:

  • 使用 sklearn.manifold.TSNE
  • 降维目标固定为二维
  • 初始化方式为 init="pca"
  • perplexity=30
  • 随机种子固定为 42
  • n_jobs 设置为 CPU 核数减 2

参数说明:

  • init="pca" 表示先用 PCA 给出一个初始二维布局,再在这个基础上继续做 t-SNE 优化。这样做的意义是让初始状态更稳定,也能减少完全随机初始化带来的波动。
  • perplexity=30 控制的是每个样本在局部邻域里大致会参考多少个邻近点。它不是“越大越好”或“越小越好”的参数:过小会让图过于碎裂,过大又会削弱局部结构。当前取 30,是为了在局部聚类感和整体可读性之间取一个常见折中值。
  • random_state=42 的意义是固定随机性,让结果更容易复现。
  • n_jobs=CPU-2 的作用是保留两颗 CPU 核心给系统和其他任务,避免可视化过程把整机资源吃满。

1.5 UMAP

UMAP 也是非线性降维方法。
其基本原理是:先在高维空间中构建近邻图,近似刻画数据所在流形的局部拓扑结构,再在低维空间中重建这一结构,从而尽可能保留样本之间的邻域关系。
相比 t-SNE,它往往更兼顾:

  • 局部邻域结构
  • 一定程度的全局结构
  • 可视化效率与稳定性通常较好

因此在 embedding 可视化里经常和 PCA、t-SNE 一起使用。

分析目的:

  • UMAP 是第三个视角,用来和 PCAt-SNE 交叉对照。
  • 如果三种方法都指向差不多的聚集趋势,那么“筛选结果背后确实有语义结构”这个判断就更站得住。

引入该方法的原因:

  • 如果只依赖一种降维方法,很容易把某一种算法特有的视觉结果误当成真实结构。
  • UMAP 在很多情况下比 t-SNE 更容易同时保留局部结构和部分整体结构,因此适合做交叉验证。
  • 加上 UMAP 之后,三种图如果都指向相近趋势,报告里的判断就更有依据。

实施口径:

  • 使用 umap-learn
  • 降维目标固定为二维
  • 随机种子固定为 42
  • n_jobs 同样设置为 CPU 核数减 2
  • 若运行环境未安装 umap-learn,则该部分会被直接跳过

参数说明:

  • 二维降维的意义与 PCA、t-SNE 一样,都是为了把高维结构映射成可以直接观察的平面图。
  • random_state=42 用于固定随机性,降低不同运行之间的图形漂移。
  • n_jobs=CPU-2 仍然是资源控制参数,目的是减少可视化过程对整机的占用。
  • “未安装依赖则跳过” 这一实现的意义是让主流程保持可运行,不因为少一个可视化库就把整条分析链路卡死。

1.6 Token 分布直方图

除了降维图以外,当前还增加了按标签叠加的对话长度分布图。
这里的长度统计口径为:

  • 对整条对话文本先去空格
  • 再用 cl100k_base 编码
  • 统计 token 数

图中两种颜色分别代表:

  • 灰色:其他对话
  • 红色:快递 / 邮政相关对话

图例中的 n 表示该类别包含的样本数量。

分析目的:

  • token 长度分布这一组图,是想从文本长度这个辅助维度再看一眼筛选结果。
  • 它不是拿长度直接当判别条件,而是想看看被筛中的对话是不是普遍更长一些。

补充长度分析的原因:

  • 仅看降维图,只能看到空间结构,无法知道两类样本在文本长度上是否还有明显差异。
  • 但如果只看长度,又会忽略真正决定相关性的语义内容。
  • 因此这里单独加长度分布图,不是为了替代语义筛选,而是为了给结果解释增加一个更直观的辅助维度。

实施口径:

  • 对每条完整对话重新拼接 speaker: utterance
  • 先去掉空格
  • 再用 cl100k_base 编码
  • is_postal_related 标签拆成两组长度序列
  • 最后将两组样本叠加画到同一张直方图中

2. 训练集结果解读

2.1 PCA

train_pca

该图对应训练集 embedding 经 PCA 降到二维后的分布。
图中:

  • 灰色点表示其他对话
  • 红色点表示被 LLM 识别为快递 / 邮政相关的对话

红色点如果在某些区域更集中,相关对话在 embedding 空间里就存在一定的主题聚集趋势。

结果解读:

  • 训练集 PCA 图里,红色样本在部分区域的密度更高,“邮政/快递相关”对话在整体线性空间中已经有一定的聚集倾向。
  • 但灰色和红色样本仍有大范围重叠,只靠线性投影还不足以把两类样本清楚分开,继续看非线性降维是有必要的。

2.2 t-SNE

train_tsne

这一图更强调局部邻域结构。
如果红色点在 t-SNE 图上形成明显簇状区域,往往说明“邮政 / 快递相关”这一语义标签在 embedding 空间中有一定可分性。

结果解读:

  • 训练集 t-SNE 图里,红色样本的局部聚集通常比 PCA 更明显,说明相关对话在近邻结构上更接近。
  • 如果红色样本不是只形成一个簇,而是出现多个小簇,那更像是在提示“邮政相关”内部还包含若干彼此相关但不完全相同的业务子主题。

2.3 UMAP

train_umap

这一图提供了另一种非线性降维视角,用来和 PCA、t-SNE 交叉对照,避免只依赖单一方法得出结论。

结果解读:

  • 训练集 UMAP 图如果也呈现红色样本在局部区域更集中,相关对话的聚集现象就不太像是单一降维算法造成的偶然视觉结果。
  • PCAt-SNEUMAP 三种方法都指向相似趋势时,可以认为 embedding 已经捕捉到一部分与邮政相关主题有关的空间结构。

2.4 Token 长度分布

train_token_hist_by_label

这里把训练集中的两类对话叠加到同一张直方图里,主要看:

  • 快递 / 邮政相关对话是否更长
  • 两类对话长度分布是否存在明显重叠或偏移

结果解读:

  • 训练集长度直方图如果显示红色分布整体略向右,被筛中的相关对话平均长度就会略高,这和物流查询、售后处理等场景通常需要更多信息交互是一致的。
  • 但两类分布仍有显著重叠,长度差异只能作为辅助证据,不能直接证明某条对话是否属于邮政相关样本。

3. 验证集结果解读

3.1 PCA

val_pca

这里用验证集 PCA 图检查相关对话是否仍然落在相似的 embedding 区域中。

结果解读:

  • 验证集 PCA 图与训练集呈现相近趋势,这表明筛选出的相关对话在不同 split 中具有相似的整体空间位置分布。

3.2 t-SNE

val_tsne

这里更关注验证集的局部簇结构是否和训练集一致。

结果解读:

  • 验证集 t-SNE 中若仍可观察到红色样本的局部簇结构,则说明训练集中的聚集现象并非偶然,而具有一定可重复性。

3.3 UMAP

val_umap

这里借助验证集 UMAP 图判断空间结构是否稳定。

结果解读:

  • 验证集 UMAP 若与训练集保持一致,则进一步支持“embedding + LLM filter” 所得到的标签具有一定的结构性和解释性。

3.4 Token 长度分布

val_token_hist_by_label

这里比较验证集里两类对话的 token 长度分布。
如果分布趋势和训练集相近,说明长度模式较稳定。

结果解读:

  • 验证集两类长度分布若与训练集相似,则说明被筛中样本的长度特征并非训练集中的偶发现象,而是较为稳定的数据属性。

4. 测试集结果解读

4.1 PCA

test_pca

这里用测试集 PCA 图观察最终评估数据中的两类样本是否保持相近的空间分布规律。

结果解读:

  • 测试集 PCA 仍呈现与训练、验证阶段相近的趋势,这表明相关样本的空间结构具有一定泛化性。

4.2 t-SNE

test_tsne

这里更容易看出局部团簇是否仍然存在。

结果解读:

  • 测试集 t-SNE 中若红色样本仍能形成局部团簇,则说明筛中的相关对话在 embedding 空间中并非随机散布,而具有一定的语义聚集基础。

4.3 UMAP

test_umap

这里将测试集 UMAP 与 PCA / t-SNE 一起看,用来判断测试集是否仍具备相似的主题结构。

结果解读:

  • 测试集 UMAP 若保持类似的局部聚集形态,则说明这一结构在训练集、验证集和测试集三个 split 中均较为一致。

4.4 Token 长度分布

test_token_hist_by_label

这里反映测试集中相关对话与其他对话的长度差异情况。

结果解读:

  • 测试集长度分布若仍显示红色样本略长或更集中,则说明长度差异并非训练集特有现象,而是在不同数据划分中均有体现。

5. 全量数据结果解读

5.1 PCA

all_pca

这里把 train / val / test 合并后统一降维,适合从全局上看全部对话的空间分布结构。

结果解读:

  • 全量 PCA 图表明,在整体数据空间中确实存在更容易聚集“邮政相关”样本的区域,这说明筛选结果具有一定的位置偏好。
  • 不过,这种位置偏好仍然主要体现为趋势性证据,不能直接替代下游分类或聚类性能指标。

5.2 t-SNE

all_tsne

这里更适合观察整个数据集范围内,相关对话是否形成更稳定的局部聚类。

结果解读:

  • 全量 t-SNE 是最能直观体现局部聚类感的图像之一,其结果表明“邮政相关”样本在低维空间中呈现出更明显的局部聚集。
  • 若红色样本形成多个相对分离的聚集区,则可合理推断该类样本内部包含查询、售后、配送、工单等多个业务子主题,而非单一类型对话。

5.3 UMAP

all_umap

这里提供另一种整体空间结构视图,用来辅助判断 embedding 对主题的表达效果。

结果解读:

  • 全量 UMAP 若与 t-SNE 呈现相似的局部聚集趋势,则会进一步支持“embedding 已学习到与业务主题有关的空间结构”这一判断。

5.4 Token 长度分布

all_token_hist_by_label

这里把整个数据集中的两类样本长度分布叠加到一起,是长度比较最直观的一张总览图。

结果解读:

  • 全量长度直方图能够直接反映两类对话是否存在整体长度偏移,因而是长度分析中最具总览意义的一张图。
  • 若红色样本平均更长,则这一现象可以被视为一个具有解释力但并不充分的辅助特征,说明相关业务对话通常包含更多信息交换与状态确认过程。

6. 图像判读说明

6.1 降维图不是分类准确率

这些散点图的作用是帮助理解 embedding 空间结构,不是直接证明分类器性能。
它们可以说明:

  • 同类语义样本是否更接近
  • 被筛出的相关对话是否在某些区域更密集

但它们不能直接替代准确率、召回率之类的指标。

6.2 多种降维方法需要交叉看

单看某一张图,容易受到降维算法本身特性的影响。
因此更合理的做法是:

  • PCA 看整体线性结构
  • t-SNE 看局部聚类
  • UMAP 看兼顾局部和部分全局结构的分布

三者一起看,结论会更稳。

6.3 Token 直方图提供了长度维度的补充解释

如果只看降维图,我们只知道“空间上怎么分布”。
而加上 token 长度分布图后,还能回答:

  • 邮政相关对话是不是普遍更长
  • 是否存在一类对话明显偏短或偏长

这能帮助理解筛选结果背后的数据特征。

整体判断:

  • 这组图整体支持“筛中的邮政相关对话在 embedding 空间中具有一定结构性”这一判断,而不是完全随机分布。
  • 但这些图仍然只能作为可解释性证据,不能直接替代严格的分类评估指标。

7. 整体结论

filter 模块的可视化结果可以总结为三层:

  1. Embedding 空间层
  2. 通过 PCA、t-SNE、UMAP 观察全部样本和被筛中样本的空间关系

  3. 标签对比层

  4. 用颜色区分“邮政相关”和“其他对话”
  5. 并在图例中直接展示两类样本数

  6. 长度分布层

  7. 通过 token 直方图比较两类对话在长度上的差异

这些图合在一起,可以形成一个更完整的实验判断:
筛选流程不仅给出了“哪些对话被判定为快递 / 邮政相关”的标签结果,也把这些样本在向量空间中的局部聚集趋势,以及在文本长度维度上的一定差异展示了出来。需要单独说明的是,这些图像结果提供的是可解释性证据,不是分类性能本身;它们更适合用于后面的人工核验、样本整理与主题分析。