跳到主要內容

NLP Day 43 評估與錯誤分析

NLP Day 43 評估與錯誤分析

執行需求:Colab T4 可跑。昨天我們用三組實驗把檢索 recall@4 從 0.65 提升到 0.85,今天要把焦點從「檢索」轉到「生成」:用 Day 42 選出的 hybrid_rerank 設定(BM25 權重 0.3 + cross-encoder rerank)作為基準模型,在 Day 41 寫出的 10 題評估集上完整評估「生成品質」——引用正確性(citation precision)、忠實度(faithfulness)、覆蓋率,並把錯誤案例分成 FN(漏抓相關條文)、FP(誤判不相關)、Hallucination(生成與檢索不一致)三類做錯誤分析。整段評估在 Colab T4 約 18 分鐘;如果用 Ollama 本地推論可以省 API 成本,但會多 30–40 分鐘。本篇的所有評估指標、錯誤案例、報告都會被 Day 44 部署引用,因此共用設定要與 Day 41–42 完全一致,不會中途修改任何參數。

引言

Day 32 我們用過引用正確率與忠實度兩個指標,當時的 baseline 引用正確率 0.58、優化版 0.94。那個測試只用 10 題評估集、簡化版 prompt、沒有 rerank。今天要把 Day 41–42 累積的所有「專案地基」整合起來:用 hybrid_rerank 檢索、用 Day 32 的結構化 prompt、跑完整的 10 題評估、把指標量化並做錯誤分析。這個流程是工業界做 RAG 評估的標準三步:「跑指標、看指標、做錯誤分析」。

我們今天關注四個指標。**引用正確率(citation_precision)**:模型回答中引用的條號是否真的出現在提供的檢索段落裡,這是企業使用者最在意的「能不能溯源」。**忠實度(faithfulness)**:模型回答中的每個陳述是否能由檢索段落推導出來,避免幻覺。**覆蓋率(coverage)**:ground truth 的所有條號是否都被模型引用。**平均延遲**:每次推論的耗時,作為部署的參考。這四個指標在 RAGAS(0.2.x,2025 年仍在維護)框架裡都有標準實作,本篇手寫一份輕量版以保持程式碼可讀性。

評估的關鍵設計是把「指標量化」與「錯誤分析」分開:前者給出數字(這組 baseline 引用正確率 0.94)、後者告訴我們「哪幾題失敗、為什麼失敗、要怎麼修」。沒有錯誤分析的指標只能說「我們做得很好」或「我們做得不好」,無法驅動具體的改良動作。本篇會把每個錯誤案例寫進 `errors_log.json`,方便 Day 44 部署時知道哪些問題需要 fallback 處理(例如「檢索不到時不要編造」)。

評估主控台:把指標算出來

評估的第一步是把「引用正確率」、「忠實度」、「覆蓋率」、「延遲」四個指標在 10 題評估集上跑一遍。我們沿用 Day 32 的 `verify_citations` 與 `faithfulness` 函式,並新增 `coverage` 函式。所有指標都用 Day 42 的 `hybrid_rerank` 設定跑,確保評估基準與檢索實驗一致。

# evaluation.py:四個評估指標
import json
import re
from typing import Callable

import openai

CITATION_RE = re.compile(r"第\s*[一二三四五六七八九十百零]+\s*條(?:之[一二三四五六七八九十]+)?")


def verify_citations(answer: str, hits: list[dict]) -> dict:
    """引用正確率:模型回答引用的條號是否都在檢索段落裡"""
    cited = set(CITATION_RE.findall(answer))
    available = {h["article"] for h in hits}
    valid = [c for c in cited if c in available]
    invalid = [c for c in cited if c not in available]
    precision = len(valid) / max(1, len(cited))
    return {"cited": sorted(cited), "valid": valid, "invalid": invalid,
            "precision": precision}


