1. 程式人生 > >R語言-缺失值處理2

R語言-缺失值處理2

資料預處理與R語言

前言

  最近正在學習資料探勘方面知識,前前後後也查閱了不少資料。但是總是一個人學習,有點枯燥,所以就想著分享些資料。也是意在找點同道中人交流學習,亦或是大神指導下(這個當然更好><)。第一次發表文章,心裡還是有點緊張的,所以不多說了,直接上乾貨:

  在對資料進行分類前,對資料的預處理可以提高分類預測的準確性、有效性和可伸縮性。以下是幾種資料預處理:

  1、資料清理:為了消除和減少資料噪聲和處理缺失值的資料預處理。雖然大部分的分類演算法都會處理噪聲和缺失值,但在進行分類對資料的清理可以減少學習時的混亂。

  2、相關性分析:資料中很多屬性可能與分類預測任務不相關或是冗餘的。因此在分類前進行相關性分析可以刪除學習過程中不相關的或是冗餘的屬性,提高分類預測的效率和準確率。

  3、資料變換:分類前的資料變換主要有概念分層和規範化兩種。概念分層就是連續值屬性概化為離散的區間,壓縮了原來的訓練資料,學習時可以減少輸入輸出操作。規範化是將給定屬性的所有值按比例縮放,使得它們落入較小的指定區間,比如落入【0,1】內,可以防止具有較大初始域的屬性相對於具有較小初始域的屬性權種過大,該方法常用於神經網路和距離度量方法。

  引自:方匡南. 基於資料探勘的分類和聚類演算法研究及R語言實現[D]. 暨南大學, 2007.

目錄

 1. 資料缺失

 2. 將缺失部分剔除

 3. 用最高頻率來填補缺失值

 4. 通過變數的相關關係來填補缺失值

 5. 通過探索案例之間的相似性來填補缺失值

1. 資料缺失

 當處理含有缺失值(NA)的資料時,可以運用以下幾種最常見的策略:

  • 將含有缺失值的案例剔除。
  • 根據變數之間的相關性關係填補缺失值。
  • 根據案例之間的相似性填補缺失值。
  • 使用能夠處理缺失值資料的工具。

  下文的例子都用到了"DMwR"包,讀取資料程式碼如下:

  library(DMwR)
  data(algae)
  head(algae)

2. 將缺失部分剔除

  將含有缺失值的案例剔除非常容易實現,尤其是當這些記錄所佔的比例在可用資料集中非常小的時候,這個選擇就比較合理。因此,我們在選擇這個方案時先檢查觀測值,或者至少得到這些觀測值的個數。

  例如:

    algae[!complete.case(algae),]
    ...
    ...
    nrow(algae[!complete.case(algae),])
    [1] 16

  函式complete.case()產生一個布林值向量,該向量的元素個數與algae資料框中的行數相同,如果資料框的相應行中不含NA值,則函式返回TRUE。如果直接刪除所有含有至少一個NA的樣本,我們可以輸入:

    algae<-na.omit(algae)

  然而這種辦法太過極端,我們一般不採用。但是對於某些缺失值太多的樣本我們可以直接剔除,因為他們幾乎是無用的樣本。觀測方法可通過如下程式碼:

    apply(algae,1,function(x) sum(is.na(x)))

  然而之前我們載入的"DMwR"包中有相關處理函式,應用如下:

    algae<-algae[-manyNAs(algae),]

  函式manyNAs()的功能是找出缺失值個數大於列數20%的行,第二個引數預設值是0.2。

3. 用最高頻率來填補缺失值

  填補含有缺失值記錄的另一個方法是嘗試找到這些缺失值最可能的值。這裡也有多種策略可以選擇,不同策略對逼近程度和演算法複雜度的權衡不同。
填補缺失資料最簡便和快捷的方法是使用一些代表中心趨勢的值。代表中心趨勢的值反映了變數分佈的最常見值,因此中心趨勢值是最自然的選擇。然而,中心趨勢值也有很多種,如平均值、中位數、眾數等。如何選擇還要由變數的分佈決定。對於接近正態分佈來說,所有的觀測值都較好地聚集在平均值周圍,平均數就是最佳選擇。然而對於偏態分佈,平均值就不適用。另一方面,離群值(極值)的存在會扭曲平均值(這些可以通過箱式圖觀測到)。下面我們列舉幾個填補例子:

  用平均值填補:

    algae[48,"mxPH"]<-mean(algae$mxPH,na.rm=T)

  用中位數填補:

    algae[is.na(algae$Chla),"Chla"]<-median(algae$Chla,na.rm=T)

  其中,na.rm是使計算時忽略缺失資料。當然,我們例子中用到的包下也提供了一個函式centralImputation()可以用資料的中心趨勢值來填補缺失值。對數值型變數使用中位數,對名義變數使用眾數。應用如下:

   data(algae)
   algae<-algae[-manyNAs(algae),]
   algae<-centralImputation(algae)

  上述方法雖然快捷方便,但是它可能導致較大的資料偏差,影響後期的資料分析工作。

4. 通過變數的相關關係來填補缺失值

  另一種獲得較少偏差填補缺失值的方法是探尋變數之間的相關關係。我們可以通過以下命令:

    symnum(cor(algae[,4:18],use="complete.obs"))

  函式cor()的功能是產生變數之間的相關值矩陣,設定引數use="complete.obs"可以使R在計算相關值時忽略含有NA的紀錄。而函式symnum()是用來改善結果的輸出形式的。
在找到相關性較高的兩個變數後,我們開始尋找他們之間的線性相關關係,如下:

   data(algae)
   algae<-algae[-manyNAs(algae),]
   lm(PO4~oPO4,data=algae)

  然後,我們通過線性關係計算缺失值的填補值。

  如果PO4中存在多個缺失值,我們也可以通過構造一個函式來完成,如下:

   data(algae)
   algae<-algae[-manyNAs(algae),]
   fillPO4<-function(oP){
     if(is.na(oP))
        return(NA)
     else return(42.897+1.293*oP)
    }
   algae[is.na(algae$PO4),"PO4"]<-sapply(algae[is.na(algae$PO4),"oPO4"],fillPO4)

  函式sapply()的第一個引數是一個向量,第二個引數是一個函式。作用是將函式結果應用到第一個引數中向量的每一個元素。

  在上面的例子中由於我們使用的是相關值,所以只用到了數值變數而排除了名義變數與缺失值之間的關係。針對這個,我們可以通過直方圖等形式進行觀測(這裡不多贅述,感興趣的可以查閱原書)。

5. 通過探索案例之間的相似性來填補缺失值

  除了變數之間的相關性外,多個樣本(行)之間的相似性也可以用來填補缺失值。度量相似性的指標有很多,常用的是歐式距離,這個距離可以非正式的定義為任何兩個案例之的觀測值之差的平方和。書中提供的包的函式knnImputation()可以實現上述操作,這個函式用一個歐式距離的變種來找到任何個案最近的k個鄰居。使用方法如下:

    algae<-knnImputation(algae,k=10)

  用中位數來填補:

    algae<-knnImputation(algae,k=10,meth="median")

小結

  綜合上述幾個方法,各有優缺點,具體如何選擇還應該根據分析領域的知識來確定。此外,根據個案之間的相似性來填補缺失值也有不合理處,例如可能存在不相關的變數扭曲相似性。對於這些大資料集問題,可以通過隨機抽取樣本的方法來計算它們之間的相似性。

參考資料