引言
以訊飛「基于帶貨視頻評論的用戶洞察挑戰賽」的賽事項目為背景,將電商直播帶貨視頻的碎片化用戶評論轉化為可量化的商業洞察信息。其實本質上在于利用自然語言處理、機器學習或者大模型技術,從海量的文本數據中提取有價值的商業洞察。
主要涉及以下幾個關鍵領域的任務:
- 任務一(文本編碼):基于視頻內容識別對應的商品
- 任務二(文本分類):從非結構化評論中提取情感傾向
- 任務三(文本聚類):通過聚類總結用戶的關鍵觀點
1. 相關知識了解
文本編碼
概念: 文本(文章句子、評論等)——> 機器可識別的向量(數字向量)
大模型文本編碼關鍵步驟:
1. 分詞: 將一句話拆解成更小的語言單元(通常是單詞、子詞、字符)
- 例子:
輸入文本:"I love AI."
分詞結果可能是:["I", "love", "AI", "."]
或["I", "lov", "e", "AI", "."]
(具體取決于分詞器類型)
2. 詞元映射為索引每個詞元都會被映射到一個詞匯表中的索引號
["I", "love", "AI", "."]
→[101, 456, 987, 102]
3.位置編碼(Position Encoding):
? 因為 Transformer 結構本身沒有序列順序的概念,所以要顯式加上位置信息
4. 生成詞嵌入: 每個 token 索引會被映射為一個高維稠密向量
- 舉例:
[101, 456, 987, 102]
→[[0.1, 0.2, ..., 0.9], [...], ..., [...]]
- 最終形成一個二維張量
[sequence_length, embedding_dim]
,比如[4, 768]
常用方法包括獨熱編碼、詞嵌入 (如Word2Vec、GloVe等靜態詞向量)以及基于預訓練模型的上下文詞嵌入(如BERT、GPT等動態詞向量)。
編碼方式 | 上下文相關 | 稠密向量 | 是否需要位置編碼 | 模型是否訓練詞向量 | 適合場景 |
---|---|---|---|---|---|
獨熱編碼 | 否 | ? 稀疏 | ? 否 | ? 否 | 教學演示、早期模型 |
Word2Vec/GloVe | 否 | ? 靜態 | ? 否 | ? 是(預訓練) | 傳統NLP任務 |
BERT/GPT等 | ? 是 | ? 動態 | ? 是 | ? 是(上下文訓練) | 現代NLP任務、SOTA模型 |
文本分類:根據文本內容將其自動歸類到預定義類別。
- 本項目中的情感分析屬于多維度文本分類任務,需要識別評論的情感傾向(正面/負面/中性等)以及是否涉及用戶場景、疑問或建議等屬性。
- 常用方法包括基于規則和詞典的方法、傳統機器學習方法(如樸素貝葉斯、支持向量機SVM等)以及深度學習方法(如循環神經網絡RNN、卷積神經網絡CNN、Transformer等) 。
文本聚類:根據文本內容的相似性自動將文本分組,無需預先定義類別。
- 本項目要求按商品對指定維度的評論進行聚類,并提煉每類的主題詞。
- 常用聚類算法包括K-Means(需預設簇數K)、層次聚類、DBSCAN等
2.賽題及數據
具體信息可查看官網
賽題難點
- 數據量少,挑戰模型泛化能力
- 比賽提供的數據量相對較少,包含 85 條脫敏后的帶貨視頻數據和 6477 條評論文本數據。其中,帶有 人工標注結果的訓練集更是有限 。
- 多任務協同,要求全鏈路解決方案
- 本次比賽并非單一任務,而是要求參賽者完成“ 商品識別-情感分析-評論聚類 ”的完整鏈條,每個階段環環相扣。
解題思路
商品識別是基礎,如果這里出了錯,后續的情感分析和聚類就沒有意義。情感分析的結果又會影響聚類的樣本選擇。
- 商品識別 (高優先級): 必須盡可能準確。【文本分類】
- 情感分析 (高優先級): 這是數據最豐富的部分,也是后面聚類的關鍵輸入。【多標簽文本分類】
- 評論聚類 (次高優先級): 基于前兩步的結果,需要考慮聚類的效果評估(輪廓系數)和主題詞提煉的質量。【無監督學習中的文本聚類+ 主題詞提取】
3.baseline解讀
1.設計思路: 分階段處理 各個任務,并利用 TF-IDF / BGE向量化 和 線性分類器/KMeans 聚類 來完成商品識別、情感分析和評論聚類。
-
計算資源需求低: 相較于大型深度學習模型,TF-IDF 和 LinearSVC/KMeans 對計算資源的要求非常低。這意味著它可以在普通的個人電腦上快速運行,無需高性能GPU,也符合比賽中可能存在的資源限制(尤其是在不使用額外付費資源的情況下)。
-
TF-IDF 的局限性: TF-IDF 僅關注詞語的頻率和文檔分布,無法捕捉詞語的 上下文信息 、 語義相似性 或 多義詞 。例如,“蘋果”在“買蘋果手機”和“吃蘋果”中含義不同,TF-IDF 無法區分。
改進:可以嘗試BERT
-
K-Means 的局限性: K-Means 是一種基于距離的聚類算法,它假設簇是凸形的且大小相近。它對初始質心敏感,且無法很好地處理不規則形狀的簇。
2.代碼整體流程
這個 baseline 代碼嚴格按照比賽的三個任務順序執行:
- 任務一: 訓練一個模型來預測
product_name
。 - 任務二: 訓練四個模型來分別預測四個情感相關的標簽。
- 任務三: 對不同類別的評論進行聚類,并提取主題詞。
分步詳解
- 數據準備
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( # 訓練模型,代碼篩選出 product_name 這一列有標注的行,用這些數據來訓練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"]) # 預測
3.任務二:情感分析
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"])
這里用一個 for
循環,對 sentiment_category
, user_scenario
等四個目標列,重復地做了和任務一幾乎一樣的事情:
- 創建一個
TF-IDF
+SGDClassifier
的流水線。 - 用已有標注的評論數據進行訓練。
- 對所有評論進行預測,填上對應的標簽。
4.任務三:評論聚類
# 1. 定義并訓練聚類模型
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"])# 2. 對評論進行聚類
kmeans_cluster_label = kmeans_predictor.predict(comments_data[comments_data["sentiment_category"].isin([1, 3])]["comment_text"])# 3. 提取每個類簇的主題詞
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] # 按TF-IDF權重排序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]
named_steps
:從 pipeline 中取出各步驟的具體對象
feature_names
:TF-IDF 中的所有詞(按順序)
cluster_centers_
:每個聚類中心的向量,表示這個簇中哪些詞的平均 TF-IDF 值最大
步驟:
-
1、創建聚類流水線:這次的流水線是
TF-IDF
+KMeans
。KMeans
是一種經典的聚類算法。 -
2、篩選數據并訓練:它先從所有評論中篩選出正面或包含正面的評論(
sentiment_category
為 1 或 3),然后用這些評論來訓練KMeans
模型。 -
3、預測簇標簽:模型會給每一條正面評論分配一個它所屬的類別標簽(比如第0類或第1類)。
-
4、提取主題詞:找出TF-IDF權重最高的幾個詞,然后把這幾個詞拼成一個字符串,作為這個類別的“總結詞”。
-
5、結果:最后,把每個評論所屬類別的“總結詞”填到
positive_cluster_theme
這一列。
其它幾個評論文本類似。
4.優化思考
對于任務一
-
模型太簡單:
TF-IDF
+SGDClassifier
是非常基礎的組合,它只能學到一些表面的詞頻信息,理解不了深層語義。 -
參數:
max_features=50
這個參數限制了TfidfVectorizer
只會關注最重要的50個詞。嘗試改為100呢?
對于任務二
- 同樣是TF-IDF局限性
對于任務三
- 模型
- 聚類數:寫一個循環,嘗試
n_clusters
從5到8的所有可能。對于每一個n_clusters
值,都計算一下聚類的輪廓系數 (Silhouette Coefficient),選擇讓輪廓系數最高的那個n_clusters
值作為你最終的聚類數量
# 動態確定最佳聚類數
from sklearn.metrics import silhouette_score
best_k = 0
best_score = -1for k in range(5,9):kmeans = KMeans(n_clusters=k)labels = kmeans.fit_predict(embeddings)score = silhouette_score(embeddings, labels)if score > best_score:best_k = k
優化思路1: 修改max_features參數和循環聚類數
分數從
提高到
其它優化思路:(預訓練模型和大模型)