【Datawhale AI 夏令營】 用AI做帶貨視頻評論分析(二)

5.預訓練模型跑分

回顧賽題

回顧賽題任務

挑戰與難點:

  • 標注數據少 ——> 半監督學習 or 數據增強

  • 聚類分析噪點影響嚴重

回顧Baseline

問題:

  • TF-IDF無法捕捉以下語義。
  • 聚類分析粗糙,未評估聚類質量。

提升方案:

  1. 分類任務(任務一和任務二)
    • 使用BERT模型
    • 數據增強(對于任務一)
    • 微調方式
  2. 聚類任務

預訓練模型步驟

任務一:商品識別

  • 數據準備: 我們把文字標簽(比如 “Xfaiyx Smart Translator”)映射成數字(0, 1),因為模型只能理解數字。
  • 模型和分詞器: AutoTokenizer 負責把漢字句子切分成模型認識的“詞元”(Token)。AutoModelForSequenceClassification 是一個專門用于分類任務的BERT模型結構。
  • 訓練: TrainingArguments 用來設置訓練的超參數(比如訓練幾輪、每批次用多少數據等)。Trainer 是一個高級封裝,我們把模型、參數、數據都喂給它,它就會自動幫我們完成整個復雜的訓練過程。
  • 預測: 訓練好后,我們用 pipeline 這個便捷工具對所有視頻的文本進行預測,得到商品名稱。

任務二:情感分析

  • 這個過程和任務一非常類似,但是我們用一個 for 循環來為四個不同的情感維度分別獨立地訓練四個模型
  • 因為每個維度的分類任務都不同(比如sentiment_category是5分類,而user_scenario是2分類),所以為每個任務單獨訓練一個模型效果最好。
  • 注意,這里我們將 1,2,3,4,5 這樣的原始標簽也轉換成了從 0 開始的 0,1,2,3,4,訓練完再轉換回去。這是Hugging Face模型的標準要求。

任務三:評論聚類

  • 句向量模型: 我們加載 SentenceTransformer 模型,它會把每個評論變成一個包含384或768個數字的向量,這個向量精準地捕捉了評論的語義。
  • 尋找最佳K: 這是關鍵的改進!代碼會遍歷 K 從 5 到 8,對每個 K 值都進行一次KMeans聚類,并計算輪廓系數。輪廓系數越高,代表聚類效果越好(類內越緊密,類間越疏遠)。最后,代碼會選用分數最高的那個 K 值。
  • 最終聚類: 使用找到的最佳 K,進行最后一次聚類,并把每個評論分到的簇標簽(比如屬于第0簇,第1簇…)記錄下來。
  • 主題生成: 我們為每個簇生成了一個簡單的名字,比如 positive_主題_1。這樣做的好處是清晰明了,并且百分百符合提交格式。

步驟

前期準備

  1. 安裝所需要的庫
!pip install --upgrade transformers accelerate sentence-transformers -q
2. 導入
import pandas as pd
import numpy as np
import torch
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from transformers import (AutoTokenizer,AutoModelForSequenceClassification,TrainingArguments,Trainer,pipeline,
)
from sentence_transformers import SentenceTransformer
from datasets import Dataset
import os
import zipfile
  1. 全局設置(模型定義)和準備數據
# ---------------------------------
# 1. 全局設置和模型定義
# ---------------------------------
print("\n--> 1. 開始進行全局設置...")
CLASSIFICATION_MODEL = 'bert-base-multilingual-cased'
EMBEDDING_MODEL = 'sentence-transformers/paraphrase-multilingual-mpnet-base-v2'
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f"將使用設備: {DEVICE}")# ---------------------------------
# 2. 加載和準備數據
# ---------------------------------
print("\n--> 2. 開始加載和準備數據...")
video_data = pd.read_csv("origin_videos_data.csv")
comments_data = pd.read_csv("origin_comments_data.csv")
video_data["text"] = video_data["video_desc"].fillna("") + " " + video_data["video_tags"].fillna("")

因為評論有多個國家的語言,所以分類模型選的bert-base-multilingual-cased,多語言句向量模型sentence-transformers/paraphrase-multilingual-mpnet-base-v2 (也可以嘗試其它模型)

任務一:商品識別

  1. 數據準備:處理數據和標簽
