
好不容易學習完資料科學三大基礎套件(NumPy / Pandas / Matplotlib)之後,就可以開始學習什麼是資料前處理(Data Preprocessing)、為什麼要做?、以及怎麼做?
🔧什麼是資料前處理?
資料前處理是指:在將資料餵給機器學習模型之前,對資料進行清理、轉換、編碼、標準化等操作,讓資料更符合模型的需求。就像廚師烹飪前會先洗菜、切菜和備料,資料前處理就是模型訓練前的準備工作。
🎯 為什麼要做資料前處理?
資料科學中有一句經典台詞: Garbage in ! Garbage out! 意思就是你丟垃圾資料去訓練模型,訓練出來的就是垃圾模型,一點用都沒有!!!
資料前處理就是為了避免這種事情發生,因此他非常的重要!!!
🧠 常見資料處理任務

🛠️ 常見資料前處理方法

🧭 資料前處理是機器學習的關鍵!!!
✅ 好的資料前處理可以讓模型:
- 更快收斂
- 更穩定準確
- 更具泛化能力
- 減少偏誤與錯誤
🎯資料清理技巧與缺失值處理
1. 檢查缺失值
df.isnull() # 回傳 True/False 表示哪裡是 NaN
df.isnull().sum() # 每欄有幾個缺失值
說明
我們會盡量讓資料不要有缺值,因此會先查看資料目前缺值狀況,後續再決定如何處理(補值/刪除)。
2. 填補缺失值
df.fillna(0) # 用 0 填補
df.fillna(method='ffill') # 前一筆資料往下填
df.fillna(method='bfill') # 後一筆資料往上填
df['age'].fillna(df['age'].mean()) # 用平均數填補
說明
資料填補的方式有很多種,可以直接全補同一個數值、補鄰近值,或是使用統計量來填補。
💡實務上會依照這個專案的背景知識來評估資料需要補什麼值,以及有沒有需要補。
3. 刪除缺失值或重複值
df.dropna() # 刪除所有有缺失值的列
df.drop_duplicates() # 刪除重複列
df.dropna(subset=['age']) # 只刪掉 age 欄位是 NaN 的列
說明
缺失值除了補值之外,還可以刪除,但前提是缺失值佔整體資料比重不高才行。 重複值代表原始資料再拿到的時候有人為或意外的疏失導致某部分資料筆數重複了,這些也建議拿掉。
💡處理缺失值時要特別注意這些缺失的部分是否有意義的,例如未婚之人他的配偶欄就會是空白。
範例
import pandas as pd
data = {
'name': ['Anna', 'Ben', 'Cathy', 'David', 'Eva'],
'score': [87, None, 78, None, 92]
}
df = pd.DataFrame(data)
print(df.isna())
df = df.fillna(df['score'].mean())
print(df.isna())
# 輸出
name score
0 False False
1 False True
2 False False
3 False True
4 False False
name score
0 False False
1 False False
2 False False
3 False False
4 False False
說明
- 先檢查是否有缺失值
- 然後用平均數填補
- 再檢查時已經填補完成
📌資料轉換與標準化處理
- 資料轉換在處理資料時很常遇到,特別是以下兩個情境:
- 整數與浮點數互轉
- 字串與日期互轉
- 一致的資料格式才能確保在運算和輸出的時候不會出錯
1. 資料類型轉換
df['age'] = df['age'].astype(float) # 整數轉浮點
df['date'] = pd.to_datetime(df['date']) # 字串轉日期
說明
在Python中處理日期這種資料會有許多函數需要了解,有需要時可以查詢有關”datetime”套件的相關資訊。
2. 分箱(Binning)
bins = [0, 18, 30, 50, 100]
labels = ['青少年', '青年', '中年', '老年']
df['age_group'] = pd.cut(df['age'], bins=bins, labels=labels)
說明
自訂類別標籤將數值型資料離散化有助於圖表分析的解釋。 例如: 單純以數字來看年紀可能不覺得有什麼顯著意義,但若改成將年齡對應到不同標籤(青少年、青年等等),會使不同年齡區分的效果更好。
3. 類別型編碼(Label Encoding / One-Hot)
df['gender'].map({'Male': 0, 'Female': 1}) # 映射為數值
# One-hot 編碼
pd.get_dummies(df['city'])
說明
雖然收集資料時候有分為數值型和類別型資料,但最終要丟入模型訓練前都要轉換為數值資料,因此會需要對類別型資料做一些編碼的處理。
4. 標準化(Standardization)與正規化(Normalization)
# Normalization: 將數值壓縮到 0-1
df['score_norm'] = (df['score'] - df['score'].min()) / (df['score'].max() - df['score'].min())
# Standardization: 平均為0,標準差為1
df['score_std'] = (df['score'] - df['score'].mean()) / df['score'].std()
df['score'].std()
說明
標準化和正規化都是資料清理時非常重要的一步,對於提升後面模型訓練的環節有很大的幫助,在此先不討論。
範例
import pandas as pd
data = { 'age': [15, 22, 37, 58, 75],
'gender': ['Male', 'Female', 'Female', 'Male', 'Female'],
'score': [55, 88, 75, 60, 45]
}
df = pd.DataFrame(data)
print(df)
# 將 age 分成年齡層欄位(青少年、青年...)
bins = [0, 18, 30, 50, 100]labels = ['青少年', '青年', '中年', '老年']
df['age_group'] = pd.cut(df['age'], bins=bins, labels=labels)
print(df)
#將 gender 轉為 one-hot 編碼
df['gender'] = df['gender'].map({'Male': 0, 'Female': 1})
print(df)
# 對 score 欄位做 normalization 與 standardization
# Normalization: 將數值壓縮到 0-1
df['score_norm'] = (df['score'] - df['score'].min()) / (df['score'].max() - df['score'].min())
# Standardization: 平均為0,標準差為1
df['score_std'] = (df['score'] - df['score'].mean()) / df['score'].std()
print(df)
# 輸出
age gender score
0 15 Male 55
1 22 Female 88
2 37 Female 75
3 58 Male 60
4 75 Female 45
age gender score age_group
0 15 Male 55 青少年
1 22 Female 88 青年
2 37 Female 75 中年
3 58 Male 60 老年
4 75 Female 45 老年
age gender score age_group
0 15 0 55 青少年
1 22 1 88 青年
2 37 1 75 中年
3 58 0 60 老年
4 75 1 45 老年
age gender score age_group score_norm score_std
0 15 0 55 青少年 0.232558 -0.565391
1 22 1 88 青年 1.000000 1.378141
2 37 1 75 中年 0.697674 0.612507
3 58 0 60 老年 0.348837 -0.270917
4 75 1 45 老年 0.000000 -1.154340
圖示: 標準化前 vs 標準化後
import matplotlib.pyplot as plt
plt.hist(df['score'], alpha=0.5, label='Original')
plt.hist(df['score_std'], alpha=0.5, label='Standardized')
plt.legend()
plt.title("Before vs After")
plt.show()

說明
- 對資料進行標準化之前,資料是分布在45~88的區間
- 對資料進行標準化之後,資料轉而分布在0的兩側
💡這個動作看似沒什麼用處,但其實他在訓練模型時的幫助非常大!!!




















