資料前處理(Data Preprocessing)指的是收集完資料之後到真正進入模型之前的過程。若我們想要提升數據分析的準確度,資料前處理將會扮演非常重要的角色。
這個章節將著重於缺失值處理的部分,處理缺失值是至關重要的一步。缺失值可能會嚴重影響數據集的完整性和分析結果的準確性。如果缺失值處理不當,可能會導致錯誤的結論和模型性能的下降。通過識別和處理缺失值,我們可以確保數據集的質量,提高模型的可靠性和預測能力。
資料跟特徵決定模型的上限,模型跟算法只是逼近這個上限。
# 可使用目錄功能快速確認要閱覽的主題
缺失值( 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 之間。
假設你有以下數據:
╔═══════╦═══════╗
║ Index ║ Value ║
╠═══════╬═══════╣
║ 0 ║ 5 ║
║ 1 ║ 12 ║
║ 2 ║ 8 ║
║ 3 ║ NaN ║
║ 4 ║ 20 ║
╚═══════╩═══════╝
你想用線性插值法來填充第 3 行(index 3)缺失的值。
步驟
進行上述計算,得出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 算法在處理缺失值時,會利用數據集中與缺失值樣本最相似的 K 個樣本來進行填補。
KNN 算法會給定一個數據點,找到與其最接近的 K 個數據點,並使用這些鄰近數據點的信息來進行分類或回歸,實際應用在缺失值填補時,具體步驟如下:
整體流程:
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
進行填充。pd.DataFrame(imputer.fit_transform(data),columns=data.columns)
:將填充後的數據轉換為 pandas
的 DataFrame 格式,並保留原數據框的列名。以上述方法填充缺失值將得到以下結果:
優點
缺點