Bir veri kümesinden aykırı değerler nasıl kaldırılır


98

Yaşlara karşı güzellikle ilgili çok değişkenli verilerim var. Yaşlar, 2 (20, 22, 24 .... 40) aralıklarla 20-40 arasında değişmektedir ve her veri kaydı için 1-5 arasında bir yaş ve güzellik derecesi verilmektedir. Bu verilerin kutu grafiklerini yaptığımda (X ekseni boyunca yaş, Y ekseni boyunca güzellik derecelendirmeleri), her kutunun bıyıklarının dışında çizilen bazı aykırı değerler var.

Bu aykırı değerleri veri çerçevesinden kaldırmak istiyorum, ancak R'nin kutu grafikleri için aykırı değerleri nasıl hesapladığından emin değilim. Aşağıda verilerimin nasıl görünebileceğine dair bir örnek var. görüntü açıklamasını buraya girin


2
boxplotİşlev görünmez (diğer istatistikler arasında) uç değerleri verir. Çıktıyı anlamaya çalışın foo <- boxplot(...); foove okuyun ?boxplot.
Joshua Ulrich

@ Prasad'ın cevabına verdiğiniz yoruma göre sorunuzu düzenlemelisiniz!
aL3xa

@ aL3xa: ikinci paragrafın ilk cümlesindedir.
Joshua Ulrich


Verilere bir bağlantı gönderebilir misiniz?
wordforthewise

Yanıtlar:


120

Tamam, veri kümenize böyle bir şey uygulamalısınız. Değiştirmeyin ve kaydetmeyin, aksi takdirde verilerinizi yok edersiniz! Ve btw, aykırı değerleri (neredeyse) asla verilerinizden çıkarmamalısınız:

remove_outliers <- function(x, na.rm = TRUE, ...) {
  qnt <- quantile(x, probs=c(.25, .75), na.rm = na.rm, ...)
  H <- 1.5 * IQR(x, na.rm = na.rm)
  y <- x
  y[x < (qnt[1] - H)] <- NA
  y[x > (qnt[2] + H)] <- NA
  y
}

Eylem halinde görmek için:

set.seed(1)
x <- rnorm(100)
x <- c(-10, x, 10)
y <- remove_outliers(x)
## png()
par(mfrow = c(1, 2))
boxplot(x)
boxplot(y)
## dev.off()

Ve bir kez daha, bunu asla kendi başınıza yapmamalısınız, aykırı değerlerin sadece olması gerekiyor! =)

DÜZENLEME:na.rm = TRUE Varsayılan olarak ekledim .

EDIT2:quantile İşlev kaldırıldı , abonelik eklendi, bu nedenle işlevi daha hızlı hale getirdi! =)

görüntü açıklamasını buraya girin


Yardım için teşekkürler! Eğer R, kutu grafiğinde aykırı değerleri verebiliyorsa, bu aracı hesaplamaları yapmak zorunda kalmamalıyım. Aykırı değerlerin silinmesine gelince, bu sadece bir ödev içindir.
Dan Q

3
Tamam, burada bir şey eksik. Aykırı değerleri verilerden kaldırmak istersiniz, böylece onları çizebilirsiniz boxplot. Bu yönetilebilir ve sorunuzu yanıtladığından beri @ Prasad'ın cevabını işaretlemelisiniz. Aykırı değerleri "aykırı değer kuralı" kullanarak hariç tutmak istiyorsanız q +/- (1.5 * H), bu nedenle bazı analizler çalıştırın ve sonra bu işlevi kullanın. BTW, bunu Googling olmadan sıfırdan yaptım, bu yüzden tekerleği bu işlevimle yeniden keşfetme şansım var ...
aL3xa

10
Stackoverflow'da ödev soruları sormamalısınız!
hadley

7
Bu da cevaplamamamız gerektiği anlamına mı geliyor? =)
aL3xa

5
"aykırı değerler sadece öyle olmalı" mı? Şart değil. Ölçü hatalarından kaynaklanabilirler ve iyice gözden geçirilmeleri gerekir. Aykırı değer çok büyük olduğunda, bir anlamı olabilir veya çok fazla olmayabilir. Bu nedenle (en azından biyolojide) medyan, bir popülasyon hakkında ortalamadan daha fazlasını söyler.
Rodrigo

133

En basit cevabı kimse göndermedi:

x[!x %in% boxplot.stats(x)$out]

Şuna da bakın: http://www.r-statistics.com/2011/01/how-to-label-all-the-outliers-in-a-boxplot/


4
Gerçekten zarif. Teşekkürler. Ancak, dağıtımın birden fazla modu varsa ve aykırı değerler gerçekten çok azsa ve dağınıksa dikkatli olunmalıdır.
KarthikS

