Python機器學習筆記(六):數據集裏有遺漏值時要如何處理
在實務上,數據集內容遺漏不齊全,是常碰到的問題,若不預先做處理,就將資料丟進模型跑,演算法絕對會亂算一通,產生不可預期的結果。所以在進行進一步的分析工作之前,一個關鍵工作,即是將那些有遺漏值的地方處理掉。
假設我們已將要分析的資料轉換成 Python 的 DataFrame 物作,其名稱為 df。DataFrame 形式上與 Excel 工作表相似,每一列為一筆紀錄樣本,總列數 n_samples,即是 df 資料集的樣本數。每一欄,則是每筆樣本的特徵內容,假設 df 是個信用卡交易資料集,特徵欄位可能如卡號、持卡人性別、持卡人年齡、消費金額、消費類別等資訊,總欄數 n_features,即是每筆交易紀錄的特徵個數。以下就以 df 資料集說明如何處理數據遺漏問題。
一、識別數據表格中,各特徵欄位是否有遺漏值
我們可以叫用 DataFrame 物件的 isnull 方法,檢查數據表格中是否有遺漏值,然後再套用 sum 方法,它會回傳每個特徵欄裏有幾個遺漏值,假設「卡號」欄位回傳數為0,代表無遺漏值,每筆樣本都帶有卡號資訊,若「消費類別」欄位回傳數字為10,表示說有10筆樣本沒有消費類別資訊。語法如下:
df.isnull().sum()
會回傳大小為 n_features 的 Series 物件,index即為欄位名稱
二、刪除具有遺漏值的特徵或樣本
處理遺漏值最簡單的方法,是刪除帶有遺漏值的特徵(欄資料)或樣本(列資料)。雖然直接將整欄或整列資料刪除,是個方便簡潔的方法,但它的缺點也很明顯,例如,我們可能會刪除過多的樣本,讓我們導出的分析結果,變得不可靠。或是,當我們刪除整欄特徵資料時,我們事實上是冒著失去重要資訊的風險,例如因有遺漏值,我們將信用卡「消費類別」欄位刪除,但「消費類別」有可能是辨別是否為偽冒交易的重要影響因素。
要刪除有遺漏值的整欄或整列資料,可叫用 DataFrame 物件的 dropna 方法,利用參數 axis 為0或1,設定是要刪除列或欄資料。
1.刪除有遺漏值的特徵欄資料
語法為
df.dropna(axis=0)
下達此一指令後,只要特徵欄裏的儲存格有遺漏值,縱使該欄(比如說「性別」欄位)只有一個遺漏值,一律將整個特徵欄(整個「性別」欄)刪除。假如每個特徵欄都至少有一個遺漏值時,結果會將整個數據表格刪光光。
2.刪除有遺漏值的樣本列資料
樣本裏的某個特徵項目有遺漏值,該筆樣本即刪除丟棄不用。有以下幾種處理方式:
1)只要樣本裏有一項特徵項目有遺漏值,整筆樣本即刪除
語法為
df.dropna(axis=1)
當然,有可能會因而刪除掉一堆樣本,導致可供分析的樣本數不足,最後分析結果的可靠性不足。
2)只刪除過多遺漏項目的樣本
為避免刪除過多樣本,只有遺漏項目超過某個門檻時,才刪除該筆資料。假設 df 資料集有8個特徵欄位,若某個樣本,其有值的特徵項目未達5個以上,該筆樣本即刪除。其樣本刪除門檻設定語法為
df.dropna(thresh=5)
3)只刪除重要特徵欄位有遺漏值的樣本
譬如,我們認為「消費金額」是信用卡交易分析上最重要的特徵欄位,其他欄位有遺漏值沒關係,但只要「消費金額」沒有資料,該筆樣本就整個刪除。語法為
df.dropna(subset=[`消費金額`])
三、填補遺漏值
將包含遺漏值的整個樣本或是整個特徵欄位刪除,並不是好辦法,因如此一來,我們可能會失去大量有用的數據。此時我們可採用「插補技術」,使用其他樣本的值所導出的估計值來填補遺漏值。「平均插補」(mean imputation)是常見的「插補技術」,利用整個特徵欄的平均值來代替遺漏值,在 Python 中,可利用 scikit-learn 的 Imputed 類別操作遺漏值「插補技術」:
• 滙入 Imputer 類別
from sklearn.preprocessing import Imputer
•初始化 Imputer 估計器(estimator)物件 imr
imr = Imputer(strategy=‘mean’,axis=0)
# strategy 參數是用來設定採用何種「插補技術」
* mean:平均數
* median:中位數
* most_frequent:出現最頻繁的值
# axis 參數是設定計算方向
* 0:就特徵欄計算取值
* 1:就樣本列計算取值
•叫用 fit 方法,讓估計器 imr 按指定「插補技術」計算插補值
imr = imr.fit(df.values)
# 叫用df.values 可取出 df 資料集裏的數據
•叫用 transform 方法,將遺漏值替換為估計器所算出的插補值
imputed_data = imr.transform(df.values)
#此處回傳的imputed_data 是大小為(n_samples, n_features)的 array 物件,而非 DataFrame 物件。
限會員,要發表迴響,請先登入










