如何用Python自动从电商商品名提取数量填充Unit列?
从商品名称中自动提取包装数量:规则引擎与机器学习方案
可行性说明
当然可以用机器学习实现自动提取,但优先推荐先尝试规则引擎方案——你的示例数据里的包装表述(数字+pack/pk/x等变体)有很强的规律,正则表达式就能覆盖绝大多数场景,无需标注数据、实现快速高效。如果后续遇到大量不规则表述(比如非标准化的数量描述),再引入机器学习方案。
方案一:规则引擎(快速落地)
用正则表达式匹配所有常见的包装数量表述,覆盖你给出的全部示例情况:
实现代码
import pandas as pd import re def extract_unit(product_name): # 匹配「数字 + pack/pk(含大小写、连字符变体)」 match1 = re.search(r'(\d+)\s*(?:pack|pk|Pack|Pk|-pack|-pk)\b', product_name) if match1: return int(match1.group(1)) # 匹配「pack x 数字」格式 match2 = re.search(r'pack\s*x\s*(\d+)\b', product_name, flags=re.IGNORECASE) if match2: return int(match2.group(1)) # 匹配「数字x数字」(比如1gx14,提取第二个数字作为数量) match3 = re.search(r'\d+x(\d+)\b', product_name, flags=re.IGNORECASE) if match3: return int(match3.group(1)) # 无匹配时返回空值 return pd.NA # 应用到DataFrame df['Unit'] = df['ProductName'].apply(extract_unit)
这个方案能快速处理现有数据,后续遇到新的包装表述时,只需添加对应的正则模式即可,比硬编码单个数字高效得多。
方案二:机器学习(处理复杂场景)
如果遇到大量非标准化的数量表述(比如“家庭装12份”“半打装”等),可以用**命名实体识别(NER)**模型专门提取“包装数量”实体,步骤如下:
1. 数据标注
从你的数据中选取至少几百条样本,标注出商品名称中的包装数量实体(可使用LabelStudio等工具),标注格式推荐用JSON或CoNLL,每条样本包含商品文本和对应的实体位置/标签。
2. 微调预训练NER模型
用Hugging Face Transformers库微调BERT/RoBERTa这类预训练模型,专门识别“包装数量”实体:
代码框架示例
from transformers import BertTokenizer, BertForTokenClassification, Trainer, TrainingArguments from transformers import pipeline import datasets # 加载标注好的数据集(假设为JSON格式,包含text和labels字段) dataset = datasets.load_dataset('json', data_files='annotated_product_data.json') tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') # 预处理函数:将文本转换为模型可接受的格式 def preprocess_data(examples): tokenized_inputs = tokenizer( examples['text'], truncation=True, padding='max_length', max_length=64, is_split_into_words=False ) # 处理标签(需根据标注格式调整,此处假设标签为实体位置标记) labels = [] for idx, label in enumerate(examples['labels']): word_ids = tokenized_inputs.word_ids(batch_index=idx) label_ids = [] for word_id in word_ids: if word_id is None: label_ids.append(-100) else: label_ids.append(label[word_id]) labels.append(label_ids) tokenized_inputs['labels'] = labels return tokenized_inputs tokenized_dataset = dataset.map(preprocess_data, batched=True) # 加载预训练模型,定义标签数(2类:O=非数量实体,U=数量实体) model = BertForTokenClassification.from_pretrained('bert-base-uncased', num_labels=2) # 设置训练参数 training_args = TrainingArguments( output_dir='./pack_unit_ner', per_device_train_batch_size=8, num_train_epochs=3, logging_steps=10, evaluation_strategy='epoch' ) # 训练模型 trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_dataset['train'], eval_dataset=tokenized_dataset['test'] ) trainer.train() # 推理函数:提取数量 ner_pipeline = pipeline('token-classification', model=model, tokenizer=tokenizer) def extract_unit_ml(product_name): results = ner_pipeline(product_name) # 收集所有标记为数量实体的token number_parts = [res['word'] for res in results if res['entity'] == 'LABEL_1'] if number_parts: number_str = ''.join(number_parts).replace('##', '') # 处理BERT的子词拆分 try: return int(number_str) except ValueError: return pd.NA return pd.NA # 应用到DataFrame df['Unit'] = df['ProductName'].apply(extract_unit_ml)
3. 后处理
模型识别后,需要处理子词拆分、非数字实体等异常情况,结合简单规则进一步提升准确率。
总结
- 优先用规则引擎:快速落地、无需标注数据,覆盖绝大多数标准化包装表述;
- 复杂场景用ML的NER方案:需要标注数据,但能处理非标准化表述;
- 也可采用混合方案:先用正则提取大部分样本,剩余难例用模型处理。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