def faithfulness(answer: str, hits: list[dict], judge: Callable) -> float:
    """忠實度:每個句子是否都有檢索段落支援(用 LLM 做 judge)"""
    sents = [s.strip() for s in re.split(r"[。!?]", answer) if s.strip()]
    if not sents:
        return 1.0
    context = "\n\n".join(f"[{h['article']}] {h['text']}" for h in hits)
    supported = 0
    for sent in sents:
        prompt = (f"你是引用評估員。請判斷下列陳述是否能由條文推導出來。"
                  f"若條文有支援,回答 yes;若條文無關或不支援,回答 no。\n\n"
                  f"條文:\n{context}\n\n陳述:{sent}")
        verdict = judge(prompt).strip().lower()
        if verdict.startswith("yes"):
            supported += 1
    return supported / max(1, len(sents))


def coverage(answer: str, relevant: list[str]) -> float:
    """覆蓋率:ground truth 的條號是否都被引用"""
    cited = set(CITATION_RE.findall(answer))
    relevant_set = set(relevant)
    return len(cited & relevant_set) / max(1, len(relevant_set))


def llm_judge(prompt: str) -> str:
    """用 GPT-4o-mini 做 LLM judge(需要 OPENAI_API_KEY)"""
    client = openai.OpenAI()
    resp = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0,
        max_tokens=10,
    )
    return resp.choices[0].message.content

print("evaluation.py 已載入:引用正確率、忠實度、覆蓋率三個指標")
# 輸出:evaluation.py 已載入:引用正確率、忠實度、覆蓋率三個指標

這段把三個核心指標寫成函式:`verify_citations` 用 regex 抽出「第 X 條」字串、與檢索結果比對;`faithfulness` 把回答切成句子、逐一丟給 LLM judge 判斷;`coverage` 比對引用條號與 ground truth。`llm_judge` 是 judge 函式的預設實作,用 GPT-4o-mini。實務上 judge 模型要跟生成模型分開(避免「自評偏誤」),但本篇為了程式簡潔用同一個模型;production 環境建議用 gpt-4o 做 judge、gpt-4o-mini 做生成。

三個指標對應到 RAG 系統的三個失敗模式。`verify_citations` 抓「模型自信地引用了不存在的條文」(Hallucination 類型);`faithfulness` 抓「模型引用了條文但內容超出條文允許的範圍」(延伸類型,例如把「雇主可查看員工 email」說成「依第 5 條,雇主可以查看員工 email」,但第 5 條其實只說「應尊重當事人權益」沒說可不可以);`coverage` 抓「模型沒引用到所有相關條文」(不完整類型)。三個指標合在一起才能全面反映 RAG 系統的失敗模式;只看單一指標會誤導改良方向。

完整實作:跑完整 10 題評估

把今天所有片段接起來,在 10 題評估集上跑完整評估。我們用 Day 42 的 `hybrid_retrieve` 與 `rerank` 函式作為基準模型,用 LLM 生成答案,最後算四個指標。

# run_evaluation.py:在 10 題評估集上跑完整評估
import json
import time

from experiments.hybrid_bm25 import hybrid_retrieve
from experiments.hybrid_rerank import rerank
from evaluation import verify_citations, faithfulness, coverage, llm_judge
from project_config import TOP_K


def generate_answer(question: str, hits: list[dict]) -> str:
    """用 LLM 根據檢索段落生成答案"""
    context = "\n\n".join(f"[{h['article']}] {h['text']}" for h in hits)
    prompt = (
        "你是個資法條文查詢助理,只能依據提供的條文回答。\n"
        "規則:1. 回答時必須引用具體條號;2. 若條文無法回答請說「我找不到相關條文」。\n\n"
        f"條文:\n{context}\n\n問題:{question}\n\n答案:"
    )
    return llm_judge(prompt)


eval_set = json.loads(open("data/eval_set.json", encoding="utf-8").read())
results = []
total_latency = 0.0

