目錄
引言
數據中的缺失值是一個非常棘手的問題,那麼數據缺失究竟帶來了多少問題?假設有100個樣本和20個特徵,這些數據都是機器收集回來的,若機器上的某個傳感器損壞導致一個特徵無效時該怎麼辦?此時是否扔掉整個數據集?這種情況下,另外19個特徵怎麼辦?它們是否還可用?答案是肯定的。因爲有時數據相當昂貴,扔掉和重新獲取都是不可取的,所以必須採用一些方法來解決這個問題。
一、可選處理方法
下面給出了一些可選的做法:
(1)使用可用特徵的均值來填補缺失值;
(2)使用特徵值來填補缺失值,如-1;
(3)忽略有缺失值的樣本;
(4)使用相似樣本的均值填補缺少值;
(5)使用另外的機器學習算法預測缺失值。
二、Python中Pandas庫處理缺失值
1.查看數據缺失值得分佈情況
【注】:缺失情況如上
1.1. 統計每列數據缺失值的分佈情況
import pandas as pd
data = pd.read_csv("./data.csv")
#統計每列數據缺失值的分佈情況
print(data.isnull().sum())
#統計每行數據缺失值的分佈情況
#通過指定參數axis=1來實現對每行數據的缺失值進行統計,默認是axis=0表示列。
print(data.isnull().sum(axis=1))
2.刪除包含缺失值的數據
處理缺失值最簡單的方法就是,將包含缺失值數據的列或者行從數據中刪除,但這樣會造成數據的浪費。
【注】:缺失情況如上
2.1. 刪除包含缺失值的行或列
data = pd.read_csv("./data.csv")
#刪除包含缺失值的行
print(data.dropna())
#刪除包含缺失值的列
print(data.dropna(axis=1))
【注】:在使用dropna方法的時候,我們可以通過設置inplace=True直接修改data的值,默認是是Flase 。
#保留缺失值的記錄
data.dropna()
print(data) #左圖
#刪除缺失值的記錄
data.dropna(inplace=True)
print(data) #右圖
2.2. 根據條件刪除包含缺失值的數據
除了直接刪除包含缺失值的數據之外,我們還可以通過dropna提供的一些參數來根據條件對缺失值進行刪除。
#刪除全爲空值的行
data = pd.read_csv("./data.csv")
print(data.dropna(how="all")) #圖1
#刪除行的缺失值個數大於指定閾值的行
#刪除缺失值個數大於2的行
print(data.dropna(thresh=2)) #圖2
#刪除指定列包含缺失值的行
print(data.dropna(subset=["C"])) #刪除C列包含缺失值的行 圖3
三、Python中Sklearn庫處理缺失值
from sklearn.preprocessing import Imputer
data = pd.read_csv("./data.csv") #原始數據如上圖
#填補缺失值
my_inputer=Imputer()
data_with_imputed_values=my_imputer.fit_transform(data)
print(data_with_imputed_values) #填補後結果如下圖
四、缺失值處理案例(一)----疝氣病數據集預處理
1.處理缺失值,以便使用分類算法
對數據集進行預處理,使其可以順利地使用分類算法。在預處理階段需要做兩件事:
(1)所有的缺失值必須用一個實數值來替換,因爲我們使用的Numpy數據類型不允許包含缺失值,這裏選擇實數0來替換所有缺失值,恰好能適用於Logistic迴歸。另外,由於Sigmoid(0)=0.5,即它對結果的預測不具有任何的傾向性,因此上述做法不會對誤差項造成任何影響。基於上述原因,將缺失值用0代替既可以保留現有數據,也不需要對優化算法進行修改。迴歸係數的更新公式如下:
weights=weights+alpha*error*dataMatrix[randIndex]
如果dataMatrix的某特徵對應值爲0,那麼該特徵的係數將不做更新,即:
weights=weights
如果在測試數據集中發現一條數據的類別標籤已經缺失,那麼我們的簡單做法是將該條數據丟棄。這是因爲類別標籤與特徵不同,很難確定採用某個合適的值來替換。
原始的數據經過預處理之後保存成兩個文件:horseColicTest.txt和horseColicTraining.txt。
參考文獻
1.【Machine Learning in Action --5】邏輯迴歸(LogisticRegression)從疝氣病預測病馬的死亡率
2. 數據的預處理之缺失值處理