# 1. 篩選出有商品名的數據
train_video_df = video_data[~video_data["product_name"].isnull()].copy()# 2. 獲取所有不重復的商品名,并排序
labels_list = sorted(train_video_df["product_name"].unique())# 3. 創建“商品名” -> “數字ID” 的映射 (字典)
label2id = {label: i for i, label in enumerate(labels_list)}# 4. 創建“數字ID” -> “商品名” 的映射 (反向字典,方便以后查看結果)
id2label = {i: label for i, label in enumerate(labels_list)}# 5. 在數據中創建新的一列 "label",存放轉換后的數字ID
train_video_df["label"] = train_video_df["product_name"].map(label2id)
  1. 分詞與編碼
# 1. 加載一個預訓練好的分詞器
#    CLASSIFICATION_MODEL 是一個預訓練模型的名字,比如 "bert-base-chinese"
tokenizer = AutoTokenizer.from_pretrained(CLASSIFICATION_MODEL)# 2. 對所有文本進行分詞和編碼
#    - tolist(): 把一列文本轉換成一個列表
#    - truncation=True: 如果句子太長,就截斷
#    - padding=True: 如果句子太短,就用特殊數字填充,讓所有句子一樣長
#    - max_length=128: 指定句子的最大長度
train_encodings = tokenizer(train_video_df["text"].tolist(), truncation=True, padding=True, max_length=128)# 3. 把我們之前轉換好的數字標簽也放進這個編碼結果里
train_encodings['label'] = train_video_df["label"].tolist()# 4. 將整個編碼結果(包含文本編碼和標簽)封裝成一個標準的數據集對象
train_dataset = Dataset.from_dict(train_encodings)
  1. 加載模型與配置訓練
# 1. 加載預訓練模型
model = AutoModelForSequenceClassification.from_pretrained(CLASSIFICATION_MODEL,          # 模型的名字,要和Tokenizer一致num_labels=len(labels_list),   # 告訴模型我們總共有多少個分類id2label=id2label,             # 把我們之前創建的ID->標簽映射告訴模型label2id=label2id              # 也把標簽->ID的映射告訴模型
).to(DEVICE) # 2. 設置訓練參數
training_args = TrainingArguments(output_dir='./results',              # 訓練結果存到哪里num_train_epochs=3,                  # 所有數據要學習3遍per_device_train_batch_size=8,       # 每次看8個樣本logging_dir='./logs',                # 日志存到哪里logging_steps=10,                    # 每訓練10步就打印一次日志report_to="none"                     # 不上報到第三方平臺
)trainer = Trainer(model=model,args=training_args,train_dataset=train_dataset
)

4.訓練與預測

# 1. 開始訓練
trainer.train()# 2. 使用 pipeline(管道)
classifier = pipeline("text-classification",      # 任務類型是文本分類model=model,                # 用我們剛訓練好的模型tokenizer=tokenizer,        # 用我們之前加載的分詞器device=0                    # 0代表使用第一塊GPU,-1代表使用CPU
)# 3. 把所有視頻的文本都扔給它進行預測
predictions = classifier(video_data["text"].tolist())# 4. 從預測結果中提取出標簽名字,并更新回原數據
video_data["product_name"] = [pred['label'] for pred in predictions]

pipeline 是 Hugging Face 提供的最高度封裝的預測工具。它把“輸入原始文本 -> 分詞 -> 轉換成ID -> 模型預測 -> 輸出 logits -> Softmax -> 翻譯回標簽”這一整套繁瑣的流程,壓縮成了一步

classifier = pipeline("任務名稱", model=訓練好的模型, tokenizer=配套的分詞器)

優化嘗試

因為我用BERT微調之后,看了一下分數只有80左右,

數據太少: 生成偽標簽 + 5折交叉驗證

假設標簽是“答案”,有標簽的數據是“教材”,就是讓5個專家做沒有答案的練習冊,如果5個專家的答案都一樣,就把這道題收入到教材,這樣教材的內容就更多了,最后再讓學生學習這本“教材”

  1. 分離數據: 一部分有標簽(答案)和一部分沒標簽