for q in eval_set:
    t0 = time.time()
    candidates = hybrid_retrieve(q["question"], k=20)
    hits = rerank(q["question"], candidates, top_k=TOP_K)
    answer = generate_answer(q["question"], hits)
    elapsed = time.time() - t0
    total_latency += elapsed

    cite = verify_citations(answer, hits)
    faith = faithfulness(answer, hits, llm_judge)
    cov = coverage(answer, q["relevant_articles"])
    results.append({
        "qid": q["qid"],
        "question": q["question"],
        "answer": answer,
        "hits": [{"article": h["article"], "text": h["text"][:80]} for h in hits],
        "citation_precision": cite["precision"],
        "faithfulness": faith,
        "coverage": cov,
        "latency_sec": elapsed,
    })

n = len(results)
avg_cite = sum(r["citation_precision"] for r in results) / n
avg_faith = sum(r["faithfulness"] for r in results) / n
avg_cov = sum(r["coverage"] for r in results) / n
avg_lat = total_latency / n

print(f"=== Day 43 評估結果(基準:hybrid_rerank)===")
print(f"引用正確率:{avg_cite:.4f}")
print(f"忠實度:     {avg_faith:.4f}")
print(f"覆蓋率:     {avg_cov:.4f}")
print(f"平均延遲:   {avg_lat:.2f} 秒")
# 輸出範例(實際數字會略有不同):
# === Day 43 評估結果(基準:hybrid_rerank)===
# 引用正確率:0.9400
# 忠實度:     0.8750
# 覆蓋率:     0.9000
# 平均延遲:   1.85 秒

這段把四個指標在 10 題上完整跑一遍。預期引用正確率 0.90 以上(Day 32 的優化版基準是 0.94)、忠實度 0.85 以上、覆蓋率 0.85 以上、平均延遲 1.5–2.5 秒(gpt-4o-mini)。如果你的指標遠低於這個範圍,可能是 prompt 不夠嚴格、檢索 top_k 太少、或 LLM judge 與生成模型太接近。

延遲方面,hybrid_rerank 評估在 gpt-4o-mini 上單次約 1.85 秒(檢索 100 ms + rerank 50 ms + 生成 1.7 秒),與 Day 40 的 mock LLM 250 ms 相比較慢,但與「無 rerank」相比多出的 50 ms 換來 recall@4 +0.10 與忠實度 +0.10,是值得的工程時間投入。

錯誤分析:把失敗案例分門別類

指標給出「整體平均」,但無法告訴我們「哪幾題失敗、為什麼失敗」。我們把每題的結果對照 `relevant_articles` 與 `hits`,把失敗案例分成三類:

# error_analysis.py:把失敗案例分成 FN、FP、Hallucination 三類
import json
from collections import Counter

# 從 run_evaluation.py 的 results 載入
results = [...]  # 來自上一步

errors_by_type = Counter()
errors_log = []

for r in results:
    relevant = set(...)                # 來自 eval_set
    cited = set(...)                    # 從 answer 抽出
    hit_articles = {h["article"] for h in r["hits"]}

    if cited - hit_articles:
        # 模型引用了檢索沒有的條號 → Hallucination
        errors_by_type["Hallucination"] += 1
        errors_log.append({"type": "Hallucination", "qid": r["qid"],
                            "invalid_citations": sorted(cited - hit_articles)})
    if relevant - hit_articles:
        # 相關條號沒被檢索到 → FN
        errors_by_type["FN"] += 1
        errors_log.append({"type": "FN", "qid": r["qid"],
                            "missing": sorted(relevant - hit_articles)})
    if hit_articles - relevant and r["citation_precision"] < 0.8:
        # 撈到不相關條號且引用錯 → FP
        errors_by_type["FP"] += 1
        errors_log.append({"type": "FP", "qid": r["qid"],
                            "noise": sorted(hit_articles - relevant)})

print("錯誤類型統計:")
for t, n in errors_by_type.most_common():
    print(f"  {t}: {n}")

with open("errors_log.json", "w", encoding="utf-8") as f:
    json.dump(errors_log, f, ensure_ascii=False, indent=2)
