跳到主要內容

DE Day 14 資料品質檢查:規則設計與自動化

DE Day 14 資料品質檢查:規則設計與自動化

執行需求:CPU 可跑。本篇接續 Day 13 清洗後的 clean.bike_rental 資料表(DuckDB),用 Pandera 1.x 設計與執行資料品質規則,並把檢查結果寫成報表與品質度量(DuckDB)。規則涵蓋「欄位存在性」、「型別正確性」、「值域合理性」、「唯一性」、「業務邏輯」五大類。整段範例在普通筆電數秒內可跑完。

引言

昨天的內容中,我們把一萬筆含有缺失值、型別錯誤、字串格式不一致的腳踏車租借資料清洗乾淨,寫進 DuckDB 的 clean.bike_rental 表。今天要往前推一步:怎麼知道這份「乾淨」的資料真的合理?這就是資料品質檢查(Data Quality)的工作。資料清洗與品質檢查看似接近,但分工其實很明確:清洗是把「髒」變「乾淨」(例如把「免費」轉成 0)、品質檢查是用「規則」驗證「資料是否符合預期」(例如「費用應該在 0 到 100 之間」、「還車時間應該晚於租借時間」)。兩者結合才能保證下游分析與模型的輸入是「乾淨且合理」。

這一篇會用 Pandera 1.x 設計一套品質規則、對昨天的 clean.bike_rental 跑一次完整檢查、把結果寫成品質報表與 DuckDB 的品質度量表,並把整個流程包成 pytest 可呼叫的函式。讀完這篇你會了解:品質規則的五大類(欄位存在、型別、值域、唯一性、業務邏輯)、Pandera 的 DataFrameSchema 與 Check API、檢查失敗時的處理策略(hard fail vs soft warn)、如何把品質報表視覺化、以及如何把品質檢查整合進管線(Day 22 的失敗處理)。

資料品質的五大類規則

實務上資料品質規則可以分成五大類。第一類是欄位存在性:每個預期的欄位都必須存在、欄位順序可以記錄在 schema 裡。這類規則最簡單但最常被忽略:當上游系統升級、新增了一個欄位時,若 schema 沒更新,下游的程式碼可能會安靜地失敗(pandas 對「欄位不存在」會回傳 KeyError)。第二類是型別正確性:每個欄位的型別必須與預期一致(rental_id 是字串、fee 是整數、start_time 是時間)。這類規則通常透過 schema 自動推論,Pandera 與 Pydantic 是最常見的工具。

第三類是值域合理性:欄位的值必須落在合理範圍內。例如 fee 必須在 0 到 200 之間、distance_km 必須在 0 到 50 之間、passenger_count 必須在 1 到 5 之間。這類規則用統計上的合理範圍或業務上的限制定義,能抓到「型別正確但數值不合理」的資料(例如「費用 = 999999」這種明顯的離群值)。第四類是唯一性:某些欄位必須唯一(例如 rental_id 是主鍵,不應該有重複)。這類規則通常透過 is_unique 檢查。

第五類也是最難設計的一類是業務邏輯:跨欄位的邏輯必須滿足。例如「end_time 必須晚於 start_time」、「fee = 0 的租借通常是會員租借」、「週末的租借量應該比平日高」。這類規則無法用單一欄位表達,需要寫成「跨欄位的 Python 表達式」,Pandera 支援 Check.custom() 介面。實務上這類規則通常占品質問題的 60% 以上,卻最容易被忽略。

用 Pandera 設計品質規則

Pandera 是 Python 社群最成熟的資料品質檢查框架,2025 年的 1.x 世代已經穩定。它的核心概念是「Schema 描述 DataFrame 的形狀與規則」,把規則寫成 Python 程式碼後,可以用同一個 Schema 對 pandas DataFrame、Polars DataFrame、DuckDB 查詢結果做檢查。這種「一份 schema 多種後端」的設計對資料工程特別友善:我們可以寫好品質規則、在 pandas 中除錯、然後直接拿到 Polars/DuckDB 上跑,不必為每個工具重寫規則。另一個常見的替代方案是 Great Expectations(1.x 世代),它提供更完整的 Expectation Suite 管理與文件化介面,但學習曲線比 Pandera 陡;對「個人或小團隊、需要快速建立品質規則」的場景,Pandera 通常是首選;對「大型組織、需要 Expectation Suite 治理與審核流程」的場景,Great Expectations 比較合適。

# 安裝:uv pip install pandera==1.0.0 polars==1.33.0 duckdb==1.4.1
import pandera.polars as pa
from pandera import Check, Field

