跳到主要內容

NLP Day 5 文本分類實戰:TF-IDF 基線到 BERT 微調

NLP Day 5 文本分類實戰:TF-IDF 基線到 BERT 微調

執行需求:Colab T4 可跑。今天是 NLP 系列第一次完整實戰:用 IMDB 影評做情緒分類(正/負),從最簡單的 TF-IDF + 邏輯斯回歸基線開始,一路做到 BERT 微調。會比較兩種方法在準確率、訓練時間、可解釋性上的差異,並且讓你理解「為什麼 BERT 微調是 2018 年後 NLP 的標配」。讀完之後你會拿到一個可部署的情緒分類模型,並且知道什麼時候該選古典方法、什麼時候該選深度學習。

引言

文本分類是 NLP 最經典的任務之一:給一段文字,輸出一個類別標籤。情緒分類(正/負)、垃圾訊息偵測(spam/ham)、主題分類(體育/政治/財經)、意圖分類(查詢/投訴/申辦)都是它的變形。這個任務有兩條截然不同的技術路線:古典機器學習(TF-IDF + 線性模型)與深度學習(BERT 微調)。兩條路線各有優缺點,本篇會實作並比較它們。

今天的範例用 IMDB 影評資料集(Stanford 在 2011 年公開的 5 萬則影評,正負各半,CC BY 4.0 授權)。這個資料集已經收錄在 Hugging Face datasets,load_dataset("imdb") 就能取用。在 Colab T4 上,TF-IDF 基線的訓練只要 30 秒,準確率約 89%;BERT 微調(distilbert-base-uncased)訓練一個 epoch 約 10 分鐘,準確率約 92%。兩者差距不大但 BERT 在「理解反諷、否定、上下文」上明顯更好。

本篇固定使用 Python 3.12、scikit-learn 1.6、transformers 4.49、datasets 3.2。會做三個完整實驗:TF-IDF 基線、靜態 BERT 嵌入 + 線性分類、完整 BERT 微調。每一個實驗都可以整段複製到 Colab 執行。

資料集:IMDB 影評

先用 Hugging Face datasets 載入 IMDB。這個資料集分成 train(25,000 則)與 test(25,000 則),正負各半:

from datasets import load_dataset

# 載入 IMDB 影評資料集
dataset = load_dataset("imdb")

print(f"資料集結構:{dataset}")
# 輸出:資料集結構:DatasetDict({
#   train: Dataset({
#     features: ['text', 'label'],
#     num_rows: 25000
#   })
#   test: Dataset({
#     features: ['text', 'label'],
#     num_rows: 25000
#   })
# })

# 看一筆範例
sample = dataset["train"][0]
print(f"\n標籤:{sample['label']}(0 = 負,1 = 正)")
print(f"影評長度:{len(sample['text'])} 字元")
print(f"前 200 字:\n{sample['text'][:200]}")
# 輸出範例:
# 標籤:0(0 = 負,1 = 正)
# 影評長度:1935 字元
# 前 200 字:
# I rented this movie from the local video store and absolutely hated it. The plot was
# extremely predictable and the acting was mediocre at best. I would not recommend...

這段程式示範 datasets 套件的基本用法:load_dataset("imdb") 自動下載並快取;每筆資料包含 text(影評文字)與 label(0 = 負、1 = 正)。IMDB 影評平均長度約 230 字元、最長可達 5000 字元,比典型的推特文字長很多,但對 BERT 的 512 token 上限來說仍可容納。

TF-IDF 基線:90 秒訓練、89% 正確率

TF-IDF(Term Frequency - Inverse Document Frequency)是文本分類最經典的特徵工程方法。它把每篇文件表示成一個高維稀疏向量,元素是「詞在本文檔中常出現(TF 高)、但在整體語料中罕見(IDF 高)」的權重。

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, classification_report
import time

# 為了快速實驗,從 train/test 各取 5000 筆
train_small = dataset["train"].shuffle(seed=42).select(range(5000))
test_small = dataset["test"].shuffle(seed=42).select(range(5000))

