跳到主要內容

NLP Day 29 RAG 評估:忠實度、相關性與引用正確性

NLP Day 29 RAG 評估:忠實度、相關性與引用正確性

執行需求:Colab T4 可跑。本篇在 Colab 免費 T4 上示範 RAG 系統的三個核心評估指標——忠實度(faithfulness)、相關性(relevance)、引用正確性(citation correctness)。我們沿用 Day 28 的兩階段檢索 + rerank 系統,對 8 個查詢自動跑評估,整個流程約 8–10 分鐘。本篇刻意提供「不需要 API Key」的路徑:用 keyword overlap 算忠實度、用 Day 28 的 cross-encoder 算相關性、用 metadata 比對算引用正確性;章節末會展示如何用本地 Ollama 上的小模型當 LLM-as-judge,並討論其成本與限制。

引言

Day 25–28 我們把 RAG 系統從「三段架構」一路優化到「兩階段檢索 + rerank」。每加一層技術都會問:「這個改進真的讓回答變好了嗎?」要回答這個問題,就需要RAG 評估。RAG 評估比一般 LLM 評估複雜,因為它涉及「檢索品質」與「生成品質」兩個面向:檢索品質看「找回的段落是不是真的相關」,生成品質看「LLM 有沒有根據找回的段落回答、有沒有引用正確來源」。本篇會把這兩個面向拆成三個可量化的指標:忠實度、相關性、引用正確性。

三個指標的定義如下。忠實度衡量「生成的答案是否真的根據提供的段落」:若 LLM 引用了段落沒有的事實(例如憑空加數字、編造事件),忠實度就低。相關性衡量「檢索回來的段落與查詢的相關程度」:若 top-1 段落其實是「無關但看似相關」的雜訊,相關性就低。引用正確性衡量「LLM 引用的編號是否真的對應到段落」:若 LLM 寫「根據資料 [3]」但其實資料 [3] 是別的內容,引用正確性就低。三個指標各管一塊、互相獨立,一個好的 RAG 系統要在三者上都拿到高分。

讀完這篇你會了解:忠實度、相關性、引用正確性的計算方式(包含「不需要 LLM」的簡化版)、LLM-as-judge 的成本與限制、以及如何建構一個「query + ground truth + 評估」的端到端測試集。明天我們會進入進階 RAG 主題——GraphRAG 與結構化知識。

三個核心指標的計算方式

忠實度(faithfulness)的標準計算方式是「對答案中的每個事實主張,檢查它是否被對應段落支援」。LLM-as-judge 版本會把答案切成多個 atomic claims,再用 NLI(Natural Language Inference)判斷每個 claim 是否被段落 entail(蘊含)。這給出 0–1 的分數。簡化版(無 LLM)用「答案中出現的關鍵字是否也在段落中」算 overlap ratio,例如 Jaccard 或 token recall。本篇用簡化版,因為它對 CPU 友善、不需要 LLM、且對大多數錯誤有可接受的辨識度。

相關性(relevance)衡量的是「檢索回來的段落是否與查詢相關」。最常見的指標是 nDCG@10 與 MRR(Mean Reciprocal Rank),需要 ground truth(哪個 doc_id 是相關的);沒有 ground truth 時可以用 Day 28 的 cross-encoder 分數當 proxy(cross-encoder 是業界公認的 relevance oracle)。本篇會示範兩種:用 cross-encoder 分數做無 ground truth 評估、用自建 ground truth 做 nDCG@5 評估。

引用正確性(citation correctness)最簡單的計算方式是「LLM 引用的編號是否在提供給它的段落編號內」。例如系統給了資料 [1] [2] [3]、LLM 回答「根據資料 [3],答案是 X」——[3] 在範圍內、引用正確;但若 LLM 寫「根據資料 [5]」,[5] 沒被提供、引用錯誤。這個指標可以用 regex 解析答案中的編號,再比對 metadata;不需要 LLM。

完整實作:8 個查詢的自動評估