# 有答案的“教材”
train_video_df = video_data[~video_data["product_name"].isnull()].copy()
# 沒答案的“練習題”
unlabeled_video_df = video_data[video_data["product_name"].isnull()].copy()# ... (標簽數字化的部分和之前一樣) ...
  1. 訓練5個模型(專家),并讓每個專家做一次“練習冊”,收集“答案”
    1. 把教材(train_video_df)平均分成5份。
    2. 第1輪:用第1、2、3、4份當教材訓練模型,第5份當模擬考(這里代碼省略了驗證,直接訓練)。
    3. 第2輪:用第1、2、3、5份當教材訓練模型,第4份當模擬考。
    4. …以此類推,一共訓練5個模型。
    5. 每個模型都學習了80%的數據,而且學習的內容都不完全相同,這樣就組成了我們的“專家委員會”。
# 引入分層K折交叉驗證工具,它能保證每一折里各類別的比例都差不多
from sklearn.model_selection import StratifiedKFold# 設定交叉驗證:分成5份,打亂順序
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
unlabeled_preds = [] # 用來存放5個專家對“練習題”的答案# skf.split(...) 會自動循環5次,每次都生成不同的訓練集索引(train_idx)
for fold, (train_idx, val_idx) in enumerate(skf.split(train_video_df['text'], train_video_df['label'])):print(f"\n===== 開始訓練第 {fold+1} 位專家 =====")# 1. 準備當前這位專家的教材train_fold_df = train_video_df.iloc[train_idx]# (數據編碼過程,和之前一樣,只是數據源是 train_fold_df)train_dataset = ... # 2. 請來一位全新的專家(模型)model = AutoModelForSequenceClassification.from_pretrained(...)# 3. 對這位專家進行特訓trainer = Trainer(model=model, args=training_args, train_dataset=train_dataset)trainer.train()# 4. 專家學成!讓他去做“練習題”(unlabeled_video_df)unlabeled_dataset = ... # 把練習題也編碼成模型能讀懂的格式# trainer.predict 返回原始的、未經處理的預測分數(logits)raw_preds, _, _ = trainer.predict(unlabeled_dataset)# 5. 將該專家的答案(處理成0-1之間的概率后)存起來unlabeled_preds.append(F.softmax(torch.from_numpy(raw_preds), dim=-1).numpy())
  1. 生成“新教材”
# 1. 計算平均意見:對5位專家的預測概率取平均值
#    axis=0 表示在“專家”這個維度上求平均
avg_preds = np.mean(unlabeled_preds, axis=0)# 2. 確定最終投票結果:取平均概率最高的那個類別作為預測結果(第一題選A, 對應標簽0)
pred_labels = np.argmax(avg_preds, axis=1) # 得到數字標簽,如 0, 1, 2# 3. 取最高的那個平均概率作為置信度分數
pred_scores = np.max(avg_preds, axis=1) # 得到分數,如 0.98, 0.75, 0.91# 4. 只有信心超過90%的答案,我們才采納
confidence_threshold = 0.90 
pseudo_df = pd.DataFrame({'text': unlabeled_video_df['text'], 'label': pred_labels, 'score': pred_scores})
high_confidence_pseudo_df = pseudo_df[pseudo_df['score'] > confidence_threshold].copy()# 5. 將“新教材”和“老教材”合并
if not high_confidence_pseudo_df.empty:print(f"成功篩選出 {len(high_confidence_pseudo_df)} 條新教材!")combined_train_df = pd.concat([train_video_df, high_confidence_pseudo_df], ignore_index=True)
else:# 如果沒篩出來,就還用老教材combined_train_df = train_video_df

? 4.得到新的數據集,進行訓練

# 1. 準備最全的教材
final_dataset = Dataset.from_pandas(combined_train_df)
final_dataset = final_dataset.map(...) # 編碼# 2. 加載模型
final_model = AutoModelForSequenceClassification.from_pretrained(...)# 3. 用所有數據進行訓練
final_trainer = Trainer(model=final_model, args=training_args, train_dataset=final_dataset)
final_trainer.train()print("\n--- 開始預測所有視頻... ---")
final_classifier = pipeline("text-classification", model=final_model, ...)
final_predictions = final_classifier(video_data["text"].tolist())# 更新最終結果
video_data["product_name"] = [pred['label'] for pred in final_predictions]

任務二:情感分析