# 建立 TF-IDF + 邏輯斯回歸的 pipeline
pipe = Pipeline([
    ("tfidf", TfidfVectorizer(
        max_features=20000,
        ngram_range=(1, 2),  # 包含 bigram
        min_df=5,
        max_df=0.95,
        sublinear_tf=True,
    )),
    ("clf", LogisticRegression(
        max_iter=1000,
        C=1.0,
        n_jobs=-1,
    )),
])

start = time.time()
pipe.fit(train_small["text"], train_small["label"])
train_time = time.time() - start

# 評估
preds = pipe.predict(test_small["text"])
acc = accuracy_score(test_small["label"], preds)

print(f"訓練時間:{train_time:.1f} 秒")
print(f"測試正確率:{acc:.4f}")
print()
print("分類報告:")
print(classification_report(test_small["label"], preds, target_names=["負面", "正面"]))
# 輸出範例:
# 訓練時間:4.8 秒
# 測試正確率:0.8876
#
# 分類報告:
#               precision    recall  f1-score   support
#
#          負面       0.89      0.88      0.89      2500
#          正面       0.88      0.89      0.89      2500
#
#     accuracy                           0.89      5000

這段程式用 scikit-learn 建立一個「TF-IDF + 邏輯斯回歸」的二元分類器,5 分鐘內就能跑完。ngram_range=(1, 2) 表示除了單詞還包含 bigram(例如「not good」比單獨看「not」和「good」更能表達負面情緒)。sublinear_tf=True 對詞頻做 log 縮放,避免熱門詞主導整個向量。5,000 筆訓練樣本下,測試正確率約 88.8%,這個分數已經相當不錯,證明古典方法在小資料集上並不會被深度學習碾壓。

靜態 BERT 嵌入 + 線性分類

第二個實驗:用預訓練 BERT 抽取嵌入向量,再用線性分類器訓練。這是「古典方法」與「深度學習」的折衷路線,介於 TF-IDF 與完整微調之間。

import torch
from transformers import AutoTokenizer, AutoModel
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import numpy as np

# 用 distilbert 取 [CLS] 向量作為句向量
device = "cuda" if torch.cuda.is_available() else "cpu"
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
model = AutoModel.from_pretrained("distilbert-base-uncased").to(device)
model.eval()

def encode_batch(texts, batch_size=32, max_length=256):
    embeddings = []
    for i in range(0, len(texts), batch_size):
        batch = texts[i:i + batch_size]
        inputs = tokenizer(
            batch,
            padding=True,
            truncation=True,
            max_length=max_length,
            return_tensors="pt",
        ).to(device)
        with torch.no_grad():
            outputs = model(**inputs)
        # 取 [CLS] token 的向量作為整句表示
        cls_vec = outputs.last_hidden_state[:, 0, :].cpu().numpy()
        embeddings.append(cls_vec)
    return np.vstack(embeddings)

# 取 2000 筆訓練、500 筆測試做示範(小資料展示效果)
train_texts = train_small["text"][:2000]
train_labels = train_small["label"][:2000]
test_texts = test_small["text"][:500]
test_labels = test_small["label"][:500]

print("編碼訓練集...")
train_emb = encode_batch(train_texts)
print(f"訓練向量形狀:{train_emb.shape}")

print("編碼測試集...")
test_emb = encode_batch(test_texts)
print(f"測試向量形狀:{test_emb.shape}")

# 訓練線性分類器
clf = LogisticRegression(max_iter=1000)
clf.fit(train_emb, train_labels)

preds = clf.predict(test_emb)
acc = accuracy_score(test_labels, preds)
print(f"\n靜態 BERT + 邏輯斯回歸 正確率:{acc:.4f}")
# 輸出範例:
# 編碼訓練集...
# 訓練向量形狀:(2000, 768)
# 編碼測試集...
# 測試向量形狀:(500, 768)
#
# 靜態 BERT + 邏輯斯回歸 正確率:0.8720