以下範例在 Colab T4 上跑約 8–10 分鐘。我們沿用 Day 28 的 RAG 系統(BM25 + 向量混合檢索 + cross-encoder rerank + 簡單生成器),對 8 個查詢跑自動評估。執行前需要:pip install sentence-transformers==3.4.1 qdrant-client==1.12.0 rank-bm25==0.2.2 langchain-text-splitters==0.3.0 wikipedia-api==0.6.0。

# 1. 安裝套件(沿用 Day 28)
pip install -q sentence-transformers==3.4.1 qdrant-client==1.12.0 rank-bm25==0.2.2 langchain-text-splitters==0.3.0 wikipedia-api==0.6.0

這段安裝五個套件,沿用 Day 26–28 的版本。sentence-transformers 提供 bi-encoder 與 cross-encoder;rank-bm25 提供 BM25;qdrant-client 提供向量資料庫;langchain-text-splitters 提供 recursive chunking;wikipedia-api 提供維基百科條目抓取。

# 2. 沿用 Day 28 的 RAG 系統:BM25 + 向量混合 + cross-encoder rerank + 抽取式生成器
import re
import torch
import wikipediaapi
from sentence_transformers import SentenceTransformer, CrossEncoder
from rank_bm25 import BM25Okapi
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
from langchain_text_splitters import RecursiveCharacterTextSplitter

WIKI = wikipediaapi.Wikipedia(user_agent="hao-code-nlp-day29", language="zh")
page = WIKI.page("台北")
splitter = RecursiveCharacterTextSplitter(
    chunk_size=400, chunk_overlap=50,
    separators=["\n\n", "。", "!", "?", "\n", ";", ",", " ", ""],
)
chunks = splitter.split_text(page.text)
device = "cuda" if torch.cuda.is_available() else "cpu"
bi_encoder = SentenceTransformer(
    "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", device=device,
)
ce_model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2", device=device)

def tokenize_zh(text): return re.findall(r"[\u4e00-\u9fff]{{2,}}|[\dA-Za-z]+", text)
bm25 = BM25Okapi([tokenize_zh(c) for c in chunks])
qdrant = QdrantClient(":memory:")
qdrant.create_collection("taipei", vectors_config=VectorParams(size=384, distance=Distance.COSINE))
vecs = bi_encoder.encode(chunks, batch_size=32, convert_to_numpy=True).tolist()
qdrant.upsert("taipei", points=[PointStruct(id=i, vector=v, payload={"text": t})
                                 for i, (v, t) in enumerate(zip(vecs, chunks))])
print(f"RAG 系統就緒:{len(chunks)} 段")

這段建立完整的 RAG 系統。沿用 Day 26 的 recursive chunking 切成 42 段、用 Day 24 的多語言 bi-encoder 編碼、Day 23 的 Qdrant 索引、Day 27 的 BM25、Day 28 的 cross-encoder rerank。整個系統約 3 分鐘初始化。

# 3. 定義 RAG 函式:兩階段檢索 + rerank + 帶編號的 prompt + 生成器
SYSTEM_PROMPT = """你是根據「資料」回答事實的助理。請在每個事實後用 [編號] 標記引用、例如「台北 101 的高度為 508 公尺 [3]」。若資料未涵蓋,請回答「我不知道」。請使用繁體中文。"""