任務二與任務一類似,并且數據夠多。用一個 for 循環來為四個不同的情感維度分別獨立地訓練四個模型

任務三:評論聚類

上期使用循環選擇聚類個數得分50+, 本來打算使用UMAP降維試試,但是分數還是50+(暫時沒有提高分數的頭緒,等提高了再補充)

結果

在這里插入圖片描述

心得

算是第一次參加這類大賽,通過Datawhale的教程,很輕松的入門,寫的很詳細。遇到不會的也可以在群里交流,對自己提升很多。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88846.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88846.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88846.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SPSSPRO:數據分析市場SaaS挑戰者的戰略分析

目錄 第一部分:執行摘要 第二部分:平臺解構:產品、架構與用戶體驗 2.1 SaaS范式轉移:架構與起源 2.2 功能能力:分析師的工具箱 2.3 “智能分析”的價值主張 第三部分:市場滲透與受眾細分 3.1 目標用戶…

低版本hive(1.2.1)UDF實現清除歷史分區數據

目標&#xff1a;通過UDF實現對表歷史數據清除 入參&#xff1a;表名、保留天數N 一、pom文件 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.…

C++中頂層const與底層const

在C中&#xff0c;const關鍵字用于定義常量&#xff0c;但它在指針和引用上下文中會產生兩種不同的常量性&#xff1a;頂層const&#xff08;top-level const&#xff09;和底層const&#xff08;low-level const&#xff09;。理解它們的區別是避免編譯錯誤和提高代碼質量的關…

“SRP模型+”多技術融合在生態環境脆弱性評價模型構建、時空格局演變分析與RSEI指數生態質量評價

集成云端、桌面端等環境&#xff0c;結合遙感云計算、GIS空間分析&#xff0c;R語言統計分析的優勢&#xff0c;以分析生態環境脆弱性的時空演變為主線。通過本課程的學習&#xff0c;您將掌握&#xff1a;第一&#xff0c;收集各類指標數據&#xff0c;構建的“生態壓力度-生態…

算法學習筆記:17.蒙特卡洛算法 ——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在計算機科學和數學領域&#xff0c;蒙特卡洛算法&#xff08;Monte Carlo Algorithm&#xff09;以其獨特的隨機抽樣思想&#xff0c;成為解決復雜問題的有力工具。從圓周率的計算到金融風險評估&#xff0c;從物理模擬到人工智能&#xff0c;蒙特卡洛算法都發揮著不可替代的作…

Tortoise 設置

如何關閉 Windows 下 TortoiseGit 任務欄里窗口標題的分支顯示 一、引言 TortoiseGit 是一個專為團隊協作設計的 Git 圖形化客戶端&#xff0c;旨在解決版本控制中常見的問題&#xff0c;如沖突、回滾、歷史查看等。本文檔是 TortoiseGit 的使用手冊前言部分&#xff0c;旨在向…

[論文閱讀] 人工智能 + 軟件工程 | AI助力軟件可解釋性:從用戶評論到自動生成需求與解釋

AI助力軟件可解釋性&#xff1a;從用戶評論到自動生成需求與解釋 Automatic Generation of Explainability Requirements and Software Explanations From User ReviewsarXiv:2507.07344 Automatic Generation of Explainability Requirements and Software Explanations From …

C語言---自定義類型(上)(結構體類型)

結構體結構體的定義與聲明結構體其實和數組一樣&#xff0c;都是一些值的集合&#xff0c;只不過數組是一系類相同類型的值&#xff0c;而結構體里邊的成員可以是不同的數據類型。關于它的聲明&#xff0c;所用到的關鍵字是struct。聲明的語法如下&#xff1a;struct 結構體名{…

Java觀察者模式實現方式與測試方法

一、實現方式 自定義實現 通過手動定義Subject和Observer接口&#xff0c;實現一對多依賴關系&#xff1a; // 觀察者接口 public interface Observer {void update(float temp, float humidity, float pressure); } // 主題接口 public interface Subject {void registerObser…

leetGPU解題筆記(1)

1.題面 題目要求 向量加法 實現一個程序&#xff0c;在GPU上對兩個包含32位浮點數的向量執行逐元素加法。該程序應接受兩個長度相等的輸入向量&#xff0c;并生成一個包含它們和的輸出向量。 實現要求 禁止使用外部庫 solve函數簽名必須保持不變 最終結果必須存儲在向量C中 示例…