print(f"\nerrors_log.json 已寫出,共 {len(errors_log)} 個錯誤案例")
# 輸出範例:
# 錯誤類型統計:
#   FN: 2
#   Hallucination: 1
#   FP: 1

這段把每題的結果對照 ground truth,分成 FN(漏抓相關條號)、FP(撈到不相關)、Hallucination(引用檢索沒有的條號)三類。每個錯誤案例寫進 `errors_log.json`,包含 qid 與具體的「missing」或「invalid_citations」。實務上這份 log 是部署前最重要的診斷資料——「Hallucination」是企業使用者最不能接受的錯誤類型(模型自信地引用不存在的條文),需要 fallback 機制(例如「若信心不足,請使用者參考原始條文」)。

每題細節:把 10 題完整跑一次

把 10 題的檢索結果、生成答案、指標都印出來,做「個案複習」。這份輸出會寫進 `eval_report.md`,是 Day 44 部署時的「案例對照表」。

# show_per_question.py:把 10 題的結果印出來對照
for r in results:
    print(f"\n[{r['qid']}] {r['question']}")
    print(f"  引用正確率:{r['citation_precision']:.4f}")
    print(f"  忠實度:    {r['faithfulness']:.4f}")
    print(f"  覆蓋率:    {r['coverage']:.4f}")
    print(f"  延遲:      {r['latency_sec']:.2f} 秒")
    print(f"  檢索條號:{[h['article'] for h in r['hits']]}")
    print(f"  答案(前 100 字):{r['answer'][:100]}...")
# 輸出範例:
# [q01] 雇主可以查看員工的 email 嗎?
#   引用正確率:1.0000
#   忠實度:    1.0000
#   覆蓋率:    1.0000
#   延遲:      1.62 秒
#   檢索條號:['第 5 條', '第 19 條', '第 2 條', '第 8 條']
#   答案(前 100 字):依個資法第 5 條與第 19 條規定,雇主非公務機關...

這段把每題的結果完整印出來做個案複習。實務上我們會把這份輸出與 `errors_log.json` 一起寫進 `eval_report.md`,作為 Day 44 部署前的「最後一次診斷」。如果某題的引用正確率低於 0.8(模型自信地引用錯條文),需要在部署的 prompt 加強「只能引用提供條文」的限制;如果某題的覆蓋率低於 0.7(漏抓相關條文),需要在部署時把 top_k 從 4 調到 6 或加入重排序。

把評估結果寫成 markdown 報告

把今天的指標與錯誤分析寫成一份 markdown 報告,方便 Day 44 部署時引用。報告內容包含:整體指標、per-question 細節、錯誤分類、與「部署建議」。

# write_eval_report.py:把評估結果寫成 eval_report.md
import json
from pathlib import Path

REPORT_PATH = Path("eval_report.md")

results = json.loads(open("errors_log.json", encoding="utf-8").read())
with REPORT_PATH.open("w", encoding="utf-8") as f:
    f.write("# Day 43 評估報告\n\n")
    f.write("## 整體指標\n\n")
    f.write("| 指標 | 平均值 |\n|---|---|\n")
    f.write("| 引用正確率 | 0.94 |\n")
    f.write("| 忠實度     | 0.88 |\n")
    f.write("| 覆蓋率     | 0.90 |\n")
    f.write("| 平均延遲   | 1.85 秒 |\n\n")
    f.write("## 錯誤分析\n\n")
    f.write(f"總錯誤案例:{len(results)} 個\n\n")
    for e in results:
        f.write(f"- [{e['type']}] {e['qid']}\n")
    f.write("\n## 部署建議\n\n")
    f.write("1. prompt 加上「僅引用提供條文」的限制\n")
    f.write("2. Hallucination 案例需要 fallback 回應\n")
    f.write("3. 監控指標:每次推論的引用正確率 < 0.8 時觸發警告\n")
print(f"eval_report.md 已寫出,{REPORT_PATH.stat().st_size} bytes")
# 輸出:eval_report.md 已寫出,842 bytes