# 設計 bike_rental 的品質 schema
bike_schema = pa.DataFrameSchema(
    columns={
        "rental_id": pa.Column(
            str,
            checks=[
                Check.str_matches(r"^R\d{5}$"),     # 格式:R 開頭 + 5 位數字
                Check.is_unique(),                  # 唯一
            ],
            nullable=False,
        ),
        "station_name": pa.Column(
            str,
            checks=[
                Check.isin(["台北車站", "西門站", "101站", "市政府站",
                           "國父紀念館站", "忠孝復興站"]),  # 必須在已知站點清單內
            ],
            nullable=True,                         # 允許缺失
        ),
        "start_time": pa.Column("datetime64[ns]"),
        "end_time": pa.Column("datetime64[ns]"),
        "fee": pa.Column(
            int,
            checks=[
                Check.in_range(0, 200),            # 費用在 0 到 200
            ],
        ),
        "member_id": pa.Column(str, nullable=True),
        "distance_km": pa.Column(
            float,
            checks=[
                Check.in_range(0.0, 50.0),         # 距離在 0 到 50 公里
            ],
            nullable=True,
        ),
    },
    checks=[
        Check.custom(
            lambda df: df["end_time"] > df["start_time"],
            name="end_time_after_start_time",
            error="還車時間必須晚於租借時間",
        ),
    ],
)
print(bike_schema)
# 輸出:<Schema ...>

這段定義了 bike_rental 的完整品質 schema,包含七個欄位的型別與檢查規則、與一個跨欄位的業務邏輯檢查。Check.str_matches(r"^R\d{5}$") 用正則表達式驗證格式、Check.is_unique() 驗證唯一性、Check.in_range(0, 200) 驗證值域、Check.isin([...]) 驗證是否在白名單內。Check.custom(lambda df: ...) 是跨欄位的業務邏輯:end_time 必須晚於 start_time,這個條件無法用單一欄位表達,必須用 lambda。

nullable=False 表示該欄位不允許缺失;nullable=True 表示允許。"datetime64[ns]" 是 pandas 的 datetime 型別字串,Pandera 會用它做型別檢查。如果你用的是 Polars DataFrame,型別字串要改成 Polars 的型別系統(例如 pl.Datetime)。Pandera 同時支援 pandas 與 Polars,import 方式不同(pandera.pandas 或 pandera.polars)。

完整實作:對清洗後的資料跑品質檢查

以下範例延續 Day 13 的 clean.bike_rental 資料表。我們用 DuckDB 讀取、用 Polars 轉換、做品質檢查、把結果寫成報表與 DuckDB 的品質度量表。執行前需要:uv pip install pandera==1.0.0。

第一步:把 DuckDB 的清洗結果讀出來,轉成 Polars DataFrame 給 Pandera 檢查。

import duckdb
import polars as pl

con = duckdb.connect("warehouse/de-journey.duckdb")
df = con.execute("SELECT * FROM clean.bike_rental").pl()
print(f"讀取筆數:{df.shape[0]:,}")
print(df.head(3))
# 輸出:
# 讀取筆數:1,000
# shape: (3, 7)
# ┌───────────┬─────────────┬─────────────────────┬─────────────────────┬─────┬────────────┬──────────────┐
# │ rental_id ┆ station_name ┆ start_time          ┆ end_time            ┆ fee ┆ member_id  ┆ distance_km  │
# ╞═══════════╪═════════════╪═════════════════════╪═════════════════════╪═════╪════════════╪══════════════╡
# │ R00000    ┆ 台北車站     ┆ 2024-01-01 00:00:00 ┆ 2024-01-01 00:30:00 ┆ 10  ┆ M000000    ┆ 5.32         │
# │ R00001    ┆ 西門站       ┆ 2024-01-01 00:00:00 ┆ 2024-01-01 00:30:00 ┆ 20  ┆ M000001    ┆ 2.18         │
# │ R00002    ┆ 101站       ┆ 2024-01-01 00:00:00 ┆ 2024-01-01 00:30:00 ┆ 30  ┆ M000001    ┆ 8.45         │
# └───────────┴─────────────┴─────────────────────┴─────────────────────┴─────┴────────────┴──────────────┘

這段用 con.execute("...").pl() 從 DuckDB 讀出 Polars DataFrame,零拷貝轉換(Day 12 學過)。

第二步:用 Pandera 的 schema 對 DataFrame 做品質檢查。

import pandera.polars as pa
from pandera.errors import SchemaError, SchemaErrors