Bir veri kümesinde indekslerini alabilseydiniz harika olurdu. Yapma şekliniz veri değerine göre filtreleyecektir. Kutu grafiği de gruplama yapıyorsa, her grupta aynı veri değerinin aykırı olması gerekmez
adam

2
Veri setini değiştirmediğini belirtmek de önemlidir. Bu sadece bir filtreleme yöntemidir. Dolayısıyla, veri setini aykırı değerler olmadan kullanmak istiyorsanız, onu bir değişkene atayın. örneğinresult = x[!x %in% boxplot.stats(x)$out]
Victor Augusto

Tek bir kod satırına sahip olmak, mutlaka basit olduğu anlamına gelmez! Tek satırlık bir kodu anlamak, özellikle yeni başlayanlar için ve yorum olmadan her zaman kolay değildir.
PeyM87

29

outline = FALSEKutu planını yaparken bir seçenek olarak kullanın (yardımı okuyun!).

> m <- c(rnorm(10),5,10)
> bp <- boxplot(m, outline = FALSE)

görüntü açıklamasını buraya girin


4
aslında bu, aykırı değerleri kutu grafiğinin kendisinden kaldıracaktır, ancak aykırı değerleri veri çerçevesinden kaldırmak istiyorum.
Dan Q

2
Görüyorum ki, @Joshua'nın dediği gibi boxplot işlevi tarafından döndürülen verilere (özellikle listedeki outve groupöğelerine) bakmanız gerekiyor .
Prasad Chalasani

16

Boxplot işlevi, çizim yapmak için kullanılan değerleri döndürür (bu daha sonra bxp () tarafından yapılır:

bstats <- boxplot(count ~ spray, data = InsectSprays, col = "lightgray") 
#need to "waste" this plot
bstats$out <- NULL
bstats$group <- NULL
bxp(bstats)  # this will plot without any outlier points

Belirli bir soruyu kasıtlı olarak yanıtlamadım çünkü "aykırı" değerleri ortadan kaldırmanın istatistiksel yanlış uygulama olduğunu düşünüyorum. Onları bir kutu grafiğine yerleştirmemenin kabul edilebilir bir uygulama olduğunu düşünüyorum, ancak bazı standart sapmaları veya belirli sayıda çeyrekler arası genişliği aştıkları için bunları kaldırmak, gözlemsel kaydın sistematik ve bilim dışı bir karıştırmasıdır.


4
Peki, sorunun neden sorulduğunu bilmeden soruyu gözden kaçırmak da iyi bir uygulama değil. Evet, 'aykırı değerleri' verilerden çıkarmak iyi değildir, ancak bazen belirli görevler için aykırı değerler olmadan verilere ihtiyaç duyarsınız. Yakın zamanda yaptığım bir istatistik ödevinde, veriler için kullanılacak en iyi regresyon modelini belirlemek için aykırı değerleri olmayan bir kümeyi görselleştirmek zorunda kaldık. Bu yüzden orada!
Alex Essilfie

4
Özellikle ikna edici olması için "en iyi regresyon modelini belirleme" konusunda bu konuda almış olabileceğiniz tavsiyeleri düşünmüyorum. Bunun yerine, belirsiz bir şekilde belirtilen amaç için aykırı değerleri kaldırmanız gerekirse, o zaman bunun benim konumumun geçersizliğinin kanıtı olmaktan ziyade bunu tavsiye eden kişilere kötü bir şekilde yansıdığını düşünüyorum.
IRTFM

Sanırım "gürültüyü" çıkardığını bildiğinde yasaldır. özellikle fizyolojik verilerde.
roscoe1895

Evet. Sinyali ayrı bir sürecin oluşturduğuna inanmak için iyi bir nedeniniz varsa, bu verilerden çıkarılmanızın gerekçesidir.
IRTFM

9

Ben Aykırı kaldırılmasıyla ilgili paketler için baktı ve bu paket bulundu (şaşırtıcı sözde "aykırı"!): Https://cran.r-project.org/web/packages/outliers/outliers.pdf
onu geçmesi durumunda aykırı değerleri kaldırmanın farklı yollarını görün ve aralarında rm.outlieren uygun olanı kullanmayı ve yukarıdaki bağlantıda söylediği gibi: "Aykırı değer tespit edilir ve istatistiksel testlerle doğrulanırsa, bu işlev onu kaldırabilir veya örnek ortalama veya medyan ile değiştirebilir" ve aynı kaynaktan gelen kullanım kısmı da burada:
" Kullanım

rm.outlier(x, fill = FALSE, median = FALSE, opposite = FALSE)

Bağımsız değişkenler
x bir veri kümesi, çoğunlukla bir vektör. Bağımsız değişken bir veri çerçevesiyse, aykırı değer her sütundan sapply ile kaldırılır. Aynı davranış, matris verildiğinde uygulayarak uygulanır.
doldur TRUE olarak ayarlanırsa, aykırı değer yerine medyan veya ortalama yerleştirilir. Aksi takdirde, aykırı değer (ler) basitçe kaldırılır.
medyan DOĞRU olarak ayarlanırsa, aykırı değer değiştirmede ortalama yerine medyan kullanılır. TRUE olarak ayarlanmışsa tersi, zıt değer verir (en büyük değer ortalamadan maksimum farka sahipse, en küçüğü verir ve tersi) "


Bu harika görünüyor, ancak veri çerçevenizde bir zaman serisi sütununuz varsa, zaman serisini değiştirir.
PeyM87

7
x<-quantile(retentiondata$sum_dec_incr,c(0.01,0.99))
data_clean <- data[data$attribute >=x[1] & data$attribute<=x[2],]

Aykırı değerleri kaldırmayı çok kolay buluyorum. Yukarıdaki örnekte, öznitelik değerlerinin yüzde 2 ila yüzde 98'ini çıkarıyorum.


5

Yapmaz:

z <- df[df$x > quantile(df$x, .25) - 1.5*IQR(df$x) & 
        df$x < quantile(df$x, .75) + 1.5*IQR(df$x), ] #rows

bu görevi oldukça kolay bir şekilde başarabiliyor musunuz?


4

@Sefarkas'ın önerisine ekleyerek ve kesitler olarak niceliği kullanarak, aşağıdaki seçenek keşfedilebilir:

newdata <- subset(mydata,!(mydata$var > quantile(mydata$var, probs=c(.01, .99))[2] | mydata$var < quantile(mydata$var, probs=c(.01, .99))[1]) ) 

Bu, 99. kuantilin ötesindeki noktaları kaldıracaktır. Aykırı değerleri korumak konusunda aL3Xa'nın söylediği gibi dikkatli olunmalıdır. Yalnızca verilerin alternatif muhafazakar bir görünümünü elde etmek için kaldırılmalıdır.


öyle 0.91ya 0.99? olduğu gibi mydata$var < quantile(mydata$var, probs=c(.01, .91))[1])veyamydata$var < quantile(mydata$var, probs=c(.01, .99))[1])
Komal Rathi