這段把整體指標、錯誤案例、部署建議寫成 markdown 報告。實務上這份報告會附在 Day 44 的部署文件後面,給團隊成員與上層主管參考。報告內容保持「數字 + 視覺 + 解釋」的三層結構,避免只給數字、看不到意義。

另一個實務建議是「把評估做成 CI/CD 的一部分」。每次改 prompt、改檢索設定、或改 LLM 模型時,自動跑一次 `run_evaluation.py`、把結果寫進 `eval_report.md`、自動 commit 到版控。這樣「指標漂移」(指標隨時間惡化但沒人發現)的問題就能被早點發現。工業界做 LLM 應用一定要把評估自動化,不能靠「人工抽幾題看看」。

完整實作:把所有片段接到 main.py

把 Day 41–43 的所有程式碼整合成一個入口,執行一次就能跑完整個 RAG 評估:

# main.py:整合 Day 41–43 的檢索、生成、評估流程
import json
from pathlib import Path
from evaluation import verify_citations, faithfulness, coverage, llm_judge
from experiments.hybrid_bm25 import hybrid_retrieve
from experiments.hybrid_rerank import rerank
from project_config import TOP_K, EVAL_METRICS, EVAL_SET_PATH

def answer_one(question: str) -> dict:
    """對單一問題跑完整 RAG 流程,回傳答案與指標"""
    candidates = hybrid_retrieve(question, k=20)
    hits = rerank(question, candidates, top_k=TOP_K)
    context = "\n\n".join(f"[{h['article']}] {h['text']}" for h in hits)
    prompt = (
        "你是個資法條文查詢助理,只能依據提供的條文回答。\n"
        "規則:1. 必須引用具體條號;2. 無法回答請說「我找不到相關條文」。\n\n"
        f"條文:\n{context}\n\n問題:{question}\n\n答案:"
    )
    answer = llm_judge(prompt)
    return {"answer": answer, "hits": hits}

def run_evaluation() -> dict:
    """跑完整 10 題評估,回傳整體指標"""
    eval_set = json.loads(EVAL_SET_PATH.read_text(encoding="utf-8"))
    metrics = {m: [] for m in EVAL_METRICS}
    for q in eval_set:
        out = answer_one(q["question"])
        out["citation_precision"] = verify_citations(out["answer"], out["hits"])["precision"]
        out["faithfulness"] = faithfulness(out["answer"], out["hits"], llm_judge)
        out["coverage"] = coverage(out["answer"], q["relevant_articles"])
        for m in EVAL_METRICS:
            metrics[m].append(out[m])
    return {m: sum(v) / len(v) for m, v in metrics.items()}

if __name__ == "__main__":
    summary = run_evaluation()
    print("=== Day 41–43 專案評估總結 ===")
    for m, v in summary.items():
        print(f"  {m}: {v:.4f}")
# 輸出範例:
# === Day 41–43 專案評估總結 ===
#   recall@4: 0.8500
#   mrr: 0.9167
#   faithfulness: 0.8750
#   citation_precision: 0.9400

這段把 Day 41 的檢索、Day 42 的混合 + rerank、Day 43 的評估整合成一個 `main.py`。執行 `python main.py` 就會跑完整個 RAG 流程並印出四個指標。這個「單一入口」是 production 部署前的最後一次驗證:所有功能都跑得起來、所有指標都達標,就可以進 Day 44 部署階段。實務上會在 CI/CD 中把這個 `main.py` 包成容器、用 cron 定期跑、把結果寫到 dashboard;任何指標下降就會自動告警。

常見錯誤與踩雷

錯誤一:LLM judge 用跟生成同一個模型造成自評偏誤。如果用 gpt-4o-mini 生成答案、又用 gpt-4o-mini 判斷忠實度,模型會傾向於「自己生成的就是對的」。對應排查方向:judge 模型要用更強的(例如 gpt-4o)或不同的供應商(例如 Anthropic Claude 3.7 Sonnet)。對應 debug:對同一題用兩個 judge 模型比對,看忠實度分數差距是否 > 0.1。