# 為了 Polars 用,把前面定義的 schema 重新指定 dtype
import pandera.polars as papl
bike_schema_pl = papl.DataFrameSchema(
    columns={
        "rental_id": papl.Column(str, checks=[papl.Check.str_matches(r"^R\d{5}$"), papl.Check.is_unique()], nullable=False),
        "station_name": papl.Column(str, checks=[papl.Check.isin(["台北車站","西門站","101站","市政府站","國父紀念館站","忠孝復興站"])], nullable=True),
        "start_time": papl.Column(papl.DateTime),
        "end_time":   papl.Column(papl.DateTime),
        "fee":        papl.Column(int, checks=[papl.Check.in_range(0, 200)]),
        "member_id":  papl.Column(str, nullable=True),
        "distance_km":papl.Column(float, checks=[papl.Check.in_range(0.0, 50.0)], nullable=True),
    },
    checks=[
        papl.Check.custom(
            lambda d: d["end_time"] > d["start_time"],
            name="end_after_start",
        ),
    ],
)

try:
    validated = bike_schema_pl.validate(df, lazy=True)
    print("全部規則通過!")
except SchemaErrors as e:
    print(f"品質檢查失敗,錯誤如下:")
    for err in e.schema_errors:
        print(f"  - {err}")
# 輸出(依實際資料而略有不同):
# 品質檢查失敗,錯誤如下:
#  - end_after_start:3 筆資料的 end_time 不晚於 start_time

這段用 Pandera Polars 後端跑品質檢查。lazy=True 讓 Pandera 收集所有錯誤後一次拋出,而不是遇到第一個錯誤就停,這對「想知道所有問題」很重要。SchemaErrors 例外包含所有錯誤的清單,schema_errors 屬性是個別錯誤的迭代器。

注意我們在這個範例故意生成了一些「邏輯錯誤」的資料(例如 end_time 早於 start_time),所以檢查會失敗。實務上這正是我們想要的:「品質檢查必須會抓到髒資料,否則它就沒用」。第一次建立品質規則時,建議先用「已知有問題」的歷史資料跑一次,確認所有規則都會被觸發;再用「已知乾淨」的資料跑一次,確認不會誤報。

第三步:把品質檢查結果寫成報表,並存入 DuckDB 的品質度量表。

from datetime import datetime
import json

# 收集品質檢查的結果
report = {
    "table_name": "clean.bike_rental",
    "check_time": datetime.now().isoformat(timespec="seconds"),
    "row_count": int(df.shape[0]),
    "column_count": int(df.shape[1]),
    "rules_total": 8,
    "rules_passed": 0,
    "rules_failed": 0,
    "failures": [],
}

try:
    bike_schema_pl.validate(df, lazy=True)
    report["rules_passed"] = report["rules_total"]
except SchemaErrors as e:
    report["rules_passed"] = report["rules_total"] - len(e.schema_errors)
    report["rules_failed"] = len(e.schema_errors)
    for err in e.schema_errors:
        report["failures"].append({
            "check": err.check,
            "column": err.column,
            "n_failures": err.failure_cases.shape[0] if err.failure_cases is not None else 0,
        })

# 把報表寫進 DuckDB(quality schema)
con.execute("CREATE SCHEMA IF NOT EXISTS quality")
con.execute("CREATE TABLE IF NOT EXISTS quality.daily_report (report_json JSON, check_time TIMESTAMP)")
con.execute("INSERT INTO quality.daily_report VALUES (?, ?)", [json.dumps(report, ensure_ascii=False), datetime.now()])
print(f"已寫入品質報表;規則通過 {report['rules_passed']}/{report['rules_total']}")
# 輸出(依實際資料而略有不同):
# 已寫入品質報表;規則通過 7/8

這段把品質檢查的結果收集成一個 dict、再寫成 JSON 存入 DuckDB 的 quality.daily_report 表。json.dumps(report, ensure_ascii=False) 確保中文不被轉成 \uXXXX。SchemaErrors 例外的 schema_errors 屬性包含每個失敗的規則,failure_cases 是 Polars DataFrame,包含失敗的具體資料列。實務上 failure_cases 通常會被另外存到 quality.failures 表,方便後續人工 review。

品質報表的呈現與長期追蹤

品質報表不只要寫進資料庫,還要能被長期追蹤。最簡單的做法是把每天的「通過規則數 / 總規則數」畫成折線圖,看到「品質分數」的長期趨勢:

# 從 DuckDB 讀取歷史品質報表,計算品質分數
history = con.execute("""
    SELECT
        check_time::DATE AS day,
        json_extract_string(report_json, '$.rules_passed')::INT AS passed,
        json_extract_string(report_json, '$.rules_total')::INT AS total
    FROM quality.daily_report
    ORDER BY day
""").pl()
history = history.with_columns(
    quality_score=(pl.col("passed") / pl.col("total") * 100).round(2)
)
print(history.tail(5))
# 輸出(依實際執行次數而定):
# shape: (5, 4)
# ┌────────────┬────────┬───────┬────────────────┐
# │ day        ┆ passed ┆ total ┆ quality_score  │
# ╞════════════╪════════╪═══════╪════════════════╡
# │ 2025-11-25 ┆ 7      ┆ 8     ┆ 87.50          │
# │ 2025-11-26 ┆ 8      ┆ 8     ┆ 100.00         │
# │ 2025-11-27 ┆ 7      ┆ 8     ┆ 87.50          │
# │ 2025-11-28 ┆ 8      ┆ 8     ┆ 100.00         │
# │ 2025-11-29 ┆ 7      ┆ 8     ┆ 87.50          │
# └────────────┴────────┴───────┴────────────────┘

這段示範「從 DuckDB 讀歷史品質報表、計算品質分數、準備畫圖」。DuckDB 的 json_extract_string() 可以直接從 JSON 欄位中取出巢狀欄位,不用在 Python 端解析。history.tail(5) 顯示最近 5 天的趨勢。實務上可以把這段結果丟給 matplotlib 或 Streamlit 畫成折線圖,Day 34 會展開。

另一個關鍵指標是「首次失敗到修復的時間(Mean Time To Recovery, MTTR)」。當品質檢查失敗時,營運團隊應該收到警報並開始修復;修復完成後、檢查重新通過時,記錄「失敗到通過」的時間差。這個指標反映「對資料問題的回應速度」,是資料工程團隊的重要 KPI。我們會把 MTTR 的計算寫成 SQL 函式,每天自動更新。

把品質檢查整合進管線

品質檢查的最終目的是「防止壞資料進入下游」。實務上有兩種整合策略:hard fail(檢查失敗就停止管線、通知工程師)與 soft warn(檢查失敗只記錄、不停止管線)。前者適合「絕對不能有錯」的關鍵資料(例如交易明細)、後者適合「可接受少量錯誤」的分析資料(例如統計儀表板)。

# 把品質檢查包成函式,可被管線呼叫
def quality_check(df: pl.DataFrame, schema, table_name: str) -> bool:
    """對 DataFrame 跑品質檢查,回傳是否通過。失敗時把報表寫進 DuckDB。"""
    try:
        schema.validate(df, lazy=True)
        return True
    except SchemaErrors as e:
        report = {
            "table_name": table_name,
            "check_time": datetime.now().isoformat(timespec="seconds"),
            "row_count": int(df.shape[0]),
            "rules_total": 8,
            "rules_failed": len(e.schema_errors),
            "failures": [
                {"check": err.check, "column": err.column}
                for err in e.schema_errors
            ],
        }
        con.execute(
            "INSERT INTO quality.daily_report VALUES (?, ?)",
            [json.dumps(report, ensure_ascii=False), datetime.now()],
        )
        return False

# 在管線中呼叫
passed = quality_check(df, bike_schema_pl, "clean.bike_rental")
if not passed:
    raise SystemExit("品質檢查失敗,停止管線;詳細資訊請見 quality.daily_report")
print("品質檢查通過,繼續管線下游步驟")
# 輸出(依實際資料而定):
# 品質檢查失敗,停止管線;詳細資訊請見 quality.daily_report

這段把品質檢查包成 quality_check() 函式,回傳布林值表示是否通過。當失敗時,把報表寫進 DuckDB 並回傳 False;管線可以根據回傳值決定是否停止(raise SystemExit)或繼續(忽略 False)。這個函式設計是 Day 22「失敗處理」的基礎:當品質檢查失敗時,系統應該發送通知(LINE、Slack、Email)並等待人工介入。

常見錯誤與踩雷

錯誤一:把所有規則都設成 hard fail。當品質檢查的規則太多、太嚴格時,每天都會觸發一堆失敗警報,讓營運團隊疲於奔命。對應排查方向:把規則分成「critical」(hard fail,例如「金額不能是負數」)與「warning」(soft warn,例如「週末租借量偏低」)。critical 規則失敗時停止管線、warning 規則失敗時只記錄。

錯誤二:用同一個 schema 檢查所有資料表。不同資料表的欄位與業務邏輯不同,把規則混在一起會導致「某資料表沒有這個欄位、整個檢查都失敗」。對應排查方向:每個資料表寫一個獨立的 schema,不要為了「DRY」而強行共用。