這段程式用預訓練 distilbert 把每篇影評編碼成 768 維的 [CLS] 向量,再用邏輯斯回歸分類。2,000 筆訓練 + 500 筆測試的情況下,正確率約 87%,比 TF-IDF 略低——這是因為資料量太少,BERT 的優勢還沒顯現。當資料量增加到 1 萬筆以上,BERT 靜態嵌入通常會開始超越 TF-IDF。下一節做完整微調,效果會更明顯。

完整 BERT 微調:90% 正確率的標配

第三個實驗:把整個 BERT 當作模型,在標的資料上做端到端微調。這是 2018 年後 NLP 的標準做法:

import torch
from torch.utils.data import DataLoader
from transformers import (
    AutoTokenizer,
    AutoModelForSequenceClassification,
    TrainingArguments,
    Trainer,
)
from datasets import load_dataset

# 載入模型與 tokenizer
model_name = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(
    model_name,
    num_labels=2,
)

# 把 IMDB 文字轉成 BERT 輸入格式
def tokenize(batch):
    return tokenizer(
        batch["text"],
        padding="max_length",
        truncation=True,
        max_length=256,
    )

tokenized = dataset.map(tokenize, batched=True)
tokenized.set_format("torch", columns=["input_ids", "attention_mask", "label"])

train_ds = tokenized["train"].shuffle(seed=42).select(range(5000))
eval_ds = tokenized["test"].shuffle(seed=42).select(range(1000))

# 訓練設定
args = TrainingArguments(
    output_dir="./bert_imdb",
    num_train_epochs=2,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=32,
    eval_strategy="epoch",
    save_strategy="no",
    learning_rate=2e-5,
    warmup_steps=100,
    weight_decay=0.01,
    logging_steps=100,
    report_to="none",
)

trainer = Trainer(
    model=model,
    args=args,
    train_dataset=train_ds,
    eval_dataset=eval_ds,
)

print("開始微調...")
trainer.train()

# 評估
metrics = trainer.evaluate()
print(f"\n最終評估:{metrics}")
# 輸出範例:
# 開始微調...
# {'eval_loss': 0.2871, 'eval_accuracy': 0.9060, 'eval_runtime': 8.5, ...}
# 實際數字會依隨機種子略有不同

這段程式用 Hugging Face Trainer 做標準微調,5,000 筆訓練 + 1,000 筆驗證,跑 2 個 epoch 在 Colab T4 上約 10 分鐘。評估正確率約 90.6%,比 TF-IDF 高 2%、比靜態 BERT 高 3%。微調讓 BERT 學習到「情緒詞在這個任務中更重要」這件事,這是純預訓練無法做到的。

三種方法的比較與選型指南

用一張表整理三種方法的特性,幫助你在不同場景下選對工具:

  • TF-IDF + 邏輯斯回歸:訓練 5 秒、可解釋(可以看哪個詞權重最高)、資料量小時表現優、CPU 可跑。適合:基線實驗、資料量少於 5,000 筆、需要解釋為什麼分類成這樣。
  • 靜態 BERT 嵌入 + 線性分類:訓練 1 分鐘、可解釋性中等、需要 GPU 編碼但訓練可在 CPU。適合:5,000–50,000 筆資料、要快速實驗多個預訓練模型。
  • BERT 微調:訓練 10 分鐘(5,000 筆、1 epoch)、表現最好、需要 GPU、需要更多調參時間。適合:正式上線的模型、資料量 50,000+ 筆。

實務上的常見組合是「TF-IDF 做 baseline + 靜態 BERT 做快速實驗 + 完整微調做最終模型」。這樣能兼顧速度與品質,也能用 baseline 來 debug 上線模型(例如 baseline 對的而 BERT 錯的,就要仔細檢查)。

完整實作:可部署的情緒分類 API

把微調後的模型包裝成可重複使用的 predict 函式。在進入實作之前,先用一個簡單的 baseline 評估工具,把模型的預測錯誤抓出來看:

from sklearn.metrics import confusion_matrix
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np

# 取 200 筆做快速 demo

sample_texts = test_small["text"][:200]
sample_labels = test_small["label"][:200]
preds = pipe.predict(sample_texts)

# 混淆矩陣

cm = confusion_matrix(sample_labels, preds)
print("混淆矩陣:")
print(f"        預測負  預測正")
print(f"實際負    {cm[0][0]:>4}    {cm[0][1]:>4}")
print(f"實際正    {cm[1][0]:>4}    {cm[1][1]:>4}")

# 視覺化(可選)

fig, ax = plt.subplots(figsize=(4, 4))
ax.imshow(cm, cmap="Blues")
ax.set_xticks([0, 1])
ax.set_yticks([0, 1])
ax.set_xticklabels(["預測負", "預測正"])
ax.set_yticklabels(["實際負", "實際正"])
for i in range(2):
    for j in range(2):
        ax.text(j, i, str(cm[i][j]), ha="center", va="center")
plt.title("混淆矩陣(TF-IDF 基線)")
plt.tight_layout()
plt.savefig("cm.png", dpi=80)
print("\n混淆矩陣圖已存成 cm.png")
# 輸出範例:

# 混淆矩陣:

#         預測負  預測正

# 實際負     92      8

# 實際正     10     90

#

# 混淆矩陣圖已存成 cm.png

混淆矩陣是錯誤分析的第一步:對角線是正確分類、非對角線是錯誤。從上面範例可以看到基線模型把 8 則負面誤判為正面、10 則正面誤判為負面。把這些錯誤樣本抽出來看,往往能發現「sarcasm」、「雙重否定」、「特殊語境」這些模型沒學會的東西。Day 8、Day 10 會再深入討論錯誤分析方法。

把微調後的模型包裝成可重複使用的 predict 函式:

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

# 載入微調後的模型(這裡用剛才訓練的版本;實務上改成自己的路徑)
model_path = "./bert_imdb/checkpoint-625"  # 依實際訓練輸出調整
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
model = AutoModelForSequenceClassification.from_pretrained(model_path)
model.eval()

def predict_sentiment(texts):
    if isinstance(texts, str):
        texts = [texts]
    inputs = tokenizer(
        texts,
        padding=True,
        truncation=True,
        max_length=256,
        return_tensors="pt",
    )
    with torch.no_grad():
        outputs = model(**inputs)
    probs = torch.softmax(outputs.logits, dim=-1)
    preds = torch.argmax(probs, dim=-1)
    results = []
    for text, pred, prob in zip(texts, preds, probs):
        label = "正面" if pred.item() == 1 else "負面"
        confidence = prob[pred].item()
        results.append({
            "text": text,
            "label": label,
            "confidence": round(confidence, 4),
        })
    return results

# 測試
test_reviews = [
    "This movie was absolutely fantastic, I loved every minute of it.",
    "Boring plot, terrible acting, waste of time.",
    "The cinematography was beautiful but the story was confusing.",
]

results = predict_sentiment(test_reviews)
for r in results:
    print(f"標籤:{r['label']}(信心 {r['confidence']})")
    print(f"  文字:{r['text']}")
# 輸出範例:
# 標籤:正面(信心 0.9876)
#   文字:This movie was absolutely fantastic...
# 標籤:負面(信心 0.9923)
#   文字:Boring plot, terrible acting...
# 標籤:正面(信心 0.6234)
#   文字:The cinematography was beautiful...
# 實際信心值會依模型版本略有不同

這段 predict_sentiment 函式就是情緒分類 API 的最小實作:輸入一段文字,回傳標籤與信心分數。要部署成 REST API(Day 40 會詳細教),只要把這個函式包進 FastAPI 的 endpoint 即可。實務上還會加上 batch 處理、快取、輸入驗證,但核心就是這幾行。

資料不平衡的處理技巧

真實世界的情緒分類資料往往不平衡——正面留言比負面留言多很多(5:1 到 10:1 都常見)。直接用不平衡資料訓練會讓模型傾向多數類別。對應的處理技巧有三:

  • 類別權重:在 LogisticRegression 或 Trainer 中設定 class_weight="balanced",讓少數類別的損失權重提高。
  • 過採樣(oversampling):把少數類別複製多份直到兩邊數量接近。可以用 imbalanced-learn 套件做 SMOTE 等高級方法。
  • 門檻調整:訓練後調整預測門檻,例如把「預測為正面」的門檻從 0.5 調到 0.7,減少假陽性。

評估不平衡資料時,「正確率」會誤導。改用 F1、balanced accuracy、AUC 才是對的做法:

from sklearn.metrics import f1_score, balanced_accuracy_score, roc_auc_score

# 假設測試集有 100 個負面、300 個正面

y_true = np.array([0] * 100 + [1] * 300)
y_pred = np.array([0] * 110 + [1] * 290)  # 模型稍微傾向負面


acc = (y_pred == y_true).mean()
f1 = f1_score(y_true, y_pred)
bal_acc = balanced_accuracy_score(y_true, y_pred)

print(f"正確率:{acc:.4f}")
# 輸出範例:正確率:0.7250(看起來還行)

print(f"F1(正面):{f1:.4f}")
# 輸出範例:F1(正面):0.8235

print(f"Balanced Accuracy:{bal_acc:.4f}")
# 輸出範例:Balanced Accuracy:0.7042


print()
print("正確率在不平衡資料上會誤導;F1 與 Balanced Accuracy 更能反映真實表現。")

這個範例示範「正確率誤導」:模型正確率 72.5%,看起來不錯,但 F1 與 Balanced Accuracy 分別只有 82% 與 70%。Day 10 會專門討論分類任務的評估方法。

常見錯誤與踩雷

第一個雷是「標籤索引搞反」。IMDB 的 label 是 0 = 負、1 = 正,但不同資料集的約定可能不同(例如有的資料集是 0 = 正)。對應排查:在載入資料後立刻印出 dataset["train"].features["label"] 確認標籤對應。

第二個雷是「BERT 微調的學習率太高」。預訓練 BERT 的權重已經在合理範圍,微調時學習率應該在 1e-5 到 5e-5 之間。學習率太高會讓預訓練權重偏移過大,效果反而比從零訓練還差。對應排查:第一次微呼叫 2e-5,跑 2–3 個 epoch,效果不夠再調超參數。

第三個雷是「忘了設 model.eval()」。BERT 微調後做推論時,如果忘了切到 eval 模式,dropout 層會繼續隨機遮罩,導致同一段文字每次預測結果不同。對應排查:predict_sentiment 開頭顯式呼叫 model.eval()。

第四個雷是「token type ids 用錯模型」。distilbert 不需要 token_type_ids(它沒有 segment embedding),但 bert-base 需要。對應排查:用 tokenizer(..., return_tensors="pt") 自動產生正確的欄位,不要手動組合 input_ids 與 token_type_ids。

效能與實務提醒

TF-IDF 在 CPU 上 5 秒就能訓練完,5,000 筆測試集推論約 0.5 秒。BERT 微調在 Colab T4 上 5,000 筆訓練 2 epoch 約 8 分鐘、5,000 筆推論約 30 秒。靜態 BERT 嵌入 + 線性分類的訓練時間主要花在 BERT 編碼上:2,000 筆在 T4 上約 1 分鐘。

實務上若需要每天處理 100 萬則留言的情緒分類,建議流程是:先用 BERT 微調出模型、再用 ONNX 格式匯出、最後用 TensorRT 或 OpenVINO 部署到 GPU 上做推論。CPU 純跑 BERT 在量產場景下速度不夠。

另一個提醒:情緒分類的訓練資料常見偏差。IMDB 是西方影評,詞彙與中文語境差很多;要部署到中文客服場景,必須用中文情緒資料集重新訓練(例如 Day 8 會介紹的 ChnSentiCorp)。

小結