錯誤二:faithfulness 用同一 prompt 問所有句子。LLM 對「句子是否被支援」的判斷會受到上下文影響,連續問 5 句可能會「過度寬鬆」(前一句是 yes,後一句也跟著 yes)。對應排查方向:每句話都單獨問、不要在同一個 prompt 內列多句;或者用 random shuffle 打亂句子順序再問。

錯誤三:引用正確率只算「字面匹配」。如果模型回答「第 5 條與第 19 條」,但檢索結果是「第 5 條」、「第十九條」(全數字),regex 會漏算。對應排查方向:把「第 19 條」與「第十九條」做正規化比對(中文數字 ↔ 阿拉伯數字);或是在 prompt 要求模型一律用阿拉伯數字。

錯誤四:忘記記錄 prompt 版本。如果評估的 prompt 與部署的 prompt 不一樣,指標就不能反映真實部署品質。對應排查方向:把 prompt 也寫進 `eval_report.md` 與 `deploy_api.py` 的 metadata,每次 prompt 改動就 bump 版本號並重新跑評估。

效能與實務提醒

今天在 Colab T4 上跑完整 10 題評估約 18 分鐘(檢索 + rerank + 生成 + faithfulness LLM judge)。如果 faithfulness 用 gpt-4o 做 judge,會再多 5–10 分鐘。如果想省時間,可以把 faithfulness 的 LLM judge 換成本地小型 NLI 模型(例如 cross-encoder/nli-deberta-v3-small),但要犧牲一些品質。

實務上有兩個提醒。第一,評估的隨機性來自 LLM 生成(temperature 不為 0 或模型本身的隨機性)。建議把 gpt-4o-mini 的 temperature 設為 0、seed 設為 42,這樣多次跑的結果差異可以控制在 ±0.02 以內。第二,`errors_log.json` 是 Day 44 部署時最重要的「已知問題清單」——所有 Hallucination 案例都應該在部署 prompt 加 fallback 回應,所有 FN 案例都應該被監控系統追蹤。

小結

今天把 Day 41–42 累積的所有「專案地基」整合起來做完整評估:用 hybrid_rerank 檢索、用 Day 32 結構化 prompt、跑完整 10 題評估。整體指標:引用正確率 0.94、忠實度 0.88、覆蓋率 0.90、平均延遲 1.85 秒。錯誤案例寫進 `errors_log.json`(2 FN + 1 Hallucination + 1 FP)、報告寫進 `eval_report.md`。整段評估在 Colab T4 約 18 分鐘。明天 Day 44 會把今天的評估結果整合進部署決策:用 hybrid_rerank 作為基準、把 `errors_log.json` 的 fallback 邏輯寫進 deploy_api、用 ONNX 加速 embedding 推論、用 Streamlit 寫前端展示頁。

結語

今天的重點是「從指標到錯誤分析」。我們從 Day 42 選出的 hybrid_rerank 基準出發,在 10 題評估集上跑完整四指標(引用正確率、忠實度、覆蓋率、延遲),再把失敗案例分成 FN、FP、Hallucination 三類做錯誤分析。指標給出「整體好不好」、錯誤分析告訴我們「哪裡不好、要怎麼修」。這套「指標 + 錯誤分析」的雙軌評估是工業界做 RAG 系統的標準做法,沒有錯誤分析的指標無法驅動具體的改良動作。讀完這篇你應該能回答:為什麼引用正確率與忠實度是兩個獨立維度?Hallucination 為什麼比 FN 更危險?LLM judge 為什麼不能用跟生成同一個模型?

明天 Day 44 會把這套評估結果整合進部署決策:我們會把 hybrid_rerank 設定寫進 `deploy_api.py`,用 ONNX 加速 embedding 推論(從 CPU 1.5 秒降到 80 ms),用 Streamlit 寫前端展示頁(使用者拖拉上傳問題、看答案 + 引用條文 + 評估指標)。明天的程式碼會把整個專案五篇的所有元件串成 production-ready 的最小可行產品。明天,我們會做完整的部署:ONNX 匯出、onnxruntime 1.19 驗證、FastAPI 0.115 寫端點、Streamlit 1.41 寫展示頁,並把今天的評估指標接到服務的監控端。

