AYKIRI DEĞERLER ÜZERİNDE R İLE İŞLEM YAPILMASI VE AYKIRI DEĞERLERİN BELİRLENMESİ

Verideki aykırılıklar uygun şekilde belirlenip üstesinden gelinmezse, özellikle regresyon modellerinde tahminleri bozabilir ve doğruluğu etkileyebilir.

Aykırı değerler üzerindeki işlemler neden önemlidir?

Çünkü uydurulmuş tahmin ve öngörüleri belirgin bir biçimde değiştirebilir. Bunu, arabalar veri setini kullanarak gösterebilirim.

Aykırı değerler ile ne anlatılmak istendiğini daha iyi anlamak için, arabalar veri seti üzerinde yapılmış olan lineer regresyon modelini aykırı değerler dahil ve aykırılıklar dahil olmadan olmak üzere karşılaştıracağım. Etkiyi daha iyi ayırt edebilmek için ekstrem değerleri, orijinal arabalar veri setine kendim giriyorum. Sonrasında ise iki veri seti üzerinde tahminlerde bulunuyorum.

# Inject outliers into data.
cars1 <- cars[1:30, ]  # original data
cars_outliers <- data.frame(speed=c(19,19,20,20,20), dist=c(190, 186, 210, 220, 218))  # introduce outliers.
cars2 <- rbind(cars1, cars_outliers)  # data with outliers.

# Plot of data with outliers.
par(mfrow=c(1, 2))
plot(cars2$speed, cars2$dist, xlim=c(0, 28), ylim=c(0, 230), main="With Outliers", xlab="speed", ylab="dist", pch="*", col="red", cex=2)
abline(lm(dist ~ speed, data=cars2), col="blue", lwd=3, lty=2)

# Plot of original data without outliers. Note the change in slope (angle) of best fit line.
plot(cars1$speed, cars1$dist, xlim=c(0, 28), ylim=c(0, 230), main="Outliers removed \n A much better fit!", xlab="speed", ylab="dist", pch="*", col="red", cex=2)
abline(lm(dist ~ speed, data=cars1), col="blue", lwd=3, lty=2)

Orijinal verinin aykırılıklar dahil olarak ve olmadan çizilmiş grafikleri:

Aykırılıkların kaldırılması ile en iyi uydurma çizgisinin eğimi üzerindeki değişime dikkat ediniz. Eğer aykırılıkları modelden kaldırmamış olsaydık (soldaki grafik), yüksek eğimden dolayı tahminlerimiz yüksek değerler için abartılmış olurdu (yüksek hata).

Aykırılıkların Belirlenmesi

Tek Değişkenli Yaklaşım

Aykırılıklar, verilmiş bir sürekli değişken için 1.5*IQR dışında kalan gözlemlerdir. IQR, (kartiller arası aralık) %75 ve %25 kartiller (dördünler) arasındaki farkı verir. Aşağıdaki kutu grafikte, alt ve üst limitler dışında kalan noktaları inceleyelim.

outlier_values <- boxplot.stats(inputData$pressure_height)$out  # outlier values.
boxplot(inputData$pressure_height, main="Pressure Height", boxwex=0.1)
mtext(paste("Outliers: ", paste(outlier_values, collapse=", ")), cex=0.6)

İki Değişkenli Yaklaşım

Kategorik X değerleri için, X ve Y değerlerini kutu grafiğinde görsel hale getirelim.

url <- "http://rstatistics.net/wp-content/uploads/2015/09/ozone.csv"
ozone <- read.csv(url)

# For categorical variable
boxplot(ozone_reading ~ Month, data=ozone, main="Ozone reading across months")  # clear pattern is noticeable.
boxplot(ozone_reading ~ Day_of_week, data=ozone, main="Ozone reading for days of week")  # this may not be significant, as day of week variable is a subset of the month var.

Kutu-grafiği:

Çıkarım nedir? Kutuların seviyelerindeki değişim, ayın ozon değerleri üzerinde etkisi var iken haftanın gününün etkisi olmadığını gösteriyor. İlgili kategorik düzeydeki aykırı değerler, kutu grafiğinin bıyıklarının dışında noktalar olarak görünür.

# For continuous variable (convert to categorical if needed.)
boxplot(ozone_reading ~ pressure_height, data=ozone, main="Boxplot for Pressure height (continuos var) vs Ozone")
boxplot(ozone_reading ~ cut(pressure_height, pretty(inputData$pressure_height)), data=ozone, main="Boxplot for Pressure height (categorial) vs Ozone", cex.axis=0.5)

Kutu grafiğinde birkaç aykırı değer ve ozon değerlerinin basınç yüksekliği ile nasıl arttığını görebilirsiniz. Bu açıktır.

Çok Değişkenli Model Yaklaşımı

Cook Mesafesi

Cook’un mesafesi, belirli bir regresyon modeline göre hesaplanan bir ölçüdür ve bu nedenle yalnızca modele dahil edilen X değişkenlerinden etkilenir. Peki Cook mesafesi ne anlama geliyor? Her veri noktasının (satır) öngörülen sonuç üzerindeki etkisini hesaplar. Her gözlem i’ye denk gelen Cook mesafesi, gözlem i olan ve olmayan tüm gözlemler için Ŷ (uydurulmuş Y) ‘deki değişikliği ölçer.

mod <- lm(ozone_reading ~ ., data=ozone)
cooksd <- cooks.distance(mod)

Etki Ölçekleri

Genelde Cook mesafesi ortalamanın 4 katından daha fazla olan gözlemler, etkisel olarak sınıflandırılabilir. Bu katı bir sınır değildir.

plot(cooksd, pch="*", cex=2, main="Influential Obs by Cooks distance")  # plot cook's distance
abline(h = 4*mean(cooksd, na.rm=T), col="red")  # add cutoff line
text(x=1:length(cooksd)+1, y=cooksd, labels=ifelse(cooksd>4*mean(cooksd, na.rm=T),names(cooksd),""), col="red")  # add labels

Cook mesafesine göre etkili gözlemler:

Şimdi orijinal verilerden etkili kayıtları bulalım. Her etkili satırı birer birer çıkarır ve incelerseniz (çıktının altından), bu satırın neden etkisel olduğunu anlayabilirsiniz. Modelde yer alan X değişkenlerinden birinin uç değerlere sahip olması muhtemeldir.

influential  4*mean(cooksd, na.rm=T))])  # influential row numbers
head(ozone[influential, ])  # influential observations.
#>     Month Day_of_month Day_of_week ozone_reading pressure_height Wind_speed Humidity
#> 19      1           19           1          4.07            5680          5       73
#> 23      1           23           5          4.90            5700          5       59
#> 58      2           27           5         22.89            5740          3       47
#> 133     5           12           3         33.04            5880          3       80
#> 135     5           14           5         31.15            5850          4       76
#> 149     5           28           5          4.82            5750          3       76
#>     Temperature_Sandburg Temperature_ElMonte Inversion_base_height Pressure_gradient
#> 19                    52               56.48                   393               -68
#> 23                    69               51.08                  3044                18
#> 58                    53               58.82                   885                -4
#> 133                   80               73.04                   436                 0
#> 135                   78               71.24                  1181                50
#> 149                   65               51.08                  3644                86
#>     Inversion_temperature Visibility
#> 19                  69.80         10
#> 23                  52.88        150
#> 58                  67.10         80
#> 133                 86.36         40
#> 135                 79.88         17
#> 149                 59.36         70

Bu satırların neden etkisel gözlemler olarak etiketlenebileceğini öğrenmek için yukarıdaki çıktıdan ilk altı satırı inceleyelim.

-Satır 58, 133, 135’te çok yüksek ozon değerleri vardır.

-Satır 23, 135 ve 149 çok yüksek Inversion_base_height değerine sahiptir.

