Lab 3: 电商数据准备实战

课程:数据库技术与应用:AI时代的基石数据技能
授课教师:王健楠 (计算机科学与技术系)
学期:2026年(春季)

实验目的与学习目标

完成本实验后,你应能够:

  1. 建立数据准备的整体认知: 理解数据如何从原始异构文本出发,经过文本清洗、候选生成、相似度验证与效果评估,最终形成可用于目录整合的匹配结果。
  2. 熟练掌握近似匹配的核心技术: 能够在真实数据上综合运用正则表达式、JaccardJoin、MinHashJoin 以及 Precision、Recall、F1、candidate recall 等指标,完成跨源匹配与方法比较。

实验背景

你正在一家电商平台的数据治理组实习。团队准备整合两份外部商品目录,建设统一的商品目录底表,用于搜索、推荐、库存整合和价格治理。

困难在于:同一商品在不同来源中的写法并不一致。标题里可能混有标点、版本号、括号附注和厂商名差异;如果直接对两张表做两两比较,计算代价又会很高。

本次实验中,你将沿着一条完整的商品匹配流水线完成工作:先清洗文本,再生成候选对,再做相似度验证,最后输出一份可用于汇报的对比结果。


评分规则: 共 100 分(4 个任务)。

作答要求: 请在包含 # YOUR CODE HERE 的代码单元中完成实现,并删除 raise NotImplementedError();每完成一个任务后,运行紧随其后的测试单元。

第 0 步:数据加载与环境准备

本实验提供两套商品数据:

你可以在下面代码块中修改 PRODUCT_DATASET = "sample""full" 来切换数据集。切换后请重新执行整本 notebook。

下面的代码会完成:


商品匹配任务主线

本实验围绕一条完整的商品匹配流程展开:

正则清洗 → JaccardJoin / MinHashJoin → 效果对比报告

建议按顺序完成。前一个任务的输出会作为后一个任务的输入。


任务 1: 数据清洗 (20 分)

任务背景

两张商品表中的同一商品,往往会因为标点、大小写、版本号和括号附注的差异而写成不同形式。正式匹配前,必须先把原始文本清洗成可比较的表示。

你需要完成

  1. 实现 normalize_text(text)
    • 缺失值按空字符串处理;
    • 全部转为小写;
    • r"[^a-z0-9]+" 将连续的非字母数字字符替换为一个空格;
    • 压缩多余空白并去掉首尾空格。
  2. 实现 extract_version_token(text)
    • 识别 2.54.110.4.8 这类至少包含一个小数点的版本号;
    • 若版本号前带 vV,返回结果时不要保留该前缀;
    • 只返回第一个版本号;若不存在则返回 None
  3. 实现 build_product_df(df, cols)
    • Amazon 使用 build_product_df(amazon, ['title', 'manufacturer'])
    • Google 使用 build_product_df(google, ['name', 'manufacturer'])
    • 先拼接 cols 中各列,再调用 normalize_text()
    • cols[0] 对应的原始标题列提取 version_token,并判断 has_bracket_note

最终产出

请生成 amazon_prepgoogle_prep。它们至少包含以下字段:

任务 2: 用 JaccardJoin 实现商品近似匹配 (30 分)

任务背景

完成清洗后,我们已经拿到了可比较的 token 表示。接下来要实现一个规则式连接基线:先基于共享 token 生成候选对,再用 Jaccard 相似度做精确验证。

你需要完成

请在 JaccardJoin 类中实现以下 3 个方法:

  1. jaccard_similarity(self, tokens1, tokens2):返回两个 token 序列的 Jaccard 相似度。
  2. generate_candidates(self, df1, df2)
    • 基于共享 token 生成候选对;
    • 不允许先做笛卡尔积再筛选;
    • 返回的 cand_pairs 至少包含 id1, joinKey1, id2, joinKey2, shared_token_count
  3. verify_candidates(self, cand_df, threshold):返回带 jaccard 列的 scored_pairs,以及满足阈值条件的 verified_pairs

最终产出

请在 Amazon 与 Google 商品数据上运行 JaccardJoin,并生成:

任务 3: 用 MinHashJoin 实现商品近似匹配 (30 分)

任务背景

当数据规模变大时,JaccardJoin 往往还不够高效。为此,团队希望引入 MinHash + LSH,在尽量保留潜在匹配对的同时,进一步减少需要精确比较的记录对数量。

你需要完成

请在 MinHashJoin 类中实现以下 5 个方法:

  1. token_to_id_func(self, left_join_keys, right_join_keys)
    • 基于两侧 joinKey 中出现的全部唯一 token;
    • 按字典序排序并从 1 开始编号;
    • 返回 token_to_id
  2. minhash_signature(self, token_id_set):返回一条记录的 MinHash 签名。
  3. sig_similarity(self, sig1, sig2):用两个签名中对应位置相等的比例估计 Jaccard 相似度。
  4. generate_candidates(self, df1, df2)
    • 在类内部完成 token 编号、签名生成、LSH 分桶和候选对生成;
    • 再用签名估计 Jaccard 相似度;
    • 返回 minhash_cand_pairs,至少包含 id1, id2, estimated_jaccard
  5. verify_candidates(self, cand_df, threshold):返回 scored_pairsverified_pairs,其中 verified_pairs 只保留 estimated_jaccard >= threshold 的记录。

最终产出

请在 Amazon 与 Google 商品数据上运行 MinHashJoin,并生成:

任务 4: 生成商品匹配效果对比报告 (20 分)

任务背景

现在你已经得到了两套匹配结果。接下来,你需要把它们整理成一份可以直接向团队汇报的效果报告,回答两个核心问题:

你需要完成

  1. 实现函数 compute_prf(pred_pairs, true_pairs),返回 (precision, recall, f1)
  2. 基于任务 2 和任务 3 的输出,分别生成:
    • jaccard_candidate_metrics, jaccard_metrics
    • minhash_candidate_metrics, minhash_metrics
  3. 最终生成名为 comparisonDataFrame

comparison 表格要求

sample 数据示例

PRODUCT_DATASET = "sample" 且使用当前默认 MinHash 参数时,comparison 的结果示例如下:

index candidate_count reduction_ratio covered_true_pairs candidate_recall precision recall f1
jaccard_join 84 0.671875 16 1.000000 1.000000 0.375000 0.545455
minhash_join 23 0.910156 15 0.937500 1.000000 0.500000 0.666667

实验圆满结束!

恭喜你完成了电商平台商品目录整合的全部实战任务!你已经亲手走通了一条完整的商品实体解析流程:从文本清洗、候选生成,到相似度验证与结果评估。这个过程正是现实数据治理与数据集成工作中的核心环节。

提交前最终检查: