<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 4278字,需瀏覽 9分鐘

           ·

          2020-09-05 05:08

          ?不論是自己爬蟲獲取的還是從公開數(shù)據(jù)源上獲取的數(shù)據(jù)集,都不能保證數(shù)據(jù)集是完全準(zhǔn)確的,難免會有一些缺失值。而以這樣數(shù)據(jù)集為基礎(chǔ)進(jìn)行建?;蛘邤?shù)據(jù)分析時,缺失值會對結(jié)果產(chǎn)生一定的影響,所以提前處理缺失值是十分必要的。

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

          • 不處理

          • 刪除含有缺失值的樣本

          • 填充缺失值

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

          我自己構(gòu)建了一個簡易的含有缺失值的DataFrame,所有操作都基于這個數(shù)據(jù)集進(jìn)行。

          1、刪除缺失值

          刪除雖說是一個可行的方式,但肯定是不能隨便刪除的,比如一個樣本中僅有一個特征的值缺失,這樣的情況下填充取得的效果一定會優(yōu)于刪除,所以在刪除缺失值時,我們需要一個衡量的標(biāo)準(zhǔn)。

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

          首先需要確定的是刪除的標(biāo)準(zhǔn)是什么?比如一個特征的缺失值所占比例已經(jīng)超過了50%,如果選擇填充的話,就表明該特征超五成的值都是自己猜測填入的,導(dǎo)致誤差可能比刪除這個特征還要大。

          def?find_missing(data):
          ????#統(tǒng)計缺失值個數(shù)
          ????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

          在確定了這個標(biāo)準(zhǔn)之后,就可以利用一個自定義函數(shù),將我們期望實現(xiàn)的功能封裝至函數(shù)中。比如上面這個函數(shù),先確定每個特征的缺失值個數(shù)并降序排列,然后計算缺失值比例,最后利用布爾索引得到需要刪除的特征名。

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

          在數(shù)據(jù)集上應(yīng)用這個函數(shù),可以看到缺失值占比超50%的特征C被刪除了。

          這個衡量標(biāo)準(zhǔn)自己可以依據(jù)情況設(shè)定,然后刪除樣本的方式可以類比上述刪除特征的方式。

          2、pandas填充

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

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

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

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

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

          填充之后結(jié)果如下:

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

          3、sklearn填充

          第二種填充方式是利用sklearn中自帶的API進(jìn)行填充。

          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']
          '''

          首先利用布爾索引得到數(shù)據(jù)集含有缺失值的特征,后續(xù)操作只針對含有缺失值的特征。

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

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

          參數(shù)strategy共有四個選項可填:

          • 1、mean:平均數(shù)

          • 2、median:中位數(shù)

          • 3、most_frequent:眾數(shù)

          • 4、constant:如果參數(shù)指定這個,將會選擇另一個參數(shù)fill_value中的值作為填充值。

          SimpleImputer優(yōu)于fillna()之處在于前者可以一行語句指定填充值的形式,而利用fillna()需要多行重復(fù)語句才能實現(xiàn),或者需要提前計算某列的平均值、中位數(shù)或者眾數(shù)。

          4、利用算法填充

          我們都知道一般的算法建模是通過n個特征來預(yù)測標(biāo)簽變量,也就是說特征與標(biāo)簽標(biāo)量之間存在某種關(guān)系,那么通過標(biāo)簽變量與(n-1)個特征是否能預(yù)測出剩下的一個特征呢?答案肯定是可以的。

          實際上標(biāo)簽變量和特征之間可以相互轉(zhuǎn)化,所以利用這種方法就可以填補(bǔ)特征矩陣中含有缺失值的特征,尤其適用于一個特征缺失值很多,其余特征數(shù)據(jù)很完整,特別標(biāo)簽變量那一列的數(shù)據(jù)要完整。

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

          當(dāng)預(yù)測一個特征時,其余特征的缺失值都需要用0暫時填補(bǔ),每當(dāng)預(yù)測完一列特征,就用預(yù)測出的結(jié)果代替原數(shù)據(jù)集對應(yīng)的特征,然后預(yù)測下一特征,直至最后一個含有缺失值的特征,此時特征矩陣中應(yīng)該沒有需要利用0填補(bǔ)的缺失值了,表示數(shù)據(jù)集已經(jīng)完整。

          以隨機(jī)森林算法為例,實現(xiàn)上面表述填充缺失值的過程。

          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)
          '''

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

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

          這部分代碼主要的思想就是,先將需預(yù)測的一列特征暫定為標(biāo)簽,然后預(yù)測列中含有數(shù)據(jù)的一部分作為訓(xùn)練集,含有缺失值的一部分作為測試集,通過隨機(jī)森林在訓(xùn)練集上建模,利用模型在測試集的基礎(chǔ)上得到缺失值那部分的數(shù)據(jù),最后填充值原特征矩陣中。

          最后預(yù)測出的結(jié)果如下:

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

          說在最后

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



          瀏覽 25
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉啪啪网 | 下一篇日韩动态图 | 日欧操逼小电影 | 在线观看免费黄色 | 国产伦精品一区二区三区竹菊视频 |