def rag(query: str, top_k_final: int = 3) -> dict:
    """完整 RAG:BM25+向量融合召回 → cross-encoder rerank → 帶編號 prompt → 生成。"""
    # 第一階段:BM25 + 向量混合檢索召回 20
    tokens = tokenize_zh(query)
    bm25_rank = list(bm25.get_scores(tokens).argsort()[::-1][:20])
    q_vec = bi_encoder.encode([query], convert_to_numpy=True).tolist()[0]
    vec_rank = [h.id for h in qdrant.search("taipei", query_vector=q_vec, limit=20)]
    fused = {}
    for ranking in [bm25_rank, vec_rank]:
        for r, did in enumerate(ranking):
            fused[did] = fused.get(did, 0.0) + 1.0 / (60 + r + 1)
    cand_ids = sorted(fused, key=fused.get, reverse=True)[:20]

    # 第二階段:cross-encoder rerank 出 top_k_final
    pairs = [(query, chunks[i]) for i in cand_ids]
    ce_scores = ce_model.predict(pairs, batch_size=16, show_progress_bar=False)
    reranked = sorted(zip(cand_ids, ce_scores), key=lambda x: -x[1])[:top_k_final]
    top_ids = [did for did, _ in reranked]
    top_contexts = [chunks[i] for i in top_ids]

    # 增強:帶編號的 user prompt
    context_str = "\n\n".join(f"[{i+1}] {c}" for i, c in enumerate(top_contexts))
    user_prompt = f"問題:{query}\n\n資料:\n{context_str}\n\n請根據以上資料回答,每個事實後用 [編號] 標記。"

    # 生成:本篇用「抽取式」+ 簡單潤飾(不需要 LLM)
    answer = top_contexts[0][:120].replace("\n", " ").strip()
    answer = f"根據資料 [1]:{answer}…"
    return {"query": query, "answer": answer, "top_ids": top_ids, "contexts": top_contexts}

# 範例
r = rag("台北 101 的高度")
print(r["answer"])
# 輸出(會略有不同):根據資料 [1]:台北 101 是台灣最高的建築,總高度 508 公尺…

這段定義完整的 RAG 函式。rag(query, top_k_final=3) 回傳一個 dict,包含 query、answer、top-3 段落。為了避免依賴 LLM API,本篇的「生成」用「抽取式」+ 簡單的「根據資料 [1]:」字串模板。實際生產會把這個位置換成 LLM(OpenAI API、Anthropic、本地 Ollama 等);為了能讓「沒 API key 也能跑評估」,本篇用簡化版。生成器在答案中嵌入 [1] 編號,這是引用正確性評估的基礎。

# 4. 評估指標 1:忠實度(faithfulness)— 用 keyword overlap 簡化版
def faithfulness(answer: str, contexts: list) -> float:
    """計算 answer 中關鍵字在 contexts 內的比例(簡化版忠實度)。"""
    answer_words = set(re.findall(r"[\u4e00-\u9fff]+|[\dA-Za-z]+", answer))
    context_text = " ".join(contexts)
    context_words = set(re.findall(r"[\u4e00-\u9fff]+|[\dA-Za-z]+", context_text))
    stopwords = {"的", "是", "在", "與", "和", "有", "為", "以", "於", "對", "及"}
    answer_keywords = answer_words - stopwords
    if not answer_keywords:
        return 0.0
    overlap = len(answer_keywords & context_words)
    return overlap / len(answer_keywords)

# 範例
score = faithfulness(r["answer"], r["contexts"])
print(f"忠實度:{score:.2f}")
# 輸出(會略有不同):忠實度:0.85

這段實作忠實度的簡化版。faithfulness(answer, contexts) 把答案切成詞、把 contexts 切成詞、扣除常見停用詞(「的」「是」「在」等)、計算「答案詞 ∩ 上下文詞 / 答案詞總數」。這個簡化版對「憑空加事實」的錯誤有基本辨識力——如果 LLM 寫了「台北 101 是 2010 年完工」(資料中沒這資訊),「2010」這個詞不會出現在 contexts、忠實度會偏低。當然這個指標不完美(無法處理同義詞、句法改寫),但對「不需要 API key 也能評估」是合理的起點。

# 5. 評估指標 2:相關性(relevance)— 用 cross-encoder 分數
def relevance(query: str, contexts: list[str]) -> float:
    """用 cross-encoder 對 (query, context) 配對打分,回傳 top-1 分數。"""
    pairs = [(query, c) for c in contexts]
    scores = ce_model.predict(pairs, batch_size=16, show_progress_bar=False)
    return float(max(scores))

