跳到主要內容

Day 22 資料探索實戰

Day 22 資料探索實戰

引言

學會 Pandas、Matplotlib、Seaborn 之後,最關鍵的問題是:「拿到一份陌生的資料,該從哪裡下手?」這就是探索性資料分析(Exploratory Data Analysis,簡稱 EDA)的價值。它不是為了得到最終結論,而是要快速摸清資料的形狀、找出異常、提出假設。EDA 做得好,後續的模型設計、特徵工程才不會走偏方向。

今天會以鐵達尼號乘客資料集為例,從頭到尾走一遍完整的 EDA 流程。我們會先看資料規模與欄位型態,再用統計量與視覺化找出缺失值、異常值與重要特徵,最後把觀察整理成幾個可驗證的假設。學會這套流程,未來不管遇到哪一份新資料,你都能在短時間內掌握它的面貌。這篇會把前三天學的技巧一次用上,是一個很好的綜合練習。

步驟一:載入資料與初步檢視

拿到資料的第一步,永遠是先看它的規模、欄位、型別與前幾筆資料。Pandas 提供一組非常方便的函式:shape、info()、head()、describe(),善用它們可以省下大量摸索時間。這些工具能在幾秒鐘內告訴你「資料有多寬、有多深、有沒有缺漏」。

import pandas as pd
import seaborn as sns

df = sns.load_dataset("titanic")
print("資料形狀:", df.shape)
print()
print(df.info())
print()
print(df.head())

輸出(部分):

資料形狀:(891, 15)

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 15 columns):
 #   Column       Non-Null Count  Dtype
---  ------       --------------  -----
 0   survived     891 non-null    int64
 1   pclass       891 non-null    int64
 2   sex          891 non-null    category
 3   age          714 non-null    float64
 4   sibsp        891 non-null    int64
 5   parch        891 non-null    int64
 6   fare         891 non-null    float64
 7   embarked     889 non-null    category
 8   class        891 non-null    category
 9   who          891 non-null    category
 10  adult_male   891 non-null    bool
 11  deck         203 non-null    category
 12  embark_town  889 non-null    category
 13  alive        891 non-null    category
 14  alone        891 non-null    bool
dtypes: bool(2), category(7), float64(2), int64(4)

   survived  pclass     sex   age  sibsp  parch     fare  ...  alone
0         0       3    male  22.0      1      0   7.2500  ...  False
1         1       1  female  38.0      1      0  71.2833  ...  False
2         1       3  female  26.0      0      0   7.9250  ...   True

從 info() 就能立刻看出幾件事:總共有 891 筆、15 個欄位;其中 age 只有 714 筆不為空,代表有 177 筆缺失;deck 缺失更嚴重(只有 203 筆);資料型別包含整數、浮點數、類別(category)與布林值。這些訊息就是後續清理的依據。當一份真實資料有上千個欄位時,這種「先看骨架」的習慣尤其重要,盲目跑分析很容易卡在欄位命名不一致、單位混雜的問題上。

步驟二:缺失值與重複值檢查

資料品質是分析的基礎。第二步要量化每個欄位的缺失比例,並檢查是否有完全重複的列。這個步驟看起來平凡,但往往能提早發現資料蒐集流程的問題,例如某個欄位缺失率高得離譜、某個維度的資料完全沒被記錄下來。

missing = df.isnull().sum()
missing = missing[missing > 0].sort_values(ascending=False)
print("缺失值統計:")
print(missing)

duplicates = df.duplicated().sum()
print(f"\n重複列數:{duplicates}")

輸出:

缺失值統計:
deck      688
age       177
embark_town    2
embarked       2
dtype: int64

重複列數:107

deck 缺失了近 77%,實務上這個欄位幾乎無法使用;age 缺 20%,可以考慮用中位數填補;embarked 與 embark_town 只缺 2 筆,可以直接刪掉那幾列。至於 107 筆完全重複的列,比較可能是資料整理時的雜訊,可以視需求決定是否移除。這個階段也適合順手檢查每個欄位的「合理範圍」,例如票價是不是有負數、年齡是不是有超過 200 歲的怪值。

步驟三:單變數分佈

接著要看每個欄位的分佈。類別型欄位用 value_counts(),數值型欄位則用直方圖。了解每個變數的「典型值」與「離群值」是分析的基礎,因為許多統計方法都假設資料有一定的分佈形態。

import matplotlib.pyplot as plt

print("艙等分佈:")
print(df["pclass"].value_counts())

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

sns.histplot(df["age"].dropna(), bins=30, kde=True, ax=axes[0])
axes[0].set_title("年齡分佈")

sns.histplot(df["fare"], bins=30, kde=True, ax=axes[1])
axes[1].set_title("票價分佈")
plt.show()

從輸出可以觀察到:

  1. 艙等(pclass):3 等艙最多(491 人),1 等艙最少(216 人)。
  2. 年齡(age):呈現右偏分佈,20–30 歲最多,少數 70 歲以上的長者屬於極端值。
  3. 票價(fare):分佈更為偏態,少數高票價把圖拉得很長,要考慮用對數尺度或只看 95 分位以下。

