應用場景與解決方案

AI 分析商品評價與差評:用本地大模型做情感分析和維度標註,按商品彙總主要問題

6 個步驟 14 分鐘閱讀 8 次閱讀 0
本文目錄

一個商品在 Shopee、Lazada、Amazon、TikTok Shop 和獨立站上會積累數百條評價,而且往往涉及多種語言。星級評分只能說明出了問題,卻說明不了是什麼問題。本文用本地大語言模型逐條閱讀評價,記錄每條評價的整體情感傾向、它稱讚或批評的商品維度,以及提到的具體問題。隨後按商品生成報告,列出被批評最多的維度、評分與內容不符的評價,以及由 AI 總結的主要問題和改進建議。整個流程都在你自己的伺服器上執行,客戶的評價內容不會傳送給第三方。

請僅通過平台允許的方式獲取評價,例如賣家中心匯出、官方 API 或自有店鋪的資料庫。爬取電商平台資料可能違反其服務條款。分析前請刪除不需要的個人資訊。

步驟 1:安裝工具

apt install -y python3-venv
python3 -m venv /opt/reviews
/opt/reviews/bin/pip install ollama numpy scikit-learn
ollama pull qwen2.5:7b

Ollama 的安裝配置請參閱使用 Ollama 執行本地大模型。本文用不到 numpy 和 scikit-learn,但配套教程中的話題分析會用到它們。

步驟 2:準備評價資料

把評價匯出為 UTF-8 編碼的 CSV 檔案。id 和 text 兩列為必填;sku、rating(1 到 5)和 date 為可選列,但有了它們,報告會更有參考價值:

id,sku,rating,date,text
R1001,LS-01,2,2026-09-14,"The stand wobbles when I type, screws came loose after a week."
R1002,LS-01,5,2026-09-15,"Sturdy, looks great on my desk, easy to fold."
R1003,BT-07,1,2026-09-15,"左耳機三天就沒聲音了,客服也沒回復。"

步驟 3:建立分析指令碼

cat > /opt/reviews/reviews.py <<'EOF2'
import csv, json, os, sys
from collections import Counter, defaultdict
import ollama

MODEL = os.environ.get("MODEL", "qwen2.5:7b")
LANGUAGE = os.environ.get("REPORT_LANG", "English")       # language of issues, summaries and the report
ASPECTS = ["quality", "size_fit", "function", "durability", "ease_of_use",
           "delivery", "packaging", "price_value", "customer_service", "other"]
SENT = {"type": "string", "enum": ["positive", "neutral", "negative"]}
SCHEMA = {
    "type": "object",
    "properties": {
        "sentiment": SENT,
        "aspects": {"type": "array", "items": {"type": "object", "properties": {
            "aspect": {"type": "string", "enum": ASPECTS}, "sentiment": SENT}, "required": ["aspect", "sentiment"]}},
        "issues": {"type": "array", "items": {"type": "string"}},
        "summary": {"type": "string"},
    },
    "required": ["sentiment", "aspects", "issues", "summary"],
}
SYSTEM = ("You analyse customer reviews for an online shop. The review can be in any language. "
          "Give the overall sentiment, and the sentiment of each product aspect the review actually mentions. "
          f"List concrete problems as short phrases in {LANGUAGE} (empty list if there are none) "
          f"and write a one-sentence summary in {LANGUAGE}. Do not invent anything that is not in the review.")

def ask(system, text, schema=None):
    r = ollama.chat(model=MODEL, format=schema, options={"temperature": 0}, messages=[
        {"role": "system", "content": system}, {"role": "user", "content": text}])
    return r.message.content

src, out = sys.argv[1], "reviews_tagged.csv"
done = {}
if os.path.exists(out):
    with open(out, encoding="utf-8-sig") as f:
        done = {r["id"]: r for r in csv.DictReader(f)}
with open(src, encoding="utf-8-sig") as f:
    reviews = [r for r in csv.DictReader(f) if r.get("text", "").strip()]

fields = ["id", "sku", "rating", "sentiment", "aspects", "issues", "summary", "text"]
new_file = not os.path.exists(out)
with open(out, "a", newline="", encoding="utf-8-sig") as f:
    w = csv.DictWriter(f, fieldnames=fields)
    if new_file:
        w.writeheader()
    for r in reviews:
        if r["id"] in done:
            continue
        d = json.loads(ask(SYSTEM, r["text"][:4000], SCHEMA))
        row = {"id": r["id"], "sku": r.get("sku", ""), "rating": r.get("rating", ""), "sentiment": d["sentiment"],
               "aspects": "; ".join(f"{a['aspect']}:{a['sentiment']}" for a in d["aspects"]),
               "issues": "; ".join(i.strip() for i in d["issues"] if i.strip()), "summary": d["summary"], "text": r["text"]}
        w.writerow(row)
        f.flush()
        done[r["id"]] = row
        print(r["id"], d["sentiment"], flush=True)