5. JVM 的方法區

1. JVM介紹和運行流程-CSDN博客 2. 什么是程序計數器-CSDN博客 3. java 堆和 JVM 內存結構-CSDN博客 4. 虛擬機棧-CSDN博客 5. JVM 的方法區-CSDN博客 6. JVM直接內存-CSDN博客 7. JVM類加載器與雙親委派模型-CSDN博客 8. JVM類裝載的執行過程-CSDN博客 9. JVM垃圾回收…

網絡安全的基本練習

一.docker搭建 1.安裝dockerapt-get install docker.io docker-compose2.編寫配置文件&#xff08;注意路徑正確&#xff09;vim /etc/systemd/system/docker.service.d/http-proxy.conf[Service] Environment"HTTP_PROXYhttp://科學上網訪問的ip:端口" Environment&…

380. O(1) 時間插入、刪除和獲取隨機元素

實現RandomizedSet 類&#xff1a; RandomizedSet() 初始化 RandomizedSet 對象 bool insert(int val) 當元素 val 不存在時&#xff0c;向集合中插入該項&#xff0c;并返回 true &#xff1b;否則&#xff0c;返回 false 。 bool remove(int val) 當元素 val 存在時&#xff…

【LeetCode Hot100 | 每日刷題】字母異位詞分組

題目鏈接&#xff1a;49. 字母異位詞分組 - 力扣&#xff08;LeetCode&#xff09; 題目&#xff1a; 給你一個字符串數組&#xff0c;請你將 字母異位詞 組合在一起。可以按任意順序返回結果列表。 示例 1: 輸入: strs ["eat", "tea", "tan"…

docker 安裝windows

目錄 下載地址&#xff1a; 使用教程&#xff1a; docker compose 查看版本 測試啟動 hello-world 報錯1 The system cannot find the file specified&#xff1a; 檢查 Docker Desktop 是否運行中 報錯2HF_ENDPOINT 1. 臨時解決方案&#xff08;當前終端會話有效&…

docker compose 和build

目錄 docker compose 和build 的區別是什么&#xff1f; 核心差別&#xff1a; 1. docker build --platform linux/amd64 -f Dockerfile -t infiniflow/ragflow:nightly_lbg . 2. docker compose -f docker-compose-gpu.yml up -d 二者如何配合&#xff1f; 總結 docker …

裂變時刻:全球關稅重構下的券商交易系統躍遷路線圖(2025-2027)

——基于RWA清算、量子加密與實時非線性風控的下一代跨境基礎設施核心事件錨定&#xff1a;特朗普于7月7日對14國啟動分級關稅制裁&#xff08;日韓25%、東南亞30%-40%、金磚關聯國10%附加稅&#xff09;&#xff0c;引發日元兌美元暴跌至144.47、銅價單日跳漲3.2%、散戶單日交…

python爬蟲初入門——基本庫和寫入方法

1.準備環境 python環境&#xff1a;3.10 2.常用庫 1.請求庫&#xff1a;實現 HTTP 請求操作 requests&#xff1a;基于 urllib 編寫的&#xff0c;阻塞式 HTTP 請求庫&#xff0c;發出一個請求&#xff0c;一直等待服務器響應后&#xff0c;程序才能進行下一步處理。seleni…

Sonar掃描C#代碼配置

需要的工具 MSBuild、sonar-scanner-4.6.1.2450-windows、jdk1.8.0_181 下載地址&#xff1a;https://download.csdn.net/download/code12313/91315686 配置sonar的地址 一、環境變量配置 1.新建變量&#xff0c;nameSONAR_RUNNER_MSBUILD_HOME。valueD:\work\dev\dev_serve…

python 在運行時沒有加載修改后的版本

陳舊的Python字節碼 (.pyc 文件)&#xff1a;最常見的原因&#xff01;Python 會把你修改的 .py 文件編譯成 .pyc 字節碼來加速后續運行。有時&#xff0c;即使你修改了 .py 文件&#xff0c;系統可能仍然固執地加載舊的、未被刪除的 .pyc 文件。1. 用“硬編碼探針”強制驗證# …