99. yüzdelik dilim yerine 91. yüzdelik dilim kullanmak için belirli bir nedeniniz varsa, onu kullanabilirsiniz. Bu sadece bir sezgisel
KarthikS

1

Bunu yapmanın 1 yolu

my.NEW.data.frame <- my.data.frame[-boxplot.stats(my.data.frame$my.column)$out, ]

veya

my.high.value <- which(my.data.frame$age > 200 | my.data.frame$age < 0) 
my.NEW.data.frame <- my.data.frame[-my.high.value, ]

0

Aykırı değerler zirvelere oldukça benzerdir, bu nedenle bir tepe detektörü aykırı değerleri belirlemek için yararlı olabilir. Burada açıklanan yöntem, z puanlarını kullanarak oldukça iyi bir performansa sahiptir. Sayfanın alt kısmındaki animasyon, aykırı değerler veya zirveler hakkında sinyal verme yöntemini gösterir.

Zirveler her zaman aykırı değerlerle aynı değildir, ancak sıklıkla benzerdir.

Burada bir örnek gösterilmektedir: Bu veri seti, seri iletişim yoluyla bir sensörden okunur. Ara sıra meydana gelen seri iletişim hataları, sensör hatası veya her ikisi de tekrarlanan, açıkça hatalı veri noktalarına yol açar. Bu noktada istatistiksel bir değer yoktur. Muhtemelen aykırı değiller, hatalardır. Z-skor tepe detektörü, sahte veri noktalarında sinyal verebildi ve sonuçta temiz bir veri seti oluşturdu:görüntü açıklamasını buraya girin


-1

Bunu dene. Değişkeninizi işlevde besleyin ve o / p'yi kaldırılan aykırı değerleri içeren değişkende kaydedin

outliers<-function(variable){
    iqr<-IQR(variable)
    q1<-as.numeric(quantile(variable,0.25))
    q3<-as.numeric(quantile(variable,0.75))
    mild_low<-q1-(1.5*iqr)
    mild_high<-q3+(1.5*iqr)
    new_variable<-variable[variable>mild_low & variable<mild_high]
    return(new_variable)
}

Lütfen cevabınıza bir açıklama ekleyin. Nasıl cevaplanır bölümüne bakın .
ejderuby
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.