-Satır 19’da çok düşük basınç gradyanı vardır.

Aykırılık Testi

Car paketindeki outlierTest fonksiyonu, verilen modele bağlı olarak en uç değerleri verir.

car::outlierTest(mod)
#> No Studentized residuals with Bonferonni p  Largest |rstudent|:
#>     rstudent unadjusted p-value Bonferonni p
#> 243 3.045756          0.0026525      0.53845

Bu çıktı, satır 243’teki gözlemin en ekstrem nokta olduğunu göstermektedir.

Aykırı Değer Paketi

Aykırı değer paketi, aykırı değerleri sistematik olarak ayıklamak için bir dizi kullanışlı fonksiyon sağlar. Bunlardan özellikle outlier () ve score () işlevleri kullanışlıdır.

Outliers Fonksiyonu

Outliers fonksiyonu, ortalama değerden (mean) en uç gözlemi bulur. Eğer komutta opposite=TRUE kullanırsanız, gözlemi diğer taraftan alır.

set.seed(1234)
y=rnorm(100)
outlier(y)
#> [1] 2.548991
outlier(y,opposite=TRUE)
#> [1] -2.345698
dim(y) <- c(20,5)  # convert it to a matrix
outlier(y)
#> [1] 2.415835 1.102298 1.647817 2.548991 2.121117
outlier(y,opposite=TRUE)
#> [1] -2.345698 -2.180040 -1.806031 -1.390701 -1.372302

Scores Fonksiyonu

Scores() fonksiyonunun iki kullanımı vardır.

-Normalleştirilmiş skorları, “z”, “t”, “chisq” ve benzerlerini temel alarak hesaplar.

-Belirli bir yüzdeye dayalı olarak verilen bir yüzdelik değerin ötesinde olan gözlemleri bulur.

set.seed(1234)
x = rnorm(10)
scores(x)  # z-scores => (x-mean)/sd
scores(x, type="chisq")  # chi-sq scores => (x - mean(x))^2/var(x)
#> [1] 0.68458034 0.44007451 2.17210689 3.88421971 0.66539631  . . .
scores(x, type="t")  # t scores
scores(x, type="chisq", prob=0.9)  # beyond 90th %ile based on chi-sq
#> [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
scores(x, type="chisq", prob=0.95)  # beyond 95th %ile
scores(x, type="z", prob=0.95)  # beyond 95th %ile based on z-scores
scores(x, type="t", prob=0.95)  # beyond 95th %ile based on t-scores

İşlemler

Aykırı değerler belirlendikten sonra, aşağıdaki yaklaşımlardan birini kullanarak düzeltebilirsiniz.

Yakıştırma

Ortalama / medyan / modu ile yakıştırma (eksik verilerin değerlerinin belirlenmesi). Bu yöntem, eksik değerlerin üzerine işlemler ile ilgili tartışmada ayrıntılı olarak ele alınmıştır. DataScience+’da ele aldığımız bir diğer sağlam yöntem, zincirleme denklemlerin çok değişkenli yakıştırmasıdır.

Sınırlama

.5 * IQR sınırlarının dışında kalan eksik değerleri, alt sınırın dışındaki gözlemleri 5. (beşinci) yüzdelik değeri ile ve üst sınırın üzerinde bulunan gözlemleri 95. yüzdelik değeri ile değiştirerek kapatabiliriz. Aşağıda bunu başaran bir örnek kod bulunmaktadır.

x <- ozone$pressure_height
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)]  (qnt[2] + H)] <- caps[2]

Tahmin

Yine başka bir yaklaşımda, aykırı değerler, eksik değerleri NA ile değiştirilebilir ve daha sonra bunları bir cevap değişkeni olarak düşünerek tahmin edilebilir. Zaten eksik değerlerin nasıl tahmin edileceğini tartışmıştık.

Kaynak: Outlier detection and treatment with R | R-bloggers (r-bloggers.com)