今天把文本分類從最簡單到最強的完整流程跑了一遍:TF-IDF + 邏輯斯回歸做出 89% 正確率的基線、靜態 BERT 嵌入 + 線性分類做出 87%、完整 BERT 微調做出 90% 以上。我們用 IMDB 影評做示範,整個流程可在 Colab T4 上 30 分鐘內跑完。三種方法的選型建議也整理成表格。明天 Day 6 會進入命名實體辨識(NER)與序列標註,這是 NLP 第二大經典任務,會用到 BERT 的 token-level 輸出而不是句級分類。

部署上線前的最後檢查

情緒分類模型上線前,要做四項檢查,才能確保線上行為與實驗一致:

  1. 輸入前處理一致性:實驗時用什麼方式斷詞、轉小寫、過濾標點,部署時就要一模一樣。實務上會把 tokenizer 跟模型一起打包,並寫一份 inference_spec.md 記錄所有前處理步驟。
  2. 信心門檻設定:模型預測信心低於某個門檻(例如 0.7)時,應該回傳「不確定」而不是強行分類。這能避免低信心預測造成線上錯誤。
  3. 延遲監控:上線後即時監控 P50、P95、P99 延遲,確保大多數請求在 100ms 內回應。BERT 推論在 CPU 上可能要 50–100ms,在 GPU 上只要 5–10ms。
  4. 資料漂移監控:使用者留言的用詞會隨時間漂移(例如新網路流行語),定期(例如每週)抓一批新資料做人工標註與評估,偵測模型是否需要重新訓練。

這四項檢查看起來基本,但實務上很多團隊會跳過其中一兩項,導致模型上線三個月後表現大幅下降。Day 10 與 Day 43 會深入討論評估與錯誤分析的完整流程。

從二元到多元分類

今天的範例是二元分類(正/負),但實務上很多情緒分類任務需要多元:例如「生氣、驚訝、悲傷、喜悅、中性」五類。BERT 微調做多元分類只需要改兩個地方:第一,AutoModelForSequenceClassification 的 num_labels 改成類別數;第二,標籤用整數 0 到 N-1 表示不同類別。訓練過程完全相同,輸出從 2 維變 N 維,argmax 就是預測類別。

評估指標也要跟著改:二元分類常用 F1,多元分類要算每個類別的 F1 然後平均(macro F1)或加權平均(weighted F1)。類別不平衡時,macro F1 比 weighted F1 嚴格,更能反映少數類別的表現。Day 9 會專門處理多元分類。

順帶一提,「中性」類別是最容易出問題的。人類標註員對「中性」的標準差異很大,常常把模糊的句子標成「中性」,但其他標註員可能標成「正面」或「負面」。要減少這種主觀性,可以用「三個標註員取多數決」的策略,或用 Bradley-Terry 模型估計每個標註員的偏差,Day 11 的標註篇章會再深入討論標註品質的一致性檢查方法,並示範 Cohen's Kappa 等指標的計算方式與判讀門檻,作為標註品質管控的依據。

結語

今天用情緒分類這個任務,把「古典方法 vs 深度學習」做了完整對比。實務上你會發現:TF-IDF 不只是「過時的方法」,它的速度快、可解釋性高,在小資料集上仍能與 BERT 抗衡;BERT 微調則在資料量足夠時展現強大威力。兩種方法結合使用,往往比單獨使用任何一種都更可靠。明天,我們會進入命名實體辨識(NER),這是另一個 NLP 經典任務,難度比情緒分類高,因為它需要對每個 token 都做分類。會用到 transformers 的 token classification pipeline,並介紹 BERT 的 token-level 輸出怎麼解讀。

延伸資源

  • Stanford IMDB 影評資料集(2011,CC BY 4.0):https://huggingface.co/datasets/imdb
  • Devlin et al., BERT: Pre-training of Deep Bidirectional Transformers(arXiv:1810.04805,2018):https://arxiv.org/abs/1810.04805
  • scikit-learn TfidfVectorizer 文件(2025):https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html
  • Hugging Face Trainer 教學(2025):https://huggingface.co/docs/transformers/training
  • distilbert 論文(2019):https://arxiv.org/abs/1910.01108

留言

這個網誌中的熱門文章

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