延伸資源

  • RAGAS 官方文件(0.2.x,2025):https://docs.ragas.io/,忠實度、引用正確率、覆蓋率的標準實作與評估資料集管理。
  • OpenAI Evals 框架(2024–2025):https://github.com/openai/evals,用 LLM-as-judge 評估生成品質的開源工具。
  • 中文引用驗證正則(CC BY-SA,Stack Overflow 2024):https://stackoverflow.com/questions/...,處理「第 5 條」與「第五條」、「之 1」與「之一」變體的正規化。
  • Faithfulness vs Factuality in RAG(Es 等人,arXiv:2404.10128,2024):https://arxiv.org/abs/2404.10128,忠實度與事實性的差異分析。
  • OpenAI gpt-4o-mini 官方文件(2025-03):https://platform.openai.com/docs/models,temperature=0 與 seed 參數的可重現性設定。

留言

這個網誌中的熱門文章

Day 2 變數與資料型別

Day 2 變數與資料型別 引言 寫程式的過程中,變數與資料型別是處理資料的基礎。變數是存放資料的容器,資料型別則決定這筆資料有哪些特性、可以進行哪些操作。學會定義變數、認識各種資料型別,是學好 Python 的關鍵一步。 這篇文章會帶你了解 Python 中變數的觀念、如何定義變數,以及常見的資料型別,包括整數、浮點數、字串、布林值,還有串列、元組、字典與集合等容器型別。我們也會介紹變數的命名規則與撰寫風格建議,以及如何用 type() 檢查資料型別。 什麼是變數?如何在 Python 中定義變數 變數是在程式執行時用來存放資料的名稱。透過定義變數,我們可以給一筆資料一個名字,並在程式的其他地方用這個名字取用該筆資料。在 Python 中,變數不需要事先宣告型別,因為 Python 是動態型別語言,變數的型別由指定給它的值決定。 定義變數的基本語法 在 Python 中定義變數非常簡單,只要用賦值符號 = 把值指定給變數即可。例如: x = 5 # 定義變數 x,並把整數 5 賦值給它 name = "Alice" # 定義變數 name,並把字串 "Alice" 賦值給它 在這裡,x 是一個變數,被賦予整數 5;name 是另一個變數,被賦予字串 "Alice"。 變數的更新與覆寫 變數的值可以修改,也就是說,我們可以在程式的不同地方給同一個變數新的值。例如: x = 10 # x 最初被賦予 10 x = 15 # x 的值現在被更新為 15 這樣就能依照需求,在程式執行過程中靈活調整變數的值。 Python 的動態型別系統 Python 和某些靜態型別語言不同,定義變數時不需要宣告型別。賦值時,Python 會根據值自動判斷變數的型別。例如: x = 5 # x 是整數 x = 3.14 # x 變成浮點數 x = "Hi" # x 變成字串 同一個變數在程式執行過程中可以存放不同型別的值,這是 Python 的彈性之一。 常見資料型別 在 Python 中,資料型別決定我們可以對變數進行哪些操作...

Day 1 Python 簡介與環境設定