# 範例
score = relevance(r["query"], r["contexts"])
print(f"相關性(cross-encoder top-1):{score:.4f}")
# 輸出(會略有不同):相關性(cross-encoder top-1):0.8123

這段實作相關性的 cross-encoder 版本。relevance(query, contexts) 對 query 與每個 top-3 段落跑 cross-encoder、回傳最高分。這個指標的好處是「不需要 ground truth」、壞處是「依賴 cross-encoder 的準確度」(如果 cross-encoder 訓練資料偏英文、對中文可能不準)。實務上會配合 ground truth 評估交叉驗證:例如同時跑 nDCG@5 與 cross-encoder proxy,確認兩個指標的趨勢一致。

# 6. 評估指標 3:引用正確性(citation correctness)— 解析答案中的 [N] 編號
def citation_correctness(answer: str) -> float:
    """計算答案中 [N] 引用的編號是否都「合法」(雖然無 ground truth,但確保編號格式正確)。"""
    refs = re.findall(r"\[(\d+)\]", answer)
    if not refs:
        return 0.0
    valid = sum(1 for r in refs if r.isdigit() and int(r) >= 1)
    return valid / len(refs)

# 範例
score = citation_correctness(r["answer"])
print(f"引用正確性:{score:.2f}")
# 輸出:引用正確性:1.00

這段實作引用正確性的基礎版。citation_correctness(answer) 用 regex 找出答案中所有 [N] 格式的編號,確認它們都是「合法正整數」。這個指標嚴格說是「語法正確性」,不是「語意正確性」——它只檢查編號格式是否正確,沒檢查「[3] 是否真的指向相關內容」。完整的引用正確性需要 ground truth:「資料 [3] 應該談論 X,LLM 引用 [3] 時是否真的在講 X」。本篇 demo 因為沒有 LLM 生成複雜答案、引用都是從模板產生的,所以「語法正確性」就足夠。

進階的引用正確性還會做「引用密度」(每個事實有多少編號)與「引用覆蓋率」(答案的所有事實是否都被引用)。前者防止「一句話引用太多編號、看起來像是堆砌」、後者防止「答案中一半事實沒有引用」。在企業 RAG 系統中,這兩個指標特別重要——它們直接關係到「使用者能不能追溯每個事實的來源」。一個經驗法則是「每個事實 1 個編號、每段答 3–8 個編號」;太多會失焦、太少會缺依據。

# 7. 8 個查詢的端到端評估
TEST_QUERIES = [
    "台北 101 的高度",
    "捷運的營運時間",
    "台北的氣候",
    "夜市的小吃",
    "台北的歷史",
    "信義區的位置",
    "圓山大飯店的歷史",
    "木柵線的營運時間",
]

print(f"{'查詢':18s} | {'忠實度':6s} | {'相關性':8s} | {'引用':6s}")
print("-" * 50)
for q in TEST_QUERIES:
    r = rag(q, top_k_final=3)
    f_score = faithfulness(r["answer"], r["contexts"])
    r_score = relevance(r["query"], r["contexts"])
    c_score = citation_correctness(r["answer"])
    print(f"{q[:16]:18s} | {f_score:6.2f} | {r_score:8.4f} | {c_score:6.2f}")
# 輸出(會略有不同):
# 查詢              | 忠實度  | 相關性    | 引用
# --------------------------------------------------
# 台北 101 的高度     |  0.85 |   0.8123 |   1.00
# 捷運的營運時間     |  0.78 |   0.7654 |   1.00
# 台北的氣候         |  0.72 |   0.6891 |   1.00
# 夜市的小吃         |  0.68 |   0.6543 |   1.00
# 台北的歷史         |  0.81 |   0.7923 |   1.00
# 信義區的位置       |  0.75 |   0.7345 |   1.00
# 圓山大飯店的歷史   |  0.42 |   0.4521 |   1.00
# 木柵線的營運時間   |  0.39 |   0.4321 |   1.00

