轉載請註明出處:https://leytton.blog.csdn.net/article/details/101349794
如果本文對您有所幫助,請點個贊讓我知道哦 😃
在本課程中,你將學習三種處理缺失值的方法。然後使用實際數據集比較這些方法的效果。
1、介紹
造成數據丟失的原因有很多。例如,
- 兩間臥室的房子不包括第三間臥室的價值。
- 調查對象可能選擇不分享其收入。
大多數機器學習庫(包括scikit-learn
)在試圖使用缺失值的數據構建模型時都會出現錯誤。因此,你需要選擇下面的策略之一。
2、三種方法
1) 一個簡單的選擇:刪除缺少值的列
最簡單的選擇是刪除缺少值的列。
除非刪除列中的大多數值都丟失了,否則使用這種方法將丟失許多潛在價值的信息。舉個極端的例子,假如有一個10,000行的數據集,其中一個重要的列缺少一條數據。這種方法將完全刪除該列!
2) 一個更好的選擇:填充
用一些數字填充缺失的值。例如,我們可以用平均值填充。
在大多數情況下,填充的值不一定正確,但它通常會比完全刪除該列數據要好。
3) 填充擴展
填充
是標準的方法,通常效果很好。然而,填充的值可能高於或低於實際值(數據集中沒有收集這些值)。或者缺少值的行在某些方面可能是唯一的。在這種情況下,你的模型將考慮哪些值是最初丟失的,從而做出更好的預測。
在這種方法中,我們像以前一樣輸入缺失的值。此外,新增一列用於記錄哪條數據是缺失填充的。
在某些情況下,這將非常有效。但某些情況,這沒有一點用。
3、案例
在本例中,我們將使用 Melbourne Housing 數據集。我們的模型將使用房間數量和土地面積等信息來預測房價。
我們不會關注數據加載步驟。相反,你可以想象你已經擁有了X_train
、X_valid
、y_train
和y_valid
中的訓練和驗證數據。
定義函數來評估每種方法的效果
我們定義了一個函數score_dataset()
來比較處理缺失值的不同方法。該函數計算隨機森林模型
的平均絕對誤差(MAE)
。
方法1的得分(刪除缺少值的列)
由於我們同時處理訓練集和驗證集,所以要注意在兩個數據框中刪除相同的列。
# 獲取缺少值的列名稱
cols_with_missing = [col for col in X_train.columns
if X_train[col].isnull().any()]
# 刪除訓練和驗證數據中的列
reduced_X_train = X_train.drop(cols_with_missing, axis=1)
reduced_X_valid = X_valid.drop(cols_with_missing, axis=1)
print("MAE from Approach 1 (Drop columns with missing values):")
print(score_dataset(reduced_X_train, reduced_X_valid, y_train, y_valid))
輸出結果:
MAE from Approach 1 (Drop columns with missing values):
183550.22137772635
方法2得分(填充)
接下來,我們使用SimpleImputer
用每一列的平均值填充缺失的值。
雖然它很簡單,但是填充平均值的方法通常很好用(不同數據集有所差異)。儘管統計學家已經嘗試了更復雜的方法來確定填充值(例如迴歸填充),但一旦將結果插入複雜的機器學習模型,這些複雜的策略通常不會帶來額外的好處。
from sklearn.impute import SimpleImputer
# 填充
my_imputer = SimpleImputer()
imputed_X_train = pd.DataFrame(my_imputer.fit_transform(X_train))
imputed_X_valid = pd.DataFrame(my_imputer.transform(X_valid))
# 填充移除了列名;補回來
imputed_X_train.columns = X_train.columns
imputed_X_valid.columns = X_valid.columns
print("MAE from Approach 2 (Imputation):")
print(score_dataset(imputed_X_train, imputed_X_valid, y_train, y_valid))
輸出結果:
MAE from Approach 2 (Imputation):
178166.46269899711
我們看到方法2的MAE
比方法1低,所以方法2在這個數據集中表現得更好。
方法3得分(填充擴展)
接下來,我們填充缺失的值,同時記錄哪些值是填充的。
# Make copy to avoid changing original data (when imputing)
X_train_plus = X_train.copy()
X_valid_plus = X_valid.copy()
# Make new columns indicating what will be imputed
for col in cols_with_missing:
X_train_plus[col + '_was_missing'] = X_train_plus[col].isnull()
X_valid_plus[col + '_was_missing'] = X_valid_plus[col].isnull()
# Imputation
my_imputer = SimpleImputer()
imputed_X_train_plus = pd.DataFrame(my_imputer.fit_transform(X_train_plus))
imputed_X_valid_plus = pd.DataFrame(my_imputer.transform(X_valid_plus))
# Imputation removed column names; put them back
imputed_X_train_plus.columns = X_train_plus.columns
imputed_X_valid_plus.columns = X_valid_plus.columns
print("MAE from Approach 3 (An Extension to Imputation):")
print(score_dataset(imputed_X_train_plus, imputed_X_valid_plus, y_train, y_valid))
輸出結果:
MAE from Approach 3 (An Extension to Imputation):
178927.503183954
正如我們所看到的,方法3的效果略差於方法2。
那麼,爲什麼填充比刪除列更好呢?
訓練數據有10864行和12列,其中3列包含丟失的數據。對於每一列,缺少的條目不到一半。因此,刪除列會刪除很多有用的信息,因此填充方法效果會更好。
# Shape of training data (num_rows, num_columns)
print(X_train.shape)
# Number of missing values in each column of training data
missing_val_count_by_column = (X_train.isnull().sum())
print(missing_val_count_by_column[missing_val_count_by_column > 0])
輸出結果:
(10864, 12)
Car 49
BuildingArea 5156
YearBuilt 4307
dtype: int64
4、結論
一般來說,比起簡單地刪除具有缺失值的列(在方法1中),填充缺失值(在方法2和方法3中)會得到更好的效果。
5、去吧,皮卡丘
在練習中比較處理缺失值的方法。
原文:
https://www.kaggle.com/alexisbcook/missing-values