1. 程式人生 > >基於R語言的缺失值及異常值處理

基於R語言的缺失值及異常值處理

缺失值

缺失值是指粗糙資料中由於缺少資訊而造成的資料的聚類,分組,刪失或截斷。它指的是現有資料集中某個或某些屬性的值是不完全的。

缺失值的處理方法:對於缺失值的處理,從總體上來說分為刪除存在缺失值的個案和缺失值插補。對於主觀資料,人將影響資料的真實性,存在缺失值的樣本的其他屬性的真實值不能保證,那麼依賴於這些屬性值的插補也是不可靠的,所以對於主觀資料一般不推薦插補的方法。插補主要是針對客觀資料,它的可靠性有保證。

刪除含有缺失值的個案:主要有簡單刪除法和權重法。

  1. 簡單刪除法是對缺失值進行處理的最原始方法。它將存在缺失值的個案刪除。如果資料缺失問題可以通過簡單的刪除小部分樣本來達到目標,那麼這個方法是最有效的。
  2. 當缺失值的型別為非完全隨機缺失的時候,可以通過對完整的資料加權來減小偏差。把資料不完全的個案標記後,將完整的資料個案賦予不同的權重,個案的權重可以通過logistic或probit迴歸求得。如果解釋變數中存在對權重估計起決定行因素的變數,那麼這種方法可以有效減小偏差。如果解釋變數和權重並不相關,它並不能減小偏差。另外對於存在多個屬性缺失的情況不適用。

可能值插補缺失值:原理是以最可能的值來插補缺失值比全部刪除不完全樣本所產生的資訊丟失要少。如果因為一個屬性值的缺失而放棄大量的其他屬性值,這種刪除是對資訊的極大浪費,所以產生了以可能值對缺失值進行插補的思想與方法。常用的有如下幾種方法。

  1. 均值插補:如果缺失值是數值型的,就以該屬性存在值的平均值來插補缺失值;如果缺失值是類別型的,就根據統計學中的眾數原理,用該屬性的眾數(即出現頻率最高的值)來補齊缺失的值;
  2. 利用同類均值插補:同均值插補的方法都屬於單值插補,不同的是,它用層次聚類模型預測缺失變數的型別,再以該型別的均值插補。首先對資訊完全的變數或其子集行聚類,然後按缺失個體所屬類來插補不同類的均值;
  3. 極大似然估計(Max Likelihood)。在缺失型別為隨機缺失的條件下,假設模型對於完整的樣本是正確的,那麼通過觀測資料的邊際分佈可以對未知引數進行極大似然估計。這種方法也被稱為忽略缺失值的極大似然估計,對於極大似然的引數估計實際中常採用的計算方法是期望值最大化(EM)。該方法比刪除個案和單值插補更有吸引力,它一個重要前提:適用於大樣本。可以保證ML估計值是漸近無偏的並服從正態分佈。但該方法可能會陷入區域性極值,收斂速度也不是很快,並且計算很複雜。
  4. 多重插補(Multiple Imputation)。思想來源於貝葉斯估計,認為待插補的值是隨機的,它的值來自於已觀測到的值。具體實踐上通常是估計出待插補的值,然後再加上不同的噪聲,形成多組可選插補值。根據某種選擇依據,選取最合適的插補值。分為三個步驟:①為每個空值產生一套可能的插補值,這些值反映了無響應模型的不確定性;每個值都可以被用來插補資料集中的缺失值,產生若干個完整資料集合。②每個插補資料集合都用針對完整資料集的統計方法進行統計分析。③對來自各個插補資料集的結果,根據評分函式進行選擇,產生最終的插補值。

缺失值檢測
關於缺失值的檢測應該包括:缺失值數量、缺失值比例、缺失值與完整值資料篩選

