
資料前處理(Data Preprocessing)指的是收集完資料之後到真正進入模型之前的過程。若我們想要提升數據分析的準確度,資料前處理將會扮演非常重要的角色。
這個章節將著重於缺失值處理的部分,處理缺失值是至關重要的一步。缺失值可能會嚴重影響數據集的完整性和分析結果的準確性。如果缺失值處理不當,可能會導致錯誤的結論和模型性能的下降。通過識別和處理缺失值,我們可以確保數據集的質量,提高模型的可靠性和預測能力。資料跟特徵決定模型的上限,模型跟算法只是逼近這個上限。# 可使用目錄功能快速確認要閱覽的主題
Pandas 缺失值處理基礎方法
缺失值( Missing Value ),是指在資料集中缺少一些值或是該值無法表示或測量的情況。常見的 Missing Value 表示方式包括 NaN 和 None。
import pandas as pd
import numpy as np
### 創健一個範例資料集 ###
data = pd.DataFrame({
'col1': [5, 12, 8, np.nan],
'col2': [16, 9, np.nan, 4],
'col3': [11, 3, 7, 20]
})
檢查缺失值
# 檢查缺失值,返回 True 表示為 Missing Value
data.isnull()
# 檢查非缺失值,返回 True 表示為非 Missing Value
data.notnull()
# 計算前10欄中每欄的缺失值數並列出
missing_values_count = nfl_data.isnull().sum()
missing_values_count[0:10]
# 計算缺失值佔整體資料的比例
total_cells = np.product(data.shape) # product 將計算元組中所有元素的乘積
total_missing = missing_values_count.sum()
percent_missing = (total_missing/total_cells) * 100
print(percent_missing)
刪除缺失值
# 刪除所有含有缺失值的觀測值(列)
data.dropna()
# 刪除所有含有缺失值的觀測值(欄)
data.dropna(axis=1)
# 刪除含有缺失值大於一定數量的觀測值(列)
data.dropna(thresh=2) # 因為第二筆資料的 np.nan 數量大於 thresh=2,則會被刪除
# 删除包含缺失值的整欄
data.dropna(axis=1, inplace=True)
※ 直「行」,也稱「欄」、「column」,axis = 1
※ 橫「列」,也稱「row」,axis = 0
※ 大陸與台灣的「行」跟「列」的講法相反,總之直的是「column」,橫的是「row」
基礎填充缺失值
# 將所有缺失值填充為 0
data.fillna(0)
# 將所有缺失值填充為 0,並且取代原始 dataframe 的資料
data.fillna(0, inplace=True)
# 將所有缺失值填充為平均值
data.fillna(data.mean(), inplace=True)
# 將所有缺失值填充為中位數
data.fillna(data.median(), inplace=True)
# 將所有缺失值填充為眾數(data.mode() 回傳結果是一個 df,要用 iloc 取得 series)
data.fillna(data.mode().iloc[0], inplace=True)
# 針對 col1 ,以 col1 裡面的眾數填補缺失值
data['col1'].fillna(data.mode()['col1'][0], inplace=True)
進階填充缺失值
鐵達尼號存活預測資料集為例
import pandas as pd
import numpy as np
df = pd.read_csv('https://raw.githubusercontent.com/dsindy/kaggle-titanic/master/data/train.csv')
# Age缺失值以性別區分,分別用該性別平均值填充
df['Age'].fillna(value=df.groupby('Sex')['Age'].transform('mean'),inplace=True)
插值法處理缺失值
插值法( Interpolation )是一種常見的填充 Missing Value 的方法,可以使用 Pandas 的 interpolate 方法實現。
import pandas as pd
import numpy as np
### 創健一個範例資料集 ###
data = pd.DataFrame({
'col1': [5, 12, 8, np.nan],
'col2': [16, 9, np.nan, 4],
'col3': [11, 3, 7, 20]
})
# 使用插值法填充缺失值
data.interpolate()
在不指定method
的情況下,默認方法為線性插值法
。
線性插值法
適合於數據點之間趨勢變化較為平緩的情況。
線性插值法基本概念
假設你有兩個已知數據點 (x0, y0) 與 (x1, y1),你想估算某個 x 對應的 y 值,這個 x 位於x0 和 x1 之間。
線性插值公式
- y 是我們要估算的值
- x 是插值點
- (x0, y0) 與 (x1, y1) 是已知數據點
線性插值應用範例
假設你有以下數據:
╔═══════╦═══════╗
║ Index ║ Value ║
╠═══════╬═══════╣
║ 0 ║ 5 ║
║ 1 ║ 12 ║
║ 2 ║ 8 ║
║ 3 ║ NaN ║
║ 4 ║ 20 ║
╚═══════╩═══════╝
你想用線性插值法來填充第 3 行(index 3)缺失的值。
步驟
- 確定相鄰的已知點:
- x0=2, y0=8
- x1=4, y1=20
- 計算插值:
- x=3(要填充的缺失值的位置)
- 使用線性插值公式計算 y:
進行上述計算,得出y=14,
因此,第 3 行(index 3)的缺失值將被填充為 14。
╔═══════╦═══════╗
║ Index ║ Value ║
╠═══════╬═══════╣
║ 0 ║ 5 ║
║ 1 ║ 12 ║
║ 2 ║ 8 ║
║ 3 ║ 14 ║
║ 4 ║ 20 ║
╚═══════╩═══════╝
線性插值法的優點和缺點
優點:
- 簡單易理解
- 計算效率高
- 適用於數據點之間變化趨勢較為平緩的情況
缺點:
- 當數據點之間變化不平滑或變化劇烈時,插值結果可能不準確
- 只能在已知數據點之間進行插值,無法外推數據
其它插值方法介紹與使用
機器學習算法處理缺失值
機器學習算法可以用於填充 Missing Value,例如 K-Nearest Neighbor(KNN)算法。KNN 算法可以根據與缺失值最接近的 k 個樣本的值來填充缺失值。
import pandas as pd
from sklearn.impute import KNNImputer
data = pd.DataFrame({
'col1': [5, 12, 8, np.nan],
'col2': [16, 9, np.nan, 4],
'col3': [11, 3, 7, 20]
})
# 使用 KNN 算法填充缺失值
imputer = KNNImputer(n_neighbors=2)
data_imputed = pd.DataFrame(imputer.fit_transform(data), columns=data.columns)
KNN 算法基本概念
KNN 算法的基本原理是基於相似性假設,即相似樣本具有相似的特徵或標籤。因此,KNN 算法在處理缺失值時,會利用數據集中與缺失值樣本最相似的 K 個樣本來進行填補。
KNN 算法會給定一個數據點,找到與其最接近的 K 個數據點,並使用這些鄰近數據點的信息來進行分類或回歸,實際應用在缺失值填補時,具體步驟如下:
- 標準化數據:由於不同特徵的取值範圍可能不同,標準化數據可以確保距離計算的合理性。
- 計算距離:對於包含缺失值的樣本,計算其與其他樣本的距離。只考慮非缺失值特徵。
- 選擇 K 個最近鄰居:根據計算出的距離,選擇 K 個與缺失樣本最接近的鄰居。
- 填補缺失值:對於數值型特徵,使用 K 個鄰居的平均值或中位數填補缺失值;對於類別型特徵,使用 K 個鄰居中最常見的類別填補缺失值。
基礎 KNN 應用範例
整體流程:
- 對於每一個缺失值樣本,找到最接近的 2 個樣本(即距離最近的鄰居)。
- 使用這些鄰居的值來填補缺失值,這樣使得填補後的數據保留了原數據的局部相似性。
- 將填補後的數據轉換為
pandas
DataFrame 格式,並保留原數據框的列名。
import pandas as pd
from sklearn.impute import KNNImputer
data = pd.DataFrame({
'col1': [5, 12, 8, np.nan],
'col2': [16, 9, np.nan, 4],
'col3': [11, 3, 7, 20]
})
# 使用 KNN 算法填充缺失值
imputer = KNNImputer(n_neighbors=2)
data_imputed = pd.DataFrame(imputer.fit_transform(data), columns=data.columns)
KNNImputer
是scikit-learn
中用於缺失值插補的類。n_neighbors=2
指定了 KNN 算法中使用的鄰居數量為 2。也就是說,對於每個缺失值,KNN 算法會找到與之最相似的 2 個鄰居,並使用這些鄰居的值來填補缺失值。
imputer.fit_transform(data)
:這個方法對數據data
進行填充。- fit_transform 是 scikit-learn 中的常用方法,它會先擬合(fit)模型然後轉換(transform)數據。對於 KNNImputer,這意味著它會計算所有非缺失值之間的距離,然後對每個缺失值進行填補。
pd.DataFrame(imputer.fit_transform(data),columns=data.columns)
:將填充後的數據轉換為pandas
的 DataFrame 格式,並保留原數據框的列名。- imputer.fit_transform(data) 返回的是一個 NumPy 的數組,我們將其轉換為 DataFrame 並設置列名為 data.columns 以保持與原數據框一致的結構。
以上述方法填充缺失值將得到以下結果:
KNN 算法的優點和缺點
優點
- 考慮了數據的局部相似性:
- KNN 算法利用相似的樣本來填補缺失值,因此能夠保留數據的局部模式和結構,這比簡單地使用平均值或中位數更能反映實際情況。
- 適用於多種數據類型:
- KNN 可以應用於連續數據和分類數據,適應性較強。
- 不需要對數據進行嚴格假設:
- KNN 算法是一種非參數方法,不需要對數據的分佈進行假設,這使得它在處理各種類型的數據時更加靈活。
- 有效利用數據中的信息:
- KNN 算法能充分利用數據中現有的樣本信息進行填補,從而可能提高模型的預測準確性。
缺點
- 計算量大:
- 對於大型數據集,KNN 的計算開銷會非常大,因為需要計算每個樣本與其他樣本之間的距離。這會導致填補缺失值的過程非常耗時。
- 受數據稀疏性的影響:
- 如果數據中缺失值較多,找到足夠的鄰居來填補缺失值會變得困難,這會影響填補的效果。
- 對異常值敏感:
- KNN 算法會受到異常值(outliers)的影響,因為異常值會影響鄰居的選擇,從而導致填補結果不準確。
- 需要選擇適當的 k 值:
- k 值(即鄰居數量)的選擇對填補結果有較大影響。如果 k 值過小,填補結果可能過於依賴單個鄰居;如果 k 值過大,填補結果可能過於平滑,無法反映數據的真實結構。
- 資料標準化的需求:
- 在使用 KNN 算法之前,通常需要對數據進行標準化(Normalization),以確保不同特徵之間的距離具有可比性。這增加了數據預處理的複雜性。