1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

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

        共 4429字,需瀏覽 9分鐘

         ·

        2020-09-12 12:09

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

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

        • 不處理

        • 刪除含有缺失值的樣本

        • 填充缺失值

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

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

        1、刪除缺失值

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

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

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

        def?find_missing(data):
        ????#統(tǒng)計(jì)缺失值個(gè)數(shù)
        ????missing_num?=?data.isna().sum(axis=0).sort_values(ascending=False)
        ????missing_prop?=?missing_num/float(len(data))?#計(jì)算缺失值比例
        ????drop_index?=?missing_prop[missing_prop>0.5].index.tolist()?#過濾要?jiǎng)h除特征名
        ????return?drop_index

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

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

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

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

        2、pandas填充

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

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

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

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

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

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

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

        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

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

        參數(shù)strategy共有四個(gè)選項(xiàng)可填:

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

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

        • 3、most_frequent:眾數(shù)

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

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

        4、利用算法填充

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

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

        但是往往一個(gè)特征矩陣中很多特征都含有缺失值,對于這種情況,可以從特征缺失值最少的一個(gè)開始,因?yàn)槿笔е翟缴俚奶卣餍枰男畔⒁簿驮缴佟?/span>

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

        以隨機(jī)森林算法為例,實(shí)現(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,因?yàn)榉祷氐呐判蚴翘卣髟谔卣骶仃囍械乃饕?/span>

        for?i?in?sort_miss_index:
        ????data3_list?=??data3.columns.tolist()?#特征名
        ????data3_copy?=?data3.copy()?
        ????fillc?=?data3_copy.iloc[:,i]?#需要填充缺失值的一列??
        ????#?從特征矩陣中刪除這列,因?yàn)橐鶕?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)#實(shí)例化
        ????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)該是精度最高的,因?yàn)槿笔е凳窃谠袛?shù)據(jù)的基礎(chǔ)上預(yù)測出的,而不是隨意猜測的,但缺點(diǎn)就是沒有前幾種便利,當(dāng)特征或缺失值較多時(shí)會(huì)比較耗時(shí)。

        說在最后

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


        推薦閱讀

        (點(diǎn)擊標(biāo)題可跳轉(zhuǎn)閱讀)

        同濟(jì)版《線性代數(shù)》引發(fā)激烈爭議!

        介紹一款分享真實(shí)互聯(lián)網(wǎng)薪資的小程序

        21張讓你代碼能力突飛猛進(jìn)的速查表(神經(jīng)網(wǎng)絡(luò)、機(jī)器學(xué)習(xí)、可視化等)


        轉(zhuǎn)了嗎
        ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ??
        ? ? ? ? ? ? ? ? ? ? ? ? ? ?贊了嗎
        在看嗎
        瀏覽 72
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            午夜国产福利一区二区 | 日韩日逼| 国产男女无遮挡猛进猛出图集 | 雷神吃旅行者萝卜视频 | 国产精品久久丝袜人妻 | 小泽玛利亚一区二区免费 | 肏屄在线看 | 夜夜av | 激情久久一区 | chineseavvideo |