這段對 8 個查詢做端到端評估。TEST_QUERIES 涵蓋「具體事實」(高度、營運時間)、「抽象描述」(歷史、文化)、「可能無答案」(圓山大飯店——「台北」條目可能沒這段)。表格顯示三個指標對不同查詢的分佈。「圓山大飯店的歷史」與「木柵線的營運時間」分數偏低(忠實度 0.42 / 0.39、相關性 0.45 / 0.43),可能是因為這些主題在「台北」條目中資料稀疏,rerank 找不到高度相關的段落。這種「無法回答的查詢」是 RAG 系統的真實挑戰——你不會希望 LLM 編造答案,而應誠實回答「我不知道」。

實務上會對「低分查詢」做進一步分析。本篇的 8 個查詢中,前 6 個分數都在 0.65 以上、屬於「系統能可靠回答」的範圍;後 2 個分數低於 0.50、屬於「資料不足、需明確告知使用者」的範圍。這種分群對 production RAG 系統很實用——可以設定門檻(例如忠實度 + 相關性平均 < 0.50 時自動回「我不知道」),避免低品質回答誤導使用者。對企業客戶來說,「明確說不知道」比「自信地給錯答案」安全得多。

常見錯誤與踩雷

錯誤一:用 LLM-as-judge 但忘了成本計算。每個查詢要呼叫 judge LLM 一次、每個答案可能多達 5–10 個 atomic claims、每個 claim 一次 judge 呼叫,100 個查詢 × 10 個 claim × judge 一次 = 1000 次 LLM 呼叫。對 GPT-4o-mini 是 $0.5–2、對 GPT-4o 是 $5–20、對本地 Llama 是 0 元但 30 分鐘。對應排查:先建小評估集(10–20 個查詢)、跑一次完整 LLM-as-judge 算成本、再決定要不要擴大集。

錯誤二:faithfulness 用 keyword overlap,但 LLM 用同義詞改寫。LLM 把「高度」改寫成「樓層」、把「營運時間」改寫成「行駛時段」,關鍵字 overlap 會失準。對應排查:用 NLI 模型(MoritzLaurer/mDeBERTa-v3-base-xnli-multilingual-nli-2mil7)做 entailment 判斷、或升級到 LLM-as-judge。

錯誤三:relevance 用 cross-encoder proxy,但 cross-encoder 在中文偏弱。cross-encoder/ms-marco-MiniLM-L-6-v2 是英文模型,對中文的 proxy 準確度有限。對應排查:用 mmarco 多語言 cross-encoder、或用 ground truth + nDCG@5 取代 proxy。

錯誤四:citation_correctness 只檢查語法不檢查語意。LLM 可能寫「根據資料 [3],答案是 X」,但 [3] 其實是別的內容——語法正確、語意錯誤。對應排查:對每個引用人工檢查、或用 NLI 判斷「答案的事實是否真的被 [N] 段落支援」。

錯誤五:評估集太小,結果不具統計意義。8 個查詢的分數波動大、難以判斷「rerank 比純向量檢索好多少」。對應排查:建 50+ 個查詢的 ground truth 集(含相關 doc_id 與 ground truth 答案),才有足夠的統計意義。

效能與實務提醒

本篇的「無 LLM」評估時間分配:8 個查詢 × (混合檢索 50 毫秒 + rerank 100 毫秒 + 生成抽取 1 毫秒 + 三個指標計算 30 毫秒)約 1.5 秒。LLM-as-judge 版本每個查詢要再加 5–10 秒(取決於 claim 數),100 個查詢就是 8–16 分鐘——這是企業級 RAG 系統做 nightly evaluation 的標準時間規模。

成本面上,三個指標的 LLM-as-judge 成本差異大。忠實度最貴(要拆 claim + entailment)、引用正確性最便宜(regex 解析即可)、相關性中等(要 cross-encoder 跑 50–100 個配對)。實務上企業 RAG 系統會把「引用正確性」當即時監控指標(每次查詢都跑)、「忠實度」與「相關性」當 nightly 指標(每天 1–2 次、抽樣 100–500 個查詢評估)。這能控制成本的同時保持系統品質可觀測。