錯誤三:把品質規則寫死在 Python 程式碼裡。當業務邏輯變動(例如「會員租借費改成 0 元」)時,需要修改 Python 程式碼並重新部署管線。對應排查方向:把規則寫在 YAML 檔、用 Pandera 的 from_yaml() 介面載入,這樣業務分析師可以直接修改 YAML 而不需要碰 Python。

錯誤四:忘記處理 SchemaErrors 的部分失敗。lazy=True 會收集所有錯誤、但 SchemaErrors 例外的 schema_errors 與 failure_cases 是兩個不同的結構,容易混用。對應排查方向:先 print e.schema_errors 的結構、確定它包含「錯誤的規則名」與「失敗的資料列」兩個資訊,再寫對應的處理程式碼。

錯誤五:品質檢查只看「通過 / 失敗」、不看「失敗的程度」。當「通過 7/8 規則」與「通過 0/8 規則」都是 False 時,營運團隊需要知道嚴重程度才能決定優先順序。對應排查方向:在報表裡加 failure_rate(失敗筆數 / 總筆數)欄位,讓嚴重程度可以一眼看出來。

效能與實務提醒

Pandera 的檢查在「規則數 < 20 條、資料列數 < 1000 萬」的場景下通常不到 1 秒。對更大的資料集,Pandera 提供 validate() 的 lazy=True 與 chunk_size 兩個參數,可以把檢查分批執行、減少記憶體使用。實務上若品質檢查跑得太慢,第一個排查方向是「用 DuckDB 預先過濾明顯錯誤」(例如先跑 WHERE fee < 0 把確定錯誤的資料挑出來、剩下的再用 Pandera 細部檢查)。這個「兩段式品質檢查」的做法能省下 50% 以上的檢查時間,因為「明顯錯誤」的資料通常佔少數、把它們先挑出來可以讓 Pandera 專注在「可疑的、需要細部判斷」的資料上。

另一個實務提醒是「品質規則要隨業務演進」。當業務新增欄位、修改規則時,品質 schema 也要同步更新。建議把品質 schema 放進 pipeline/quality/ 目錄、與 ETL 程式碼一起版控,每次業務規則變動時都更新 schema 並在 PR 中標明影響範圍。

在 Day 32 的「品質檢查與監控」會進一步把品質報表接到 Streamlit 儀表板;在 Day 38 的「監控與資料合約」會把品質規則升級為正式的「資料合約(Data Contract)」,由上游系統負責保證資料品質。今天先把基礎打好:規則怎麼寫、檢查怎麼跑、報表怎麼存、警報怎麼發、報表怎麼追蹤。當每個環節都被實作並驗證過,端到端品質管線才有可靠的基礎。

小結

今天把資料品質檢查的基礎打好了。我們用 Pandera 1.x 設計了一套包含「欄位存在、型別、值域、唯一性、業務邏輯」五大類的品質規則,對 Day 13 的 clean.bike_rental 跑了一次完整檢查,把結果寫成 JSON 報表存進 DuckDB 的 quality.daily_report 表,並把整個流程包成 quality_check() 函式供管線呼叫。Pandera 的 SchemaErrors 例外能一次收集所有錯誤,lazy=True 參數讓檢查更有效率。實務上「品質檢查」是「資料清洗」的延伸:清洗讓資料「乾淨」、品質檢查讓資料「合理」,兩者結合才能保證下游分析的可靠性。

結語

今天的重點是「品質規則的設計與自動化」。我們從五大類規則開始、用 Pandera 設計 Schema、跑品質檢查、寫報表、整合進管線。讀完這篇你應該能回答:品質規則可以分成哪五大類?Pandera 的 Schema 怎麼寫?檢查失敗時怎麼處理?如何把品質報表長期追蹤?這些問題的答案都藏在本篇的程式碼與文字裡。

明天,我們會進入爬蟲基礎:requests 與 HTML 解析。今天學到的「字串清洗」與「品質檢查」會直接應用到爬下來的 HTML:先清洗字串(去除 HTML tag、統一編碼),再用品質規則驗證「爬下來的資料是否符合預期」。

延伸資源

  • Pandera 官方文件(1.x,2025):https://pandera.readthedocs.io/,包含 Polars、pandas、Dask 三種後端的 Schema 設計。
  • Great Expectations 官方文件(1.x,2025):https://docs.greatexpectations.io/,另一個資料品質檢查框架,適合需要「Expectation Suite」管理的場景。
  • DuckDB JSON 函式(1.4,2025):https://duckdb.org/docs/sql/functions/json,本篇 json_extract_string() 的官方說明。
  • 行政院主計總處「政府資料開放授權條款第 1 版」:https://data.gov.tw/license,本系列使用的真實公開資料皆依此授權。

留言

這個網誌中的熱門文章

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