Datawhale AI 夏令营:基于带货视频评论的用户洞察挑战赛 Notebook(上篇)
一、食用指南
作为 AI 领域的新手,笔者有幸参与 DataWhale
组织的AI夏令营活动。这是首次参加此类技术训练营,特此记录学习过程中的收获、挑战与成长。若存在任何内容上的遗漏或错误,恳请不吝赐教。
二、跑通 Baseline
!算法赛Baseline (基线)是一个基础的解决方案,通常由竞赛组织者或社区提供,用于展示如何完成从数据处理到模型训练再到结果输出的整个流程。对于竞赛新手来说,Baseline提供了一个可复现的起点,后续可以在其基础上改进。
!Baseline 代码采用 Python 编写,利用 TF-IDF 和 线性分类器/KMeans 聚类 来完成商品识别、情感分析和评论聚类,最终可获得约 176 左右 的分数。
!Jupyter Lab是一个开源的交互式开发环境(IDE),基于Jupyter Notebook扩展而来。它提供模块化界面,支持同时编辑Notebook、代码文件、终端、Markdown文档等,并集成数据可视化、调试工具等功能,适用于数据科学、机器学习、教学研究等领域。
!在交互式环境中学习,是更好地理解它们的好方法。
接下来我们需要在 Notebook 环境下跑通 Baseline,请根据个人情况选择云环境
或者本地环境
,笔者推荐使用云环境。
方式一:云环境(推荐)
优势:即开即用,无需安装依赖,效率杠杠的。
Step1、启动魔搭 Notebook
打开链接直达:https://www.modelscope.cn/my/mynotebook/preset
勾选方式一启动,注意启动需要 1 分钟左右,稍等片刻,然后”查看notebook“,然后会调转阿里云账户登录。
notebook 页面是长这样子的:
Step2、下载 Baseline文件
新开一个命令行窗口分别执行以下两个语句:
git lfs install
git clone https://www.modelscope.cn/datasets/Datawhale/AISumerCamp_video_comments_insights_baseline.git
OK,现在我们已经下载了baseline文件,可以看到左上角有一个文件夹,点击进入文件夹:
Step3、运行 Baseline
文件夹中有一个 Baseline.ipynb
文件,它是一个交互式笔记本,点击打开之后,此时只需要点击上方的按钮即可一键运行代码:
代码跑完之后会在当前目录下生成一个 submit.zip
文件:
选中文件,右键进行下载:
Step4、提交文件,拿下第一个分数
https://challenge.xfyun.cn/h5/detail?type=video-comment-insight&ch=dwsfsp25-1
下载 submit.zip
文件后,在提交结果页面上传文件:
刷新页面,拿下第一个分数 174.49328
。
方式二、本地环境
优势:所有数据都在本地,操作相对便捷。
Step1、安装并启动 Notebook
!需要先安装 python 环境
查看本地环境是否已有 Notebook :
jupyter-lab --version
4.4.3
若没有显示版本号,则进行安装:
pip install -qU jupyterlab -i https://pypi.tuna.tsinghua.edu.cn/simple
创建一个文件夹路径,用于启动 Notebook :
jupyter-lab
复制控制台输出的 URL 打开链接:
http://localhost:8888/lab?token=5ded857b2984b02e925bc12f133f7c732c021035f1fc83a8
http://127.0.0.1:8888/lab?token=5ded857b2984b02e925bc12f133f7c732c021035f1fc83a8
Step2、下载并运行 Baseline
新开一个命令行窗口分别执行以下两个语句:
git lfs install
git clone https://www.modelscope.cn/datasets/Datawhale/AISumerCamp_video_comments_insights_baseline.git
在左边窗口会显示一个文件夹 AISumerCamp_video_comments_insights_baseline
(可能需要刷新),点击进入该文件夹,打开 Baseline.ipynb
笔记本:
然后一键执行:
如何查看执行过程中是否有异常?只需要切换到目录视图,如果有显示红色叹号三角形
则说明中间有异常:
然后根据 Cell 的执行顺序找到报错位置:
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[5], line 1
----> 1 import jieba2 from sklearn.feature_extraction.text import TfidfVectorizer3 from sklearn.linear_model import SGDClassifierModuleNotFoundError: No module named 'jieba'
这是缺少依赖库,安装即可:
pip install -qU jieba -i https://pypi.tuna.tsinghua.edu.cn/simple
最后重新跑代码:运行成功!
同样的,我们下载 submit.zip
文件,并提交到官方地址就可以拿到分数了。
至此,恭喜新手村毕业,接下来开始准备打 Boss!
三、赛题解读
接下来进入正题,在提交 Baseline 结果时相信你已经发现了:实际上我们参加的是科大讯飞的基于带货视频评论的用户洞察挑战赛。
详情:https://challenge.xfyun.cn/topic/info?type=video-comment-insight&ch=dwsfsp25-1
1、背景
在电商直播快速发展的背景下,短视频平台积累了大量带货视频和用户互动数据。这些数据不仅反映消费者对商品的直接反馈,还具有重要的商业决策价值。通过分析带货视频评论,企业可以深入了解消费者对商品的真实态度和需求痛点,从而优化选品策略和评估网红带货效果。具体分析过程包括商品识别、情感分析和聚类洞察三个步骤,将碎片化的用户评论转化为结构化数据,帮助企业把握消费心理、评估网红效果,提升从内容营销到消费决策的全链路价值。
2、数据
官方提供了 85
条脱敏后的带货视频数据和 6477
条评论文本数据。我们看下具体的数据内容跟结构是怎样的,可以在官方下载:
也可以直接看 Notebook 的这两个文件:origin_comments_data.csv
、origin_videos_data.csv
带货视频内容文本信息
数据格式如下:
评论区文本信息
数据格式如下:
可以看到,官方给的赛题数据相当的炸裂,不仅包含多国语言还存在空缺值,好在字段结构非常清晰 :)
3、任务
参赛者需基于提供的带货视频文本及评论文本数据,完成以下三阶段分析任务:
-
1)【商品识别】精准识别推广商品;
-
2)【情感分析】对评论文本进行多维度情感分析,涵盖维度见数据说明;
-
3)【评论聚类】按商品对归属指定维度的评论进行聚类,并提炼类簇总结词。
简而言之就是,文本提纯分析。
4、方法
至于如何提取有效成分,就需要使用对应的方法策略,以下是一些常见方法:
文本编码 => 商品识别
效果:将人类可读的文本转换为机器可理解的数值向量表示,这是所有文本分析任务的基础。
常用方法包括独热编码、词嵌入 (如Word2Vec、GloVe等静态词向量)以及基于预训练模型的上下文词嵌入(如BERT、GPT等动态词向量)。
文本分类 => 情感分析
效果:根据文本内容将其自动归类到预定义类别。
常用方法包括基于规则和词典的方法、传统机器学习方法(如朴素贝叶斯、支持向量机SVM等)以及深度学习方法(如循环神经网络RNN、卷积神经网络CNN、Transformer等) 。
文本聚类 => 评论聚类
效果:根据文本内容的相似性自动将文本分组,无需预先定义类别。
常用聚类算法包括K-Means(需预设簇数K)、层次聚类、DBSCAN等。聚类效果通常用轮廓系数等指标衡量,其值越接近1表示聚类效果越好。
上古秘法:大模型技术
随着技术发展,大型预训练语言模型(LLM) 在NLP任务中表现突出,因此可以利用大模型的零样本/少样本学习能力,在标注数据有限时完成任务,或通过微调预训练模型来更好地适应本任务。此外,还可使用预训练模型提供的API接口获取文本向量表示,用于后续的分类或聚类。
四、解题思路
本挑战赛聚焦"商品识别-情感分析-聚类洞察"的完整链条:参赛者需先基于视频内容建立商品关联关系,进而从非结构化评论中提取情感倾向,最终通过聚类总结形成结构化洞察。
笔者的解题思路:直接站在巨人的肩膀上,分析现有方案的不足,针对方案短板思考可优化的点,最后把这些点全部实现一遍。
1、输入与输出
输入
带货视频内容文本信息和评论区文本信息,即文件 origin_videos_data.csv
和 origin_comments_data.csv
。
输出
提交一个名为 submit.zip
的压缩包文件,内含 submit
文件夹,文件内为 submit_videos.csv
和submit_comments.csv
。
2、精读 Baseline 思路
Step1、加载数据
import pandas as pd
video_data = pd.read_csv("origin_videos_data.csv")
comments_data = pd.read_csv("origin_comments_data.csv")
使用 pandas
库加载 csv
文件数据:
Step2、商品识别
输入数据: 带货视频内容文本信息
代码实现:
video_data["text"] = video_data["video_desc"].fillna("") + " " + video_data["video_tags"].fillna("")...product_name_predictor = make_pipeline(TfidfVectorizer(tokenizer=jieba.lcut, max_features=50), SGDClassifier()
)
product_name_predictor.fit(video_data[~video_data["product_name"].isnull()]["text"],video_data[~video_data["product_name"].isnull()]["product_name"],
)
video_data["product_name"] = product_name_predictor.predict(video_data["text"])
这段代码实现了一个基于文本内容预测产品名称的机器学习流程,以下是详细解析:
-
管道构建:
- 使用
make_pipeline
创建了一个包含两个步骤的机器学习管道 - 第一步是
TfidfVectorizer
文本向量化:- 使用
jieba.lcut
进行中文分词 - 限制最大特征数为50(即只保留最重要的50个词汇特征)
- 使用
- 第二步是
SGDClassifier
分类器(随机梯度下降分类器)
- 使用
-
模型训练:
- 使用非空产品名称的数据进行训练
- 输入特征:
video_data
中的"text"列(视频文本内容) - 目标变量:
video_data
中的"product_name"列(产品名称)
-
预测应用:
- 对全部视频数据的"text"列进行预测
- 将预测结果填充到"product_name"列中
通过TF-IDF将文本转化为数值特征,再用分类模型预测最可能的产品名称。
Step3、文本分类
输入数据:评论区文本信息
代码实现:
for col in ['sentiment_category','user_scenario', 'user_question', 'user_suggestion']:predictor = make_pipeline(TfidfVectorizer(tokenizer=jieba.lcut), SGDClassifier())predictor.fit(comments_data[~comments_data[col].isnull()]["comment_text"],comments_data[~comments_data[col].isnull()][col],)comments_data[col] = predictor.predict(comments_data["comment_text"])
这段代码实现了一个基于TF-IDF和SGD分类器的文本分类流程,用于对评论数据中的多个类别列进行预测填充。以下是详细解析:
-
循环处理多列:
- 代码遍历[‘sentiment_category’,‘user_scenario’, ‘user_question’, ‘user_suggestion’]四个列名,分别处理情感分类、用户场景、用户问题和用户建议四种文本分类任务。
-
构建分类管道:
- 使用
make_pipeline
组合了TfidfVectorizer
和SGDClassifier
两个组件:TfidfVectorizer(tokenizer=jieba.lcut)
:将中文文本转换为TF-IDF特征矩阵,其中jieba.lcut
作为分词器实现中文分词。SGDClassifier()
:随机梯度下降分类器,适合处理大规模稀疏数据(如文本特征)。
- 使用
-
模型训练:
fit()
方法使用非空样本进行训练:- 输入特征:
comments_data[~comments_data[col].isnull()]["comment_text"]
(过滤空值后的评论文本) - 目标标签:
comments_data[~comments_data[col].isnull()][col]
(对应列的非空标签)。
- 输入特征:
-
预测填充:
- 训练完成后,用
predict()
方法预测全部评论的类别,并将结果填充回原数据列的缺失位置comments_data[col]
。
- 训练完成后,用
Step4、文本聚类
输入数据:评论区文本信息
聚类要求:
a. 需进行情感分析的字段包括sentiment_category、user_scenario、user_question和user_suggestion。训练集中部分数据已提供标注,测试集需自行预测。其中字段sentiment_category情感倾向分类的数值含义见下表:
分类值 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
含义 | 正面 | 负面 | 正负都包含 | 中性 | 不相关 |
b. 需进行聚类的字段包括:
- positive_cluster_theme:基于训练集和测试集中正面倾向(sentiment_category=1 或 sentiment_category=3)的评论进行聚类并提炼主题词,聚类数范围为 5~8。
- negative_cluster_theme:基于训练集和测试集中负面倾向(sentiment_category=2 或 sentiment_category=3)的评论进行聚类并提炼主题词,聚类数范围为 5~8。
- scenario_cluster_theme:基于训练集和测试集中用户场景相关评论(user_scenario=1)进行聚类并提炼主题词,聚类数范围为 5~8。
- question_cluster_theme:基于训练集和测试集中用户疑问相关评论(user_question=1)进行聚类并提炼主题词,聚类数范围为 5~8。
- suggestion_cluster_theme:基于训练集和测试集中用户建议相关评论(user_suggestion=1)进行聚类并提炼主题词,聚类数范围为 5~8。
代码实现:
kmeans_predictor = make_pipeline(TfidfVectorizer(tokenizer=jieba.lcut), KMeans(n_clusters=2)
)kmeans_predictor.fit(comments_data[comments_data["sentiment_category"].isin([1, 3])]["comment_text"])
kmeans_cluster_label = kmeans_predictor.predict(comments_data[comments_data["sentiment_category"].isin([1, 3])]["comment_text"])kmeans_top_word = []
tfidf_vectorizer = kmeans_predictor.named_steps['tfidfvectorizer']
kmeans_model = kmeans_predictor.named_steps['kmeans']
feature_names = tfidf_vectorizer.get_feature_names_out()
cluster_centers = kmeans_model.cluster_centers_
for i in range(kmeans_model.n_clusters):top_feature_indices = cluster_centers[i].argsort()[::-1]top_word = ' '.join([feature_names[idx] for idx in top_feature_indices[:top_n_words]])kmeans_top_word.append(top_word)comments_data.loc[comments_data["sentiment_category"].isin([1, 3]), "positive_cluster_theme"] = [kmeans_top_word[x] for x in kmeans_cluster_label]
这段代码实现了一个基于 K-means
聚类的 positive_cluster_theme
文本主题挖掘系流程,用于情感评论聚类分析、主题关键词提取、数据标注增强。以下是详细解析:
-
管道构建阶段
- 创建
make_pipeline
组合TfidfVectorizer
和KMeans
:TfidfVectorizer(tokenizer=jieba.lcut)
:使用结巴分词处理中文文本,生成TF-IDF特征矩阵KMeans(n_clusters=2)
:指定聚类数为2的K-means模型
- 创建
-
模型训练与预测
fit()
方法训练模型:仅使用sentiment_category
为1或3的评论数据predict()
生成聚类标签:对相同筛选条件的数据进行聚类预测
-
关键词提取逻辑
- 通过管道组件名获取模型对象:
tfidf_vectorizer
:提取特征词表get_feature_names_out()
kmeans_model
:获取聚类中心点cluster_centers_
- 计算每类TOP词:
argsort()[::-1]
对中心点权重降序排序- 拼接权重最高的
top_n_words
个特征词
- 通过管道组件名获取模型对象:
-
结果存储
- 将聚类主题词映射回原数据:在
sentiment_category
为1或3的行中新增positive_cluster_theme
列存储对应关键词
- 将聚类主题词映射回原数据:在
同样的,Baseline 继续实现了 negative_cluster_theme
、scenario_cluster_theme
、 question_cluster_theme
、 suggestion_cluster_theme
聚类,加起来一共 5 个聚类结果,符合赛题要求。
Step5、输出结果
在当前目录创建文件夹 submit
:
!mkdir submit
将所有数据保存到 csv
文件中:
video_data[["video_id", "product_name"]].to_csv("submit/submit_videos.csv", index=None)
comments_data[['video_id', 'comment_id', 'sentiment_category','user_scenario', 'user_question', 'user_suggestion','positive_cluster_theme', 'negative_cluster_theme','scenario_cluster_theme', 'question_cluster_theme','suggestion_cluster_theme']].to_csv("submit/submit_comments.csv", index=None)
压缩文件夹 submit
:
!zip -r submit.zip submit/
OK,这里的 submit.zip
就是赛题要求提交的文件,上传就可以拿分了。
3、Basline 不足分析
- TF-IDF 无法捕捉上下文 => 影响商品识别、文本分类
- 聚类分析粗糙,未评估聚类质量 => 影响聚类效果
4、改进方向
替代TF-IDF
例如使用 Sentence-BERT
:Sentence-BERT 在句子/短语级别的语义相似度任务上性能远超原始 BERT 的简单池化方法,是替代 TF-IDF 进行相似度计算、语义搜索、聚类的最佳选择之一。
替代jieba分词器
jieba.lcut
是中文分词的轻量级首选工具,但其局限性(未登录词处理、歧义切分、领域适配性等)在专业场景中可能显著影响下游任务效果。
动态确定最佳聚类数
comments_to_cluster = comments_data[comments_data["user_question"].isin([1])]["comment_text"]# 动态选k(带轮廓系数评估)
k_values = range(5, 9)
best_k = 0
best_silhouette = -1# 单独拟合TF-IDF用于轮廓系数计算(确保与后续模型特征空间一致)
tfidf_for_silhouette = TfidfVectorizer(tokenizer=jieba.lcut)
X_silhouette = tfidf_for_silhouette.fit_transform(comments_to_cluster) # 稀疏矩阵for k in k_values:kmeans = KMeans(n_clusters=k, random_state=42)labels = kmeans.fit_predict(X_silhouette)score = silhouette_score(X_silhouette, labels) # silhouette支持稀疏矩阵print(f"k={k} | 轮廓系数: {score:.4f}")if score > best_silhouette:best_silhouette = scorebest_k = kprint(f"\n最佳聚类数k={best_k}(轮廓系数: {best_silhouette:.4f})")
利用大模型进行分类
prompt = """
你是一个专业的电商产品识别系统。请从视频描述中识别推广商品,必须严格选择以下选项之一:
- Xfaiyx Smart Translator
- Xfaiyx Smart Recorder规则说明:
1. 当描述提到"翻译"、"多语言"等关键词时选择Translator
2. 当描述出现"录音"、"转写"等关键词时选择Recorder
3. 遇到不确定情况时选择更符合主要功能的选项示例:
输入:这款设备支持实时语音转文字
输出:Xfaiyx Smart Recorder现在请识别:
输入:{}
输出:"""
prompt = """请对以下评论进行多维度分析,严格按照格式返回JSON:{"sentiment": ["1-正面","2-负面","3-正负混合","4-中性","5-不相关"],"has_scenario": [0/1],"has_question": [0/1],"has_suggestion": [0/1]
}分析规则:
1. 用户场景判断:评论提及使用场合/环境(如"出差用"、"上课时")则标1
2. 用户疑问判断:包含问号或疑问词(吗/怎么/为什么)标1
3. 情感混合判断:同时出现褒贬词(如"质量好但价格高")选3评论样本:{}"""
综合方案
结合少样本学习、多语言处理和半监督学习技术,最大化利用有限标注数据并提升泛化能力:
Step1、数据预处理与增强
-
数据清洗与标准化
-
video_tags处理:
- 缺失值填充:将缺失的
video_tags
填充为特殊标记(如[MISSING_TAGS]
),并新增一个二进制特征is_tags_missing
(0/1表示是否存在标签),显式建模标签缺失的信息。 - 标签归一化:若标签包含多语言(如中英文混合),统一转换为小写/大写(如英文标签转小写),去除冗余符号(如
#
、,
)。
- 缺失值填充:将缺失的
-
video_desc处理:
- 多语言清洗:去除乱码、重复字符,保留核心语义(如通过正则过滤无意义符号)。
- 语言识别:使用轻量级语言检测模型(如
langdetect
)标注每条video_desc
的语言(如英语、西班牙语等),作为额外特征(可选)。
-
-
数据增强(针对20条标注数据)
- 文本回译:对
video_desc
使用多语言翻译模型(如M2M100)先翻译成中间语言(如法语),再译回原语言,生成增强样本(注意保留原标签)。 - 同义词替换:基于多语言词向量(如FastText多语言词向量),对非关键词汇替换为同义词(避免改变核心语义)。
- 标签填充模拟:对未缺失的
video_tags
,随机删除1-2个标签生成“部分缺失”样本(模拟真实场景中的不完整标签)。
- 文本回译:对
Step2、模型架构设计:多模态提示学习+小样本微调
针对少样本场景,优先采用 提示学习(Prompt Learning) 利用大模型的上下文学习能力,同时结合小样本微调提升特定任务的适配性。
- 基础模型选择
选择多语言预训练大模型(如XLM-RoBERTa-Large或mT5-Large)作为编码器,原因:
- 支持100+语言,能统一处理多语言
video_desc
; - 上下文窗口大(如XLM-RoBERTa支持512 tokens),可容纳长
video_desc
和video_tags
; - 已在多语言NLP任务中验证过少样本性能。
- 提示模板设计(零样本/少样本推理)
将任务转化为 文本蕴含(Textual Entailment) 或 问答(QA) 任务,通过构造自然语言提示引导模型输出分类结果。示例模板:
模板1(QA任务):
“视频描述:{video_desc}
视频标签:{video_tags}
问题:这个视频对应的产品是p1还是p2?
回答:p1”(正例)/ “回答:p2”(负例)
模板2(蕴含任务):
“前提:视频描述为’{video_desc}‘,标签为’{video_tags}'。
假设:这个视频的产品是p1。
判断:蕴含/矛盾”(若为蕴含则标签为p1,否则p2)
- 小样本微调(若有标注数据)
若计算资源允许,用20条标注数据对基础模型进行轻量级微调,提升任务适配性:
- 输入构造:将
video_desc
和video_tags
拼接为[CLS] video_desc [SEP] video_tags [SEP]
,输入模型。 - 输出层:添加一个线性分类头(如256维→2维),预测
p1
或p2
。 - 训练策略:
- 冻结前90%的编码器层,仅微调顶层和分类头(减少过拟合);
- 使用交叉熵损失+AdamW优化器(学习率1e-5);
- 批次大小设为8(小样本下避免梯度震荡);
- 训练轮次3-5轮(早停防止过拟合)。
Step3、半监督学习:利用未标注数据
通过自训练(Self-Training)利用65条未标注数据,生成伪标签并迭代优化:
- 初始模型:用20条标注数据微调后的模型(或纯提示模型)。
- 伪标签生成:对未标注数据,用模型预测概率最高的类别作为伪标签(阈值设为0.8,仅保留高置信度样本)。
- 筛选与融合:将伪标签样本与原20条标注数据合并(去重),重新微调模型(或更新提示模板)。
- 迭代优化:重复步骤2-3(2-3轮),逐步扩大训练集规模。
Step4、集成学习:提升鲁棒性
结合多个模型的预测结果,降低单一模型的偏差:
- 模型1:纯提示模型(使用XLM-RoBERTa,无微调);
- 模型2:小样本微调后的XLM-RoBERTa;
- 模型3:mT5-Large(通过QA任务生成分类结果);
最终预测:对三个模型的输出概率加权平均(权重通过验证集调优),取概率高的类别作为最终结果。
Step5、评估与验证
- 交叉验证:因样本量小,采用分层5折交叉验证(保持每折中p1/p2比例与原数据一致)。
- 指标:重点关注F1-score(平衡精确率和召回率)和AUC-ROC(衡量排序能力)。
- 消融实验:验证各模块(如提示模板、半监督学习、数据增强)的有效性。
五、Basline 改进篇
因文章篇幅过长,故拆分上下两篇,请查阅下篇
-> Datawhale AI 夏令营:基于带货视频评论的用户洞察挑战赛 Notebook(下篇)
参考文档
- https://mp.weixin.qq.com/s/HSQp6EnSiSYPsoHFWBAF-g
- https://www.datawhale.cn/activity/324/learn/191/4315/7/11