3000字詳解四種常用的缺失值處理方法

2021-02-20 碼小辮

天天在用錢

不論是自己爬蟲獲取的還是從公開數據源上獲取的數據集,都不能保證數據集是完全準確的,難免會有一些缺失值。而以這樣數據集為基礎進行建模或者數據分析時,缺失值會對結果產生一定的影響,所以提前處理缺失值是十分必要的。

對於缺失值的處理大致可分為以下三方面:

不處理應該是效果最差的了,刪除雖然可以有效處理缺失值,但是會損傷數據集,好不容易統計的數據因為一個特徵的缺失說刪就刪實在說不過去。填充缺失值應該是最常用且有效的處理方式了,下面介紹四種處理缺失值的常用Tips。

我自己構建了一個簡易的含有缺失值的DataFrame,所有操作都基於這個數據集進行。

1、刪除缺失值

刪除雖說是一個可行的方式,但肯定是不能隨便刪除的,比如一個樣本中僅有一個特徵的值缺失,這樣的情況下填充取得的效果一定會優於刪除,所以在刪除缺失值時,我們需要一個衡量的標準。

刪除的方式無非有兩種,一是刪除缺失值所在行,也就是含有缺失值的樣本;二就是刪除缺失值所在列,也就是含有缺失值的特徵,下面以後者為例。

首先需要確定的是刪除的標準是什麼?比如一個特徵的缺失值所佔比例已經超過了50%,如果選擇填充的話,就表明該特徵超五成的值都是自己猜測填入的,導致誤差可能比刪除這個特徵還要大。

def find_missing(data):
    #統計缺失值個數
    missing_num = data.isna().sum(axis=0).sort_values(ascending=False)
    missing_prop = missing_num/float(len(data)) #計算缺失值比例
    drop_index = missing_prop[missing_prop>0.5].index.tolist() #過濾要刪除特徵名
    return drop_index

在確定了這個標準之後,就可以利用一個自定義函數,將我們期望實現的功能封裝至函數中。比如上面這個函數,先確定每個特徵的缺失值個數並降序排列,然後計算缺失值比例,最後利用布爾索引得到需要刪除的特徵名。

data2 = data.copy()
data2.drop(find_missing(data2),axis = 1)

在數據集上應用這個函數,可以看到缺失值佔比超50%的特徵C被刪除了。

這個衡量標準自己可以依據情況設定,然後刪除樣本的方式可以類比上述刪除特徵的方式。

2、pandas填充

pandas中的fillna()應該是最常用的一種填充缺失值方法,可以指定填充指定列或者整個數據集。

data['A'].fillna(value = data['A'].mean(),limit=1)

比如上面這句代碼,就是只填充特徵A一列,填充的選擇可以利用平均數、中位數、眾數等等,limit是限制要填充的個數,如果有兩個缺失值,但是參數limit=1的話,按順序填充第一個。

value參數也允許傳入字典格式,鍵為要填充的特徵名,值為要填充的缺失值。

values = {'A':4,'B':3,'C':4}
data.fillna(value=values)

填充之後結果如下:

fillna()方法固然簡單,但前提是含有缺失值的特徵比較少,如果很多的話,代碼就會很冗雜,客觀性也比較差。

3、sklearn填充

第二種填充方式是利用sklearn中自帶的API進行填充。

from sklearn.impute import SimpleImputer
data1 = data.copy()
#得到含有缺失值的特徵
miss_index = data1.isna().any()[data1.isna().any().values == True].index.tolist()
print(miss_index)
'''
['A', 'B', 'C']
'''

首先利用布爾索引得到數據集含有缺失值的特徵,後續操作只針對含有缺失值的特徵。

miss_list = []
for i in miss_index:
    #將一維數組轉化為二維
    miss_list.append(data1[i].values.reshape(-1,1))
for i in range(len(miss_list)):
    #利用眾數進行填充
    imp_most = SimpleImputer(strategy='most_frequent')
    imp_most = imp_most.fit_transform(miss_list[i])
    data1.loc[:,miss_index[i]] = imp_most

最需要注意的一點是SimpleImputer傳入的參數至少要是二維,如果將直接索引出的一列特徵傳入的話,是會發生報錯的,所以必須利用reshape()將一維轉化為二維。之後的操作就是先實例化、然後訓練模型,最後用填充後的數據覆蓋之前的數據。

參數strategy共有四個選項可填:

SimpleImputer優於fillna()之處在於前者可以一行語句指定填充值的形式,而利用fillna()需要多行重複語句才能實現,或者需要提前計算某列的平均值、中位數或者眾數。

4、利用算法填充

我們都知道一般的算法建模是通過n個特徵來預測標籤變量,也就是說特徵與標籤標量之間存在某種關係,那麼通過標籤變量與(n-1)個特徵是否能預測出剩下的一個特徵呢?答案肯定是可以的。

實際上標籤變量和特徵之間可以相互轉化,所以利用這種方法就可以填補特徵矩陣中含有缺失值的特徵,尤其適用於一個特徵缺失值很多,其餘特徵數據很完整,特別標籤變量那一列的數據要完整。

但是往往一個特徵矩陣中很多特徵都含有缺失值,對於這種情況,可以從特徵缺失值最少的一個開始,因為缺失值越少的特徵需要的信息也就越少。

當預測一個特徵時,其餘特徵的缺失值都需要用0暫時填補,每當預測完一列特徵,就用預測出的結果代替原數據集對應的特徵,然後預測下一特徵,直至最後一個含有缺失值的特徵,此時特徵矩陣中應該沒有需要利用0填補的缺失值了,表示數據集已經完整。

以隨機森林算法為例,實現上面表述填充缺失值的過程。

data3 = data.copy()
#獲取含有缺失值的特徵
miss_index = data3.isna().any()[data3.isna().any().values == True].index.tolist()
#按照缺失值多少,由小至大排序,並返回索引
sort_miss_index = np.argsort(data3[miss_index].isna().sum(axis = 0)).values
sort_miss_index
'''
array([1, 0, 2], dtype=int64)
'''

第一步就是通過布爾索引得到含有缺失值的特徵,並且根據缺失值的多少進行由小到大排序,這裡選擇利用argsort,因為返回的排序是特徵在特徵矩陣中的索引。

for i in sort_miss_index:
    data3_list =  data3.columns.tolist() #特徵名
    data3_copy = data3.copy() 
    fillc = data3_copy.iloc[:,i] #需要填充缺失值的一列  
    # 從特徵矩陣中刪除這列,因為要根據已有信息預測這列
    df = data3_copy.drop(data3_list[i],axis = 1) 
    #將已有信息的缺失值暫用0填補
    df_0 = SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0).fit_transform(df)
    
    Ytrain = fillc[fillc.notnull()]#訓練集標籤為填充列含有數據的一部分
    Ytest = fillc[fillc.isnull()]#測試集標籤為填充列含有缺失值的一部分
    
    Xtrain = df_0[Ytrain.index,:]#通過索引獲取Xtrain和Xtest
    Xtest = df_0[Ytest.index,:]
    
    rfc = RandomForestRegressor(n_estimators = 100)#實例化
    rfc = rfc.fit(Xtrain,Ytrain)  # 導入訓練集進行訓練
    Ypredict = rfc.predict(Xtest) # 將Xtest傳入predict方法中,得到預測結果
    #獲取原填充列中缺失值的索引
    the_index = data3[data3.iloc[:,i].isnull()==True].index.tolist()
    data3.iloc[the_index,i] = Ypredict# 將預測好的特徵填充至原始特徵矩陣中

這部分代碼主要的思想就是,先將需預測的一列特徵暫定為標籤,然後預測列中含有數據的一部分作為訓練集,含有缺失值的一部分作為測試集,通過隨機森林在訓練集上建模,利用模型在測試集的基礎上得到缺失值那部分的數據,最後填充值原特徵矩陣中。

最後預測出的結果如下:

可以看到原特徵矩陣中缺失值的一部分被填充好了,這種利用算法填充缺失值的方法應該是精度最高的,因為缺失值是在原有數據的基礎上預測出的,而不是隨意猜測的,但缺點就是沒有前幾種便利,當特徵或缺失值較多時會比較耗時。

說在最後

缺失值處理是特徵工程至關重要的一步,而特徵工程和數據本身往往決定著一個模型的上限,所以數據集中的缺失值在一個項目中值得我們花些時間去處理,而不是用自己的幸運數字隨意填充,一句話總結就是"你不要你覺得,而是模型覺得"。

   小貼士

隱藏菜單:返回上一級 回復 「 1024 "關鍵詞,即可獲取內部學習資料