sum(is.na(data))                #檢視data裡缺失值個數
sum(is.na(data$DINNER_PRICE)    #檢視data裡維度DINNER_PRICE缺失值個數
data=data[!is.na(data$DINNER_PRICE),]     #刪除DINNER_PRICE缺失樣本
data=na.omit(data)              #去除有NA的行(方法1)
data[complete.cases(data),]     #去除有NA的行(方法2)
data[complete.cases(data[,5:6]),]    #只過濾第5列,第6列中含有NA的行

缺失值檢測-整體

sum(complete.cases(data))   #不含缺失值記錄 
sum(!complete.cases(data))    #含缺失值記錄
mean(!complete.cases(data))       #有缺失值記錄比例  
head(data[!complete.cases(data),])  #篩選出有缺失值的記錄 
sum(is.na(data))     #資料集中缺失值總計數量

缺失值檢測-維度檢測

sum(complete.cases(data$CHANNEL_GRADE))   #不含缺失值 
sum(!complete.cases(data$CHANNEL_GRADE))    #含缺失值
mean(!complete.cases(data$CHANNEL_GRADE))       #有缺失值佔比
head(data[!complete.cases(data$CHANNEL_GRADE),])    #篩選出CHANNEL_GRADE有缺失值的記錄

把缺失值資料集、非缺失值資料集分開

sub <- which(is.na(data$CHANNEL_GRADE))  #識別CHANNEL_GRADE中缺失值所在行數  
inputfile1 <- inputfile[-sub,]   #將資料集分成完整資料和缺失資料兩部分  
inputfile2 <- inputfile[sub,] 

異常值(outlier)

指樣本中的個別值,其數值明顯偏離它(或他們)所屬樣本的其餘觀測值,也稱異常資料,離群值。

目前人們對異常值的判別與剔除主要採用物理判別法和統計判別法兩種方法。

  1. 物理判別法就是根據人們對客觀事物已有的認識,判別由於外界干擾、人為誤差等原因造成實測資料值偏離正常結果,在實驗過程中隨時判斷,隨時剔除;
  2. 統計判別法是給定一個置信概率,並確定一個置信限,凡超過此限的誤差,就認為它不屬於隨機誤差範圍,將其視為異常值剔除。當物理識別不易判斷時,一般採用統計識別法。

異常值檢驗

方法1:箱線圖檢驗離群值

sp=boxplot(hon_01$CHARGE_T,boxwex=0.7)  
title("異常值檢測箱線圖")  
xi=1.1  
sd.s=sd(hon_01[complete.cases(hon_01),]$CHARGE_T)  
mn.s=mean(hon_01[complete.cases(hon_01),]$CHARGE_T)  
points(xi,mn.s,col="red",pch=18)  
arrows(xi, mn.s - sd.s, xi, mn.s + sd.s, code = 3, col = "pink", angle = 75, length = .1)  
text(rep(c(1.05,1.05,0.95,0.95),length=length(sp$out)),labels=sp$out[order(sp$out)],  
     sp$out[order(sp$out)]+rep(c(150,-150,150,-150),length=length(sp$out)),col="red")  

方法2:當前值在平均值的±3個標準差之外

a<-matrix(1:12,nrow=3) 
list_mean<- apply(a,2,mean)        #按列求均值
list_sd<-apply(a,2,std)            #按列求標準差
max<-list_mean+3*(list_sd)         #按列求最大值
min<-list_mean-3*list_sd           #按列求最小值
apply(a,2,mean,na.rm=TRUE)         #如果有空值,可以加入na.rm=TRUE,忽略掉空值

方法3:
3.1、計算下四分位數、上四分位數和四分位距

QL <- quantile(value, probs = 0.25)
QU <- quantile(value, probs = 0.75)
QU_QL <- QU-QL

3.2、找出異常點

which(value > QU + 1.5*QU_QL)
value[which(value > QU + 1.5*QU_QL)]

異常值處理
蓋帽法:整行替換資料框裡99%以上和1%以下的點,將99%以上的點值=99%的點值;小於1%的點值=1%的點值

q1 <- quantile(hon_01$USER_AGE, 0.01)        #取得時1%時的變數值  
q99 <- quantile(hon_01$USER_AGE, 0.99)       #取得時99%時的變數值
hon_01[hon_01$USER_AGE < q1,]$USER_AGE <- q1  
hon_01[hon_01$USER_AGE > q99,]$USER_AGE < -q99  
summary(hon_01$USER_AGE)      #蓋帽法之後,檢視資料情況