這些觀察會影響後續的視覺化策略,例如票價圖如果用對數軸會更清楚。當某個欄位的分佈極度偏態時,做統計檢定或建模時也應該考慮對數轉換,否則極端值會主導整個模型的行為。

步驟四:探索變數之間的關係

EDA 的重頭戲是找出變數之間的關係。對這份資料,最重要的問題是「哪些因素影響存活率?」我們可以從艙等、性別、年齡三個面向切入。雙變數分析是建立假設的關鍵階段,能告訴我們「接下來該深入看哪些欄位組合」。

fig, axes = plt.subplots(1, 3, figsize=(15, 4))

sns.barplot(data=df, x="pclass", y="survived", ax=axes[0])
axes[0].set_title("各艙等存活率")

sns.barplot(data=df, x="sex", y="survived", ax=axes[1])
axes[1].set_title("不同性別存活率")

sns.boxplot(data=df, x="survived", y="age", ax=axes[2])
axes[2].set_title("存活者與罹難者年齡分佈")
plt.show()

輸出會看到三個關鍵結論:

  1. 艙等越高,存活率越高:1 等艙存活率約 63%,3 等艙只有 24%。
  2. 女性存活率遠高於男性:女性約 74%,男性約 19%,差距非常懸殊。
  3. 年齡中位數差距不大:但孩童(年齡較低)的存活率略高於平均。

這三個變數顯然都是重要的預測特徵,之後在 Day 38 的模型設計章節,會被納入特徵工程。值得注意的是,僅僅看雙變數關係可能會被「辛普森悖論」誤導——某些效應在合併資料時消失,但分組後又出現。所以下一步要做交叉分析。

步驟五:交叉分析與相關性

單變數與雙變數分析之後,更深一層是用交叉表與相關矩陣,看變數彼此之間的關聯強度。交叉表能把兩個類別變數的組合展開,看每個交叉組合的目標值分佈;相關矩陣則把多個數值變數的線性關係量化。

ct = pd.crosstab(df["pclass"], df["sex"], values=df["survived"], aggfunc="mean")
print("各艙等 × 性別 的存活率:")
print(ct.round(3))

numeric = df[["survived", "pclass", "age", "fare"]]
corr = numeric.corr()

fig, ax = plt.subplots(figsize=(6, 5))
sns.heatmap(corr, annot=True, fmt=".2f", cmap="coolwarm",
            vmin=-1, vmax=1, ax=ax)
ax.set_title("相關矩陣")
plt.show()

輸出:

各艙等 × 性別 的存活率:
sex    female   male
pclass
1       0.968  0.340
2       0.921  0.146
3       0.500  0.135

交叉表顯示,1 等艙女性存活率高達 96.8%,3 等艙男性只剩 13.5%——艙等與性別的交互作用非常明顯。相關矩陣則進一步確認 pclass 與 fare 呈負相關(艙等數字越大、票價越低,這符合邏輯),survived 與 pclass 也呈負相關(艙等數字越大、存活率越低)。交叉分析的結論往往比雙變數分析更細緻,能避免「只看總體趨勢」的盲點。

步驟六:彙整觀察與下一步

完成上面的步驟,EDA 的探索階段就結束了。這時應該把觀察整理成幾個可驗證的假設,方便後續建模或進一步驗證。一份好的 EDA 筆記不只是一堆圖,而是要能讓團隊的人 30 秒內看懂「這份資料長什麼樣、有什麼該注意」。

  1. 假設 1:艙等是強預測因子——1 等艙存活率明顯高於 3 等艙。
  2. 假設 2:性別的影響大於艙等——同艙等下,女性存活率遠高於男性。
  3. 假設 3:年齡與存活的關係較弱,但仍值得納入模型。
  4. 假設 4:deck 缺失太多,不適合直接使用;可以考慮依艙等推估,或直接捨棄。

這些假設之後可以透過卡方檢定、邏輯斯迴歸等統計方法驗證。在 Day 38 設計模型時,這四個假設就會變成特徵工程的指引。EDA 不只是「看圖」,而是建立「可被驗證的假設」。當你能在 30 分鐘內把一份陌生資料整理成 5 條假設,就代表已經具備資料分析師的核心能力了。

結語

今天用鐵達尼號資料集走完了一次完整的 EDA。流程上分成六個步驟:初步檢視、缺失值處理、單變數分佈、雙變數關係、交叉分析、彙整觀察。這套流程可以套用到任何新資料集上,只要把欄位名稱換掉、視覺化依資料特性調整即可。明天開始,我們會暫時離開資料分析的內容,進入深度學習的數學基礎:線性代數。理解向量、矩陣與內積,才能真正看懂神經網路的運作方式。

明天,我們會暫時離開資料分析的內容,進入深度學習的數學基礎:線性代數。理解向量、矩陣與內積,才能真正看懂神經網路的運作方式。

留言

這個網誌中的熱門文章

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