相關焦點

  • 離群值與缺失值的識別與處理
    拉依達準則:如果數據整體服從正太分布,一般在均數加減三個標準差之外的值被稱為離群值。Q檢驗法:當數據整體不服從正太分布的時候,用Q檢驗。當數據量大於10的時候,Q檢驗Q>0.33,則該可疑離群值捨去,否則保留。多變量離群值的識別與處理馬氏距離(Mahalanobis distance)法是判別多變量離群值的一個常用方法。
  • Kaggle知識點:缺失值處理
    寫在前面在進行數據競賽中,數據預處理階段經常需要對數據進行缺失值處理。關於缺失值的處理並沒有想像中的那麼簡單。以下為一些經驗分享,基本涵蓋了大部分處理方式。這樣做的好處是,D的係數可以被解釋成「在控制了其他變量的情況下,X具缺失數據的個體其Y的預測值減去具X平均數的個體於Y的預測值」缺失值插補相對丟棄而言,補全是更加常用的缺失值處理方式。通過一定的方法將缺失的數據補上,從而形成完整的數據記錄,對於後續的數據處理、分析和建模至關重要。常用的補全方法如下。
  • 機器學習之缺失值處理
    缺失值數據圖片比較小,其實這段時間的數據缺失值還是較多的(我是特意找了段缺失值多的數據,方便我們後面對比不同處理方法的結果,嘿嘿~~~),這裡面我們以temp_out欄位為例來進行下面的缺失值處理啦缺失時段曲線圖為了對比缺失值效果,填充後的曲線統一下移一定距離哈~~~1:前值替換缺失值df_show = df_show.fillna
  • Python數據清洗(二):缺失值識別與處理
    不管是變量角度的缺失值判斷,還是數據行角度的缺失值判斷,一旦發現缺失值,都需要對其作相應的處理,否則一定程度上都會影響數據分析或挖掘的準確性。缺失值的處理辦法通常對於缺失值的處理,最常用的方法無外乎刪除法、替換法和插補法。
  • R語言如何檢測和處理數據缺失值?
    面對一份數據,我們會做數據的缺失值檢測和分析,根據數據的缺失程度,以知道數據的完整性和可用性。實際的數據,絕大部分會有缺失值現象。缺失值的產生與諸多因素有關聯,例如:數據採集不成功,數據採集成功了但是數據確實沒有值,數據的值受其它因素控制等。面對有缺失值的數據,我們要怎麼處理、分析和應用,是我們數據工作者要思考和實踐的命題。
  • 樣本缺失值處理,你真的操作對了嗎?
    我在數據清理與探索性分析中遇到的最常見問題之一就是處理缺失數據。首先我們需要明白的是,沒有任何方法能夠完美解決這個問題。不同問題有不同的數據插補方法——時間序列分析,機器學習,回歸模型等等,很難提供通用解決方案。在這篇文章中,我將試著總結最常用的方法,並尋找一個結構化的解決方法。在討論數據插補方法之前,我們必須了解數據丟失的原因。
  • 數據的預處理基礎:如何處理缺失值
    圖片來源: thermofisher數據集缺少值? 讓我們學習如何處理:數據清理/探索性數據分析階段的主要問題之一是處理缺失值。 缺失值表示未在觀察值中作為變量存儲的數據值。 這個問題在幾乎所有研究中都是常見的,並且可能對可從數據得出的結論產生重大影響。
  • 「統計實戰」缺失值識別與處理
    關注我的,分析數據不發愁了不信你試試後臺留言,獲取統計軟體在科學研究中,缺失值通常難以避免,但處理起來又比較麻煩,很多人選擇忽略缺失值,但有些時候它們會不知不覺給我們造成麻煩,學幾招缺失值識別和處理的技術還是很有必要的。
  • 統計分析零單系列第五期:缺失值處理(專題)
    4 數據缺失的處理處理缺失值無非兩種方法,刪除和插補數據。何時刪除何時插補數據?並非所有的插補數據都能帶來好的結果。我們首先看下所有的可能情況,最後進行總結。刪除法刪除行。 PS:不同的缺失值處理方法依託不同的統計軟體,筆者能力與精力有限,未列出其他各種處理方法。想深入挖掘的朋友,可以參考下圖。這裡提到的缺失模式在《管理學季刊》刊出的文章中有提及(但並不詳細)。
  • 機器學習基礎:缺失值的處理技巧
    在數據分析和建模中,經常會遇到變量值缺失的情況,這是非常常見的。為了保證數據指標的完整性以及可利用性,通常我們會採取特殊的方式對其進行處理。 2、缺失處理 方式1:刪除 直接去除含有缺失值的記錄,這種處理方式是簡單粗暴的,適用於數據量較大(記錄較多)且缺失比較較小的情形,去掉後對總體影響不大。一般不建議這樣做,因為很可能會造成數據丟失、數據偏移。
  • 數據分析|R-缺失值處理
    數據中往往會有各種缺失值,異常值,錯誤值等,今天先介紹一下如何處理缺失值,才能更好的數據分析,更準確高效的建模。一 查看數據集的缺失情況    R中使用NA代表缺失值,用is.na識別缺失值,返回值為TRUE或FALSE。由於邏輯值TRUE和FALSE分別等價於數值1和0,可用sum()和mean()來獲取數據集的缺失情況。
  • 缺失值插補方法程序和數據release, 總結加註解
    , 步驟和方法供參考這篇文章異常值和缺失值處理環節和步驟, 讓數據具有總體代表性告訴咱們什麼時候使用如下即將引薦的缺失值填補方法。缺失值處理的最終目的是讓樣本儘可能代表總體,這樣才能夠讓審稿人放心你的樣本不存在偏差,從而讓推斷出來的結果不具有generalization特徵。在看下面的內容之前,還是先總結一下基本的概念:在對缺失數據進行處理前,了解數據缺失的機制和形式是十分必要的。
  • 獨家 | 在機器學習中利用統計插補來處理缺失值(附代碼)
    數據有可能會含有缺失值,而這可能會導致多種機器學習算法出現問題。同樣地,在你對自己的預測任務進行建模之前,對數據每一列進行缺失值識別和替換是非常恰當的做法。這一步驟被稱為數據缺失值插補處理,或者簡稱插補。一種常見的數據缺失值插補方式是計算每一列的統計值(例如均值),並用這個值來替換該列所有的缺失值。
  • 手把手教你用pandas處理缺失值
    pandas對象的所有描述性統計信息默認情況下是排除缺失值的。pandas對象中表現缺失值的方式並不完美,但是它對大部分用戶來說是有用的。對於數值型數據,pandas使用浮點值NaN(Not a Number來表示缺失值)。
  • 機器學習基礎:缺失值的處理技巧(附Python代碼)
    在數據分析和建模中,經常會遇到變量值缺失的情況,這是非常常見的。為了保證數據指標的完整性以及可利用性,通常我們會採取特殊的方式對其進行處理。
  • 3000字!5大SQL數據清洗方法!
    前兩天在Towards Data Science上看到一篇文章,講的是用Pandas做數據清洗,作者將常用的清洗邏輯封裝成了一個個的清洗函數。02 重複值、缺失值處理場景:比如某網站今天來了1000個人訪問,但一個人一天中可以訪問多次,那資料庫中會記錄用戶訪問的多條記錄,而這時候如果想要找到今天訪問這個網站的1000個人的ID並根據此做用戶調研,需要去掉重複值給業務方去回訪。
  • 數據分析之Pandas缺失數據處理
    基礎概念首先,對缺失值分類和缺失值處理方法進行講解。【注意】:Panda讀取的數值型數據,缺失數據顯示「NaN」(not a number)。數據值的處理方法主要就是兩種方法:【注意】缺失值的插補只能用於客觀數據。由於主觀數據受人的影響,其所涉及的真實值不能保證。簡單刪除法是對缺失值進行處理的最原始方法。它將存在缺失值的個案刪除。
  • 多重插補法處理缺失數據(缺失值)
    同時,我們還將以最新發表、或各學科Top期刊文章中的統計方法為例,給大家逐一講解如何做統計(分析數據)!介 紹做科學研究的時候,我們經常會碰到缺失值的問題,除了直接刪除、簡單插補,多重插補也是常用到的處理缺失數據的方法。
  • 【圖文詳解】電線接頭常用連接方法及絕緣處理
    二、常用連接方法需連接的導線種類和連接形式不同,其連接的方法也不同。常用的連接方法有絞合連接、緊壓連接、焊接等。連接前應小心地剝除導線連接部位的絕緣層,注意不可損傷其芯線。絞合連接是指將需連接導線的芯線直接緊密絞合在一起。銅導線常用絞合連接。(1)單股銅導線的直接連接。
  • Pandas None值處理的 3 種方法
    只要和數據打交道,就不可能不面對一個令人頭疼的問題-數據集中存在空值。