五金工业品商品名称解析与向量化技术方案
摘要
五金机电建材等工业品的商品名称没有标准格式,同一商品存在大量别名、缩写、型号简写等表述差异,例如"金杯1.5平红色电线5卷"和"红色1.5平方金杯电线5卷"指同一商品。本方案研究从非结构化商品名称中提取品牌、规格、颜色、品名、型号、单位、数量、品类等字段,并进行向量化处理以支持判重和近似度查询。
数据规模:37万+商品 SKU
核心目标:字段解析 + 向量检索 + 判重归一化
一、业务问题定义
1.1 典型商品名称示例
金杯 1.5平方 红色 电线 5卷/箱
舒友 红色 电工胶布 1箱(12卷/箱)
德力西 63A 2P 漏电保护开关 1个
东成 20V 锂电钻套装 1套
304不锈钢六角螺栓 M10*50 全牙镀锌
博世(Bosch) GSB 180-LI 18V 锂电冲击钻
WD-40 专业级防锈润滑剂 400ml
1.2 名称结构分析
工业品名称遵循「品牌 + 规格 + 颜色 + 品名 + 单位/包装」的结构,但存在以下变体:
| 变化类型 | 示例 |
|---|---|
| 词序变化 | "金杯电线" ↔ "电线金杯" |
| 规格简繁 | "1.5平" ↔ "1.5平方" ↔ "1.5mm²" |
| 缩写混用 | "漏保" ↔ "漏电保护器" ↔ "RCD" |
| 品牌别名 | "公牛" ↔ "GONGNIU" ↔ "Bull" |
| 颜色位置 | "红色金杯电线" ↔ "金杯红色电线" |
1.3 待提取字段
| 字段 | 说明 | 示例 |
|---|---|---|
| brand | 品牌 | 金杯、德力西、博世 |
| product_name | 品名 | 电线、开关、胶布 |
| spec | 规格 | 1.5mm²、63A、2P |
| color | 颜色 | 红、黄、蓝 |
| model | 型号 | M10*50、DZ47LE |
| material | 材质 | 304不锈钢、镀锌 |
| unit | 单位 | 卷、箱、个、米 |
| quantity | 数量 | 5、10 |
| category | 品类 | 电线电缆、开关插座 |
二、方案一:规则 + 词典(轻量级)
2.1 核心思想
利用五金工业品命名的规律性,通过正则表达式和词典匹配实现快速解析。
2.2 品牌词典
BRANDS = [
"金杯", "舒友", "东成", "德力西", "正泰", "公牛", "西门子", "欧普",
"雷士", "松下", "3M", "史丹利", "世达", "博世", "力丰", "宏发",
"公牛", "鸿雁", "飞雕", "泰力", "龙胜", "飞利浦", "欧司朗",
]
2.3 规格正则模式
SPEC_PATTERNS = [
(r"(\d+\.?\d*)\s*[平方平米平]", "截面积", "mm²"),
(r"(\d+\.?\d*)\s*[mM][mM]", "直径", "mm"),
(r"(\d+\.?\d*)\s*A", "电流", "A"),
(r"(\d+\.?\d*)\s*V", "电压", "V"),
(r"(\d+\.?\d*)\s*W", "功率", "W"),
(r"(\d+\.?\d*)\s*[Pp]", "功率", "P"),
(r"(\d+\.?\d*)\s*寸", "尺寸", "寸"),
(r"(\d+\.?\d*)\s*[Pp][Ss][iI]", "压力", "psi"),
(r"(\d+\.?\d*)\s*[Hh][Zz]", "频率", "Hz"),
]
2.4 规格归一化映射
SPEC_NORMALIZE = {
"1.5平": "1.5mm²", "1.5平方": "1.5mm²", "1.5平米": "1.5mm²",
"2.5平": "2.5mm²", "2.5平方": "2.5mm²",
"4平": "4mm²", "4平方": "4mm²",
"6平": "6mm²", "6平方": "6mm²",
"漏保": "漏电保护器", "空开": "空气开关",
"排插": "插排", "插排": "插排",
}
2.5 解析流程
原始商品名称
↓
繁转简 / 全角转半角
↓
品牌词典匹配 → 提取brand,余项继续
↓
品类词典匹配 → 提取product_name,余项继续
↓
规格正则匹配 → 提取spec
↓
颜色词典匹配 → 提取color
↓
单位匹配 → 提取quantity + unit
↓
剩余词 → product_name补充
↓
结构化JSON
2.6 优缺点
| 优点 | 缺点 |
|---|---|
| 实现简单,推理速度快 | 覆盖率受限,长尾商品解析差 |
| 可解释性强 | 规则维护成本随品类增加 |
| 无需训练数据 | 边界情况处理困难 |
| CPU 即可运行 | 歧义问题难以解决 |
三、方案二:Elasticsearch 全文检索(推荐)
3.1 核心思想
利用 Elasticsearch 的中文分词器(IK)+ 拼音插件,实现高效的商品名称检索,支持同义词扩展、模糊匹配、拼音搜索。
3.2 索引设计
{
"mappings": {
"properties": {
"goods_id": { "type": "keyword" },
"goods_name": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": { "type": "keyword" },
"pinyin": { "type": "text", "analyzer": "pinyin" }
}
},
"brand": {
"type": "text",
"fields": { "keyword": { "type": "keyword" } }
},
"category": { "type": "keyword" },
"spec": { "type": "text" },
"pinyin": { "type": "text", "analyzer": "pinyin" },
"embedding": { "type": "dense_vector", "dims": 768, "index": true, "similarity": "cosine" }
}
}
}
3.3 核心插件
| 插件 | 用途 |
|---|---|
| elasticsearch-analysis-ik | IK 中文分词器 |
| elasticsearch-analysis-pinyin | 拼音搜索支持 |
| elasticsearch-analysis-simhash | 相似文本去重 |
3.4 查询示例
# 搜索"金杯1.5平红色电线"
query = {
"bool": {
"should": [
{ "match": { "goods_name": "金杯 1.5平 红色 电线" }},
{ "match": { "pinyin": "jinbei dianxian" }},
{ "term": { "brand": "金杯" }},
{ "term": { "spec": "1.5mm²" }},
],
"minimum_should_match": 2
}
}
3.5 同义词配置
{
"settings": {
"analysis": {
"synonym_path": "synonyms.txt"
}
}
}
金杯电线,金杯牌电线
漏电保护器,漏保,漏电开关,RCD
空气开关,空开,断路器
插排,插座,排插
3.6 优缺点
| 优点 | 缺点 |
|---|---|
| 全文检索能力强 | 无法理解语义相似但字面不同的表述 |
| 拼音搜索支持好 | 向量检索能力弱 |
| 集群扩展能力强 | 规则仍需人工维护 |
| 毫秒级响应 | 无法处理嵌套实体 |
四、方案三:BERT NER 命名实体识别(深度学习)
4.1 核心思想
使用预训练语言模型(BERT 系列)对商品名称进行序列标注,识别出各实体边界。
4.2 BIO 标签体系
采用 BIO (Begin-Inside-Outside) 标注体系:
B-{实体类型} 实体开始
I-{实体类型} 实体延续
O 非实体
| 标签 | 说明 | 示例 |
|---|---|---|
| B-BRAND | 品牌开始 | 德力西 |
| I-BRAND | 品牌延续 | 德力西 |
| B-SPEC | 规格开始 | 10A |
| I-SPEC | 规格延续 | 10A |
| B-COLOR | 颜色开始 | 红色 |
| B-PRODUCT_TYPE | 品名开始 | 电线 |
| B-UNIT | 单位开始 | 5卷 |
4.3 标注示例
德力西(Deli) 10A 250V 墙壁开关插座面板
B-BRAND I-BRAND O O O O B-SPEC I-SPEC O B-PRODUCT_TYPE I-PRODUCT_TYPE I-PRODUCT_TYPE
4.4 模型选型
| 模型 | 参数量 | 精度 | 推理速度 | 适用场景 |
|---|---|---|---|---|
| hfl/chinese-roberta-wwm-ext | 100M | 高 | 慢 | 精度优先 |
| hfl/chinese-macbert-base | 100M | 高 | 慢 | 中文优化 |
| hfl/chinese-roberta-wwm-ext-small | 43M | 中 | 中 | 平衡 |
| albert_tiny | 4M | 中 | 快 | 轻量优先 |
推荐:精度优先用 hfl/chinese-macbert-base,轻量用 hfl/chinese-roberta-wwm-ext-small
4.5 训练配置
TRAIN_CONFIG = {
"model": "hfl/chinese-macbert-base",
"max_length": 64,
"batch_size": 32,
"learning_rate": 2e-5,
"epochs": 10,
"warmup_ratio": 0.1,
}
4.6 数据准备(CoNLL 格式)
德 B-BRAND
力 I-BRAND
西 I-BRAND
1 O
0 O
A O
...
4.7 轻量化方案
MacBERT-base (100M)
↓ 知识蒸馏
TinyBERT (14M)
↓ INT8量化
~3M 参数,CPU实时推理
4.8 优缺点
| 优点 | 缺点 |
|---|---|
| 泛化能力强 | 需大量标注数据 |
| 端到端训练 | 训练成本高 |
| 歧义处理好 | 推理速度较慢 |
| 长尾覆盖好 | 模型维护复杂 |
五、方案四:向量 Embedding + 对比学习(AI 语义检索)
5.1 核心思想
将商品名称映射为语义向量,通过余弦相似度判断近似程度,支持模糊匹配和语义相同但表述不同的商品关联。
5.2 Embedding 模型选型
| 模型 | 维度 | 中文支持 | 推理速度 | 适用场景 |
|---|---|---|---|---|
| text2vec-base-chinese | 768 | 5星 | 中 | 通用中文语义 |
| m3e-base | 768 | 5星 | 快 | 中文+代码混合 |
| bge-base-zh-v1.5 | 768 | 5星 | 快 | 通用语义检索 |
推荐:text2vec-base-chinese(中文语义最优)
5.3 结构化向量编码
每个商品编码为多个字段向量的组合:
def encode_product_structured(product: dict) -> list[float]:
vectors = []
# 1. 品牌向量
vectors.append(embed_text(f"品牌:{product['brand']}"))
# 2. 品名向量
vectors.append(embed_text(f"品名:{product['product_name']}"))
# 3. 规格向量(归一化后)
spec_normalized = normalize_spec(product['spec'])
vectors.append(embed_text(f"规格:{spec_normalized}"))
# 4. 品类向量
vectors.append(embed_text(f"品类:{product['category']}"))
# 5. 全量描述向量
full_desc = f"{product['brand']} {product['product_name']} {product['spec']} {product['color']}"
vectors.append(embed_text(full_desc))
return concat_and_project(vectors, output_dim=256)
5.4 对比学习训练数据
# 同商品不同表述 → 正例对
POSITIVE_PAIRS = [
("金杯1.5平方红色电线5卷", "红色1.5平方金杯电线5卷"),
("德力西63A漏电保护开关", "德力西漏电保护器63A2P"),
("舒友电工胶布红色1箱", "舒友红色胶布1箱(12卷)"),
]
# 不同商品 → 负例对
NEGATIVE_PAIRS = [
("金杯1.5平方红色电线", "金杯2.5平方红色电线"),
("德力西63A漏电开关", "德力西32A漏电开关"),
("东成20V锂电钻", "东成21V锂电钻套装"),
]
5.5 对比学习损失
def contrastive_loss(anchor, positive, negative, margin=0.5):
pos_sim = cosine_similarity(anchor, positive)
neg_sim = cosine_similarity(anchor, negative)
return max(0, neg_sim - pos_sim + margin)
5.6 向量数据库选型
| 特性 | Milvus | Qdrant | Chroma |
|---|---|---|---|
| 定位 | 企业级分布式 | 云原生/嵌入式 | 轻量级/本地 |
| 分布式 | 原生支持 | 原生支持 | 不支持 |
| 延迟 | 低 | 极低(<10ms) | 低 |
| 召回率 | 99.9% | 99.9% | ~95% |
推荐:实时搜索用 Qdrant,离线分析用 Milvus
5.7 优缺点
| 优点 | 缺点 |
|---|---|
| 语义理解强 | 训练成本高 |
| 模糊匹配好 | 精确字段提取弱 |
| 同义词覆盖好 | 向量维度选择需调试 |
| 端到端 | 难以解释具体字段值 |
六、方案对比与选型建议
6.1 综合对比
| 维度 | 规则词典 | ES全文检索 | BERT NER | 向量Embedding |
|---|---|---|---|---|
| 实现难度 | 低 | 中 | 高 | 高 |
| 训练成本 | 无 | 无 | 高(需标注数据) | 中(对比学习) |
| 推理速度 | 快(<1ms) | 快(<10ms) | 中(~50ms) | 快(<10ms) |
| 字段精度 | 中 | 中 | 高 | 低 |
| 语义泛化 | 低 | 中 | 高 | 高 |
| 覆盖率 | 依赖词典 | 依赖词典+分词 | 依赖标注数据 | 依赖训练数据 |
| 可解释性 | 强 | 强 | 中 | 弱 |
6.2 推荐技术路径
路径 A:快速上线(1-2周)
规则词典 + Elasticsearch
├── 品牌词典(500+)
├── 品类词典(300+)
├── 规格正则(50+)
└── ES 索引 + 拼音搜索
适用场景:数据质量较好,品类品牌相对固定
路径 B:精度优先(4-6周)
BERT NER + Elasticsearch
├── 标注数据(2000条)
├── BERT-wwm-ext 模型训练
├── 规则后处理修正
└── ES 向量混合检索
适用场景:需要精确字段解析,对精度要求高
路径 C:语义最优(6-8周)
BERT NER + 向量Embedding + ES
├── NER 提取结构化字段
├── text2vec 向量化
├── Qdrant 向量检索
└── ES 过滤和精确匹配
适用场景:需要语义相似匹配 + 精确字段双重能力
6.3 爱优系统选型建议
基于37万商品规模和现有 PHP 技术栈,推荐路径 A 快速上线 + 路径 C 长期演进:
Phase 1(1-2周):
├── 建立品牌词典(200个核心品牌)
├── 建立品类词典(100个核心品类)
├── ES 索引搭建
└── PHP 对接搜索 API
Phase 2(3-4周):
├── NER 模型训练(500条标注数据)
├── 规则引擎完善
└── 向量索引搭建
Phase 3(持续优化):
├── 对比学习微调
├── 新品类规则扩充
└── 标注数据积累
七、品类 Taxonomy 设计
7.1 一级品类
| 品类代码 | 品类名称 | 典型商品 |
|---|---|---|
| WIRE | 电线电缆 | BV线、BVR线、RVV护套线 |
| SWITCH | 开关插座 | 墙壁开关、断路器、漏电保护器 |
| LIGHT | 照明灯具 | 灯泡、灯管、灯带、射灯 |
| TOOL | 五金工具 | 电钻、扳手、钳子、螺丝刀 |
| FASTENER | 紧固件 | 螺丝、螺母、螺栓、膨胀螺栓 |
| ADHESIVE | 胶带胶水 | 电工胶布、ab胶、瞬间胶 |
| PIPE | 水管管件 | PPR管、PVC管、弯头、三通 |
| BUILDING | 建筑材料 | 水泥、黄沙、砖、砂石 |
7.2 品类识别关键词
CATEGORY_KEYWORDS = {
"WIRE": ["电线", "电缆", "线缆", "BV", "BVR", "RVV"],
"SWITCH": ["开关", "插座", "断路器", "漏电", "空开", "配电箱"],
"LIGHT": ["灯泡", "灯管", "灯带", "吸顶灯", "射灯", "支架"],
"TOOL": ["电钻", "冲击钻", "螺丝刀", "扳手", "钳子", "锯子", "锤子"],
"FASTENER": ["螺丝", "螺母", "螺栓", "膨胀", "钉子", "铆钉"],
"ADHESIVE": ["胶布", "胶带", "胶水", "ab胶", "防水胶带"],
"PIPE": ["水管", "PPR", "PVC", "管件", "弯头", "三通", "阀门"],
"BUILDING": ["水泥", "黄沙", "砖", "砂", "石子", "钢筋", "模板"],
}
八、数据增强策略
8.1 同义表述变换
AUGMENTATION_RULES = {
"swap_order": {
"input": "金杯电线",
"outputs": ["电线金杯"]
},
"add_color": {
"input": "金杯电线",
"outputs": ["红色金杯电线", "金杯红色电线"]
},
"spec_variants": {
"input": "1.5平方",
"outputs": ["1.5平", "1.5mm²", "1.5平米"]
},
"brand_alias": {
"input": "公牛",
"outputs": ["GONGNIU", "Bull", "公牛电器"]
},
"category_expand": {
"input": "漏保",
"outputs": ["漏电保护器", "漏电开关", "RCD", "ELCB"]
}
}
8.2 标注数据自动生成
def auto_generate_training_data(product_template, count=10):
"""基于模板自动生成标注数据"""
variations = []
for _ in range(count):
text = generate_variant(product_template, AUGMENTATION_RULES)
labels = ner_model.predict_labels(text) # 伪标签
variations.append({"text": text, "labels": labels})
return variations
九、评估指标
9.1 NER 评估
| 指标 | 计算方式 | 目标值 |
|---|---|---|
| Token F1 | 按 token 对齐计算 | > 90% |
| Entity F1 | 按实体边界对齐 | > 85% |
| Brand Accuracy | 品牌识别准确率 | > 95% |
| Spec Accuracy | 规格识别准确率 | > 90% |
9.2 向量检索评估
| 指标 | 计算方式 | 目标值 |
|---|---|---|
| Recall@K | TopK 召回率 | > 85% |
| MRR | 平均倒数排名 | > 0.8 |
| NDCG@K | 归一化折损累计增益 | > 0.75 |
9.3 业务评估
| 指标 | 说明 | 目标值 |
|---|---|---|
| 搜索转化率 | 搜索→下单比例 | 提升 20% |
| 模糊匹配准确率 | 模糊词→正确商品 | > 80% |
| 响应时间 | P99 延迟 | < 100ms |
十、总结
10.1 方案选型汇总
| 模块 | 推荐方案 | 备选方案 |
|---|---|---|
| 字段解析 | 规则词典(快速)→ BERT NER(精度) | BERT NER |
| 搜索引擎 | Elasticsearch + IK + 拼音 | Meilisearch |
| 向量检索 | Qdrant(实时)+ Milvus(离线) | Chroma |
| Embedding | text2vec-base-chinese | bge-base-zh-v1.5 |
| 训练方式 | 对比学习微调 | Triplet Loss |
10.2 实施建议
- Phase 1(1-2周):规则词典 + ES 上线,解决80%常见商品
- Phase 2(3-4周):BERT NER 训练,覆盖长尾商品
- Phase 3(持续):向量检索优化,提升语义匹配能力
10.3 预期效果
| 指标 | 当前 | 目标 |
|---|---|---|
| 品牌识别准确率 | ~70% | > 95% |
| 规格解析准确率 | ~60% | > 90% |
| 模糊匹配召回率 | ~30% | > 85% |
| 搜索响应时间 | - | P99 < 100ms |