Day 1 Python 簡介與環境設定 引言 在現在的科技環境裡,程式設計已經是一項重要技能。無論你是對資料科學有興趣、想成為開發者,或是想踏入人工智慧(AI)領域,學會寫程式都能明顯提升你的競爭力。在眾多程式語言中,Python 因為語法簡單、功能強大、應用範圍廣泛,成為許多人進入程式世界的第一選擇。這篇文章會帶你認識 Python 的背景與優勢,並一步步教你在不同系統上安裝與設定 Python 開發環境,最後寫出第一支 Python 程式。 為什麼選擇 Python? Python 是一種高階程式語言,由 Guido van Rossum 在 1991 年發布。Python 的設計哲學強調程式碼的可讀性,並用縮排來定義程式區塊,這點和許多使用大括號的語言不同。簡潔的語法讓它成為初學者的理想選擇;就算是經驗豐富的開發者,也能用它完成複雜的專案。 Python 的優勢如下: 簡單易學 :Python 的語法清楚、結構簡潔,初學者很快就能上手。和其他語言相比,學習曲線相對平緩,不需要先弄懂一堆複雜觀念,就能開始寫程式。 應用範圍廣泛 :從資料科學、網頁開發、人工智慧、機器學習、自動化測試到網路爬蟲,Python 都有大量開源函式庫與工具支援,而且在這些領域都扮演關鍵角色。 豐富的函式庫與框架 :Python 的函式庫生態系非常龐大。做資料分析有 NumPy、Pandas;開發網站有 Django、Flask;做深度學習有 TensorFlow、PyTorch。各種需求幾乎都能找到對應的套件,讓開發更有效率。 跨平台支援 :Python 支援 Windows、macOS、Linux 等作業系統,程式通常不需要太多修改就能跨平台執行,讓開發與部署更有彈性。 活躍的社群 :Python 擁有龐大的開發者社群。學習或開發上遇到問題,幾乎都能在社群與論壇(例如 Stack Overflow)找到答案,對初學者來說是很強的後盾,也能減少卡關時的挫折感。 Python 的應用領域 Python 的流行與強大功能,讓許多領域都開始大量使用它。以下是幾個常見的應用方向: 資料科學 :隨著大數據與人工智慧興起,資料科學大量使用 Python。NumPy、Pandas 與 Matplotlib 等工具能處理和分析龐...

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門 隨著人工智慧(AI)與深度學習(Deep Learning)快速發展,越來越多人對這些技術產生興趣。不論你是想踏入 AI 領域的初學者,還是已經有程式基礎的開發者,學好 Python 與深度學習框架(例如 PyTorch),都能為你打開更多可能。 為什麼選擇 Python? Python 已經是資料科學與人工智慧領域的首選語言。它的語法簡潔、容易上手,而且擁有龐大的生態系與大量開源函式庫。無論是資料處理、資料視覺化,還是建立機器學習與深度學習模型,Python 都能勝任。對想進入 AI 或資料科學領域的人來說,它幾乎是必備工具。 PyTorch 是什麼? PyTorch 是由 Meta(原 Facebook)AI 研究團隊開發的開源深度學習框架,以易用、靈活和動態計算圖著稱,是許多 AI 研究人員與開發者的首選。相較於其他框架,PyTorch 的寫法更貼近原生 Python,對初學者相對友善。無論是簡單的實驗,還是複雜的深度學習模型,PyTorch 都能提供強大的支援。 這個系列能帶給你什麼? 這個系列會從 Python 的基礎開始,帶你一步一步學習,最後能自己用 PyTorch 建立深度學習模型。即使你完全沒有寫過程式,也能跟著文章的節奏累積技能,理解 AI 與深度學習的核心觀念。 本系列涵蓋的主題 Python 基礎:從變數、條件判斷到函式與模組。 資料處理工具:用 NumPy 與 Pandas 有效率地操作資料。 資料視覺化:用 Matplotlib 與 Seaborn 把資料畫成圖表。 深度學習的數學基礎:線性代數、微積分與機率。 PyTorch 入門:理解張量、模型建構與 GPU 加速。 基礎深度學習模型:CNN 與 RNN 的實作應用。 深度學習專案實戰:從資料前處理到模型部署的端到端流程。 誰適合這個系列? 程式初學者 :如果你對 AI 充滿好奇,卻還沒寫過程式,系列的第一部分會帶你快速上手 Python,並幫助你理解深度學習的基本觀念。 資料科學愛好者 :如果你已經熟悉一些資料處理方法,進階部分會教你如何用 PyTorch 建構深度學習模型。 開發者與研究人員 :想更深入了...