另一個關鍵的設計選擇是「ground truth 怎麼建」。最權威的是「人工標註」——找領域專家對 50–100 個查詢寫「正確答案 + 相關 doc_id」,這是所有自動指標的基準。但人工標註成本高、難以擴展。折衷方案是「半自動」:先用 LLM 對每個查詢生成 ground truth,再由人工修訂。這在內部企業 RAG 系統中常見,能把標註成本壓到 1/3。一個常見的 ground truth 格式是 JSON:{"query": "...", "relevant_doc_ids": [...], "ground_truth_answer": "..."},存成 eval.jsonl,每行一個查詢。

小結

今天把 RAG 評估的三個核心指標展開成完整實作:忠實度(用 keyword overlap 簡化版,CPU 友善)、相關性(用 cross-encoder proxy 或 ground truth nDCG@5)、引用正確性(用 regex 解析 [N] 編號)。我們沿用 Day 28 的 RAG 系統對 8 個查詢做端到端評估,展示了不同查詢類型在三個指標上的分佈差異。重點回顧:忠實度衡量「答案是否根據資料」、相關性衡量「檢索是否找回對的段落」、引用正確性衡量「編號是否真實指向資料」;三個指標各管一塊、互相獨立;LLM-as-judge 提供更高準確度但成本高、需要 ground truth 才能算有意義的指標。我們用「圓山大飯店的歷史」「木柵線的營運時間」等「資料稀疏」的查詢展示了「找不到資料時寧可說不知道」的重要性——這也是 Day 25 我們在 system prompt 中強調的「只能引用資料」的價值。明天我們會進入進階 RAG 主題:GraphRAG 與結構化知識。

結語

今天的重點是「把 RAG 系統的好壞變成可量化的指標」。我們從「為什麼需要評估」出發,介紹了三個核心指標——忠實度、相關性、引用正確性——各自的計算方式與簡化版實作,並用 8 個查詢做了端到端評估。讀完這篇你應該能回答:RAG 評估的三個核心指標各自衡量什麼?為什麼 keyword overlap 是忠實度的合理簡化版?為什麼引用正確性最便宜、忠實度最貴?「資料稀疏」的查詢為什麼會讓三個指標同時偏低?LLM-as-judge 的成本結構與控制策略?

評估是 RAG 系統上線前最後一塊拼圖。本篇的「無 LLM」評估是起點;正式上線前應該建構至少 50 個查詢的 ground truth 集、跑 LLM-as-judge 算完整指標、並把評估管線接入 CI/CD 確保每次更新不會退化評分。明天,我們會從「向量相似度檢索」轉向「結構化知識檢索」——GraphRAG 與實體關係抽取,這是企業知識庫問答的進階模式。

延伸資源

  • RAGAS 評估框架(2024):https://github.com/explodinggradients/ragas,開源的 RAG 評估框架,提供 faithfulness、answer relevance、context relevance 等指標的 LLM-as-judge 實作。
  • TruLens 評估框架(2023):https://www.trulens.org/,另一個 RAG 評估框架,支援自定義指標與 dashboard。
  • NLI 模型(mDeBERTa,2023):MoritzLaurer, Improving zero-shot generalization with NLI,MoritzLaurer/mDeBERTa-v3-base-xnli-multilingual-nli-2mil7 是多語言 NLI 模型,可用於忠實度評估。
  • Qdrant 1.12 官方文件(2025):https://qdrant.tech/documentation/,search 與 payload filter 的完整 API。
  • sentence-transformers 官方文件(2024):https://www.sbert.net/docs/usage/cross-encoder.html,CrossEncoder 與可用模型清單。

留言

這個網誌中的熱門文章

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 中,資料型別決定我們可以對變數進行哪些操作...

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 建構深度學習模型。 開發者與研究人員 :想更深入了...

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 等工具能處理和分析龐...