Büyük veri kümelerinden örnekleme (Resample)

Elimizde machine learning metotlarından biriyle eğiteceğimiz veri kümesi olsun. Eğer bu veri kümesinde sınıflar dengeli değılmamışsa, yani örneğin pozitif ve negatif olmak üzere iki sınıflı veri kümesinde negatif olan örneklerin sayısı pozitif olanlardan çok daha fazla ise bu durumda negatif örneklerden belli sayıda örnek alarak eğitmek sonuçları daha elle tutulur mantıklı hale getirecektir.

Bir örnek verelim. Elimizde proteinler arasındaki ilişkileri gösteren bir veri kümesi olsun. Bu kümedeki her bir eleman iki protein arasında ilişki varsa pozitif yoksa (ya da var olduğu bilinmiyorsa) negatif olarak sınıflandırılmış olsun. Bu durumda negatif elemanların sayısı pozitif olanlardan çok daha fazla olacaktır.

pozitif olanların sayısı : 158
negatif olanların sayısı : 354683

Bu durumda eğitici, istediğimiz gibi sağlıklı bir model oluşturmayacaktır. Bizim verileri daha dengeli hale getirmemiz lazım. Yani negatif olanlardan belli sayıda örnek alacağız. Bunu yapmak için WEKA’da SpreadSubsample kullanılabilir. SpreadSubsample filteresine -X parametresini (maxCount) 16000 olarak verdiğimizde her sınıftan en fazla 16000 örnek almasını gerektiğini söylemiş oluruz. Elimizde sadece 158 pozitif olduğundan hepsi alınacaktır, negatiflerden ise sade 16000 tanesi seçilecektir. Aşağıdaki galeride WEKA GUI üzerinden bu işlemlerin nasıl yaptığını görebilirsiniz.

Aynı işi R ile birkaç işlemde yapmamız mümkün.

> length(which(alldata$label == 1))
[1] 158
> length(which(alldata$label == 0))
[1] 354683

> negSamp_Idx = which(alldata$label == 0) # neg olanlari bir kenara ayırdık
> length(negSamp_Idx)
[1] 354683
> negSubSamp_Idx = sample(negSamp_Idx, 16000) # neg olanların 16000 tanesi rasgele alında (örneklendi)
> length(negSubSamp_Idx)
[1] 16000
> posSamp_Idx = which(alldata$label == 1) # pos olanların kenara ayrıldı
> length(posSamp_Idx)
[1] 158
> subSampleAllData = rbind(alldata[posSamp_Idx, ], alldata[negSubSamp_Idx, ]) # pos ve neg örnekler birleştirildi
> nrow(subSampleAllData)
[1] 16158
> head(subSampleAllData)
V1 V2 V3 V4 V5 label
5243 0.5 -0.209416 -0.199330 -0.010026 0.084191 1
21203 -1.0 -0.396010 -0.259078 -0.011425 0.033241 1
21529 -1.0 -0.283479 -0.174865 -0.308930 -0.357127 1
21916 -1.0 -0.273719 -0.149112 -0.259501 0.124685 1
21917 -1.0 -0.310464 -0.257790 0.068314 0.439259 1
21918 -1.0 -0.203387 -0.135462 -0.030543 -0.194464 1

# birleştirme işlemi sırası ile yapıldığı için (rbind) bütün pos örnekler başta kümelendi
# bunu çözmek için datadan tekrar sample yapmamız gerekir

> a = sample(nrow(subSampleAllData))
> head(a)
[1] 4658 3336 2683 14759 14022 8241
> a = subSampleAllData[a, ]
> head(a)
V1 V2 V3 V4 V5 label
193706 -1 -0.216018 -0.166624 0.045931 0.189659 0
294381 -1 -0.250179 -0.051764 -0.058610 0.255319 0
307550 -1 -0.260404 -0.198143 -0.058610 0.033241 0
240577 -1 -0.136214 -0.408705 -0.058610 0.033241 0
303848 -1 -0.251041 -0.275560 -0.058610 0.033241 0
127326 -1 -0.241854 -0.184136 0.027745 0.033241 0

> length(which(a$label == 1))
[1] 158
> length(which(a$label == 0))
[1] 16000