by_sku = defaultdict(list)
for row in done.values():
    by_sku[row["sku"] or "-"].append(row)
with open("report.md", "w", encoding="utf-8") as f:
    for sku, rows in sorted(by_sku.items(), key=lambda x: -len(x[1])):
        sent = Counter(r["sentiment"] for r in rows)
        neg = Counter(a.split(":")[0] for r in rows for a in r["aspects"].split("; ") if a.endswith(":negative"))
        issues = [i for r in rows for i in r["issues"].split("; ") if i]
        odd = [r["id"] for r in rows if r["rating"].isdigit() and ((int(r["rating"]) >= 4 and r["sentiment"] == "negative")
               or (int(r["rating"]) <= 2 and r["sentiment"] == "positive"))]
        f.write(f"## {sku}: {len(rows)} reviews\n\n")
        f.write(f"- Positive {sent['positive']}, neutral {sent['neutral']}, negative {sent['negative']}\n")
        f.write("- Most criticised aspects: " + (", ".join(f"{a} ({n})" for a, n in neg.most_common(5)) or "none") + "\n")
        f.write("- Rating does not match the text: " + (", ".join(odd) or "none") + "\n\n")
        if issues:
            f.write(ask(f"You are a product manager. Group these customer complaints into the main problems, "
                        f"most frequent first, and suggest one concrete fix for each. Answer in {LANGUAGE}, briefly.",
                        "\n".join(issues[:300])) + "\n\n")
        print("report:", sku, flush=True)
print("done: reviews_tagged.csv, report.md")
EOF2

JSON Schema 強制模型按固定結構作答:三種情感傾向之一、從你的列表中選取的維度,以及問題列表。每條評價分析完成後立即儲存,再次執行時會跳過已完成的評價,因此可以隨時中斷和繼續,之後也可以把新評價追加到同一個 CSV 檔案中。

步驟 4:執行分析

cd /data/reviews
REPORT_LANG="Simplified Chinese" nohup /opt/reviews/bin/python /opt/reviews/reviews.py reviews.csv > reviews.log 2>&1 &
tail -f reviews.log

在 CPU 伺服器上,7B 模型處理每條評價需要幾秒到幾十秒,具體取決於評價長度;資料量大的匯出檔案可以放在夜間執行,或者通過 MODEL=qwen2.5:3b 換用 qwen2.5:3b 等更小的模型。結果檔案為 reviews_tagged.csv(每條評價一行)和 report.md(每個商品一節)。

步驟 5:解讀結果

  • 被批評最多的維度(報告中的 Most criticised aspects)顯示商品讓人失望的地方:耐用性、尺碼、物流或包裝問題需要不同的解決辦法,也由不同的團隊負責。
  • 評分與內容不符(報告中的 Rating does not match the text)會列出諸如仍在抱怨(多半是物流問題)的五星評價,以及實際上是好評的一星評價。這兩類都值得看一看。
  • AI 總結會把投訴歸納為幾個主要問題,併為每個問題給出一條改進建議;可以直接轉給產品開發團隊或供應商。
  • 在 reviews_tagged.csv 中按商品和負面情感篩選,即可閱讀每個問題背後的原始評價。

請根據你的類目調整 ASPECTS 列表,例如服裝類可以用 fabric、size_fit 和 colour(面料、尺碼、顏色),電子產品可以用 battery、connectivity 和 sound(電池、連線、音質)。

步驟 6:形成例行流程

每月匯出一次新評價,用同一個檔案執行指令碼,並對比不同時期的報告。如果想發現意料之外的問題,可以按照用 Embedding 向量把評價歸類成話題的方法對評價進行聚類。如果想更快地回覆評價,請參閱用 AI 起草買家評價回覆。客戶稱讚最多的地方,也是撰寫商品詳情的好素材。

常見問題

分析結果準確嗎?

對於表達清晰的評價,情感傾向和維度的判斷都比較可靠。反諷、褒貶參半的評價以及“ok”這類極短的文本則較難判斷。在依賴這些統計數字之前,請隨機抽取 20 條評價與結果核對,並把溫度保持為 0,以獲得一致的回答。

能用同樣的方法分析工單或聊天記錄嗎?

可以。把每張工單或每段對話放入 text 列,並把維度替換為你的客服分類,例如帳單、物流、安裝設定或帳戶。

可以改用雲端 AI 模型嗎?

很多 AI API 都支援結構化輸出,但這樣評價內容就會離開你的伺服器。請先確認你的隱私合規義務、服務商的服務條款及其支援的地區。

如果按以上步驟操作後問題仍未解決,請提交工單聯絡 IMIDC 7×24 技術支援,並附上伺服器 IP、所用的模型、CSV 檔案的前幾行(去除個人資訊)以及報錯資訊,方便工程師快速定位。

這篇文章有幫助嗎?

相關教程