3

不均衡なデータを処理するためのtomekのリンクを実装したいと思います。このコードは、1クラスが多数派クラスで、0クラスが少数派である二項分類問題に使用されます。X入力、Y次のコードを記述した出力ですが、計算を高速化する方法を探しています。

コードを改善するにはどうすればよいですか?

#########################
#remove overlapping observation using tomek links
#given observations i and j belonging to different classes
#(i,j) is a Tomek link if there is NO example z, such that d(i, z) < d(i, j) or d(j , z) < d(i, j)
#find tomek links and remove only the observations of the tomek links belonging to majority class (0 class).
#########################
tomekLink<-function(X,Y,distType="euclidean"){
i.1<-which(Y==1)
i.0<-which(Y==0)
X.1<-X[i.1,]
X.0<-X[i.0,]
i.tomekLink=NULL
j.tomekLink=NULL
#i and j belong to different classes
timeTomek<-system.time({
for(i in i.1){
    for(j in i.0){
        d<-dst(X,i,j,distType)
        obsleft<-setdiff(1:nrow(X),c(i,j))
        for(z in obsleft){
            if ( dst(X,i,z,distType)<d | dst(X,j,z,distType)<d ){
                break() #(i,j) is not a Tomek link, get next pair (i,j)
                } 
            #if z is the last obs and d(i, z) > d(i, j) and d(j , z) > d(i, j),then (i,j) is a Tomek link
            if(z==obsleft[length(obsleft)]){
                if ( dst(X,i,z,distType)>d & dst(X,j,z,distType)>d ){
                    #(i,j) is a Tomek link
                    #cat("\n tomeklink obs",i,"and",j)
                    i.tomekLink=c(i.tomekLink,i)
                    j.tomekLink=c(j.tomekLink,j)
                    #since we want to eliminate only majority class observations
                    #remove j from i.0 to speed up the loop
                    i.0<-setdiff(i.0,j)
                    }
                }
            }
        }
    }
})  
print(paste("Time to find tomek links:",round(timeTomek[3],digit=2))) 
#id2keep<-setdiff(1:nrow(X),c(i.tomekLink,j.tomekLink))
id2keep<-setdiff(1:nrow(X),j.tomekLink)
cat("numb of obs removed usign tomeklink",nrow(X)-length(id2keep),"\n",
    (nrow(X)-length(id2keep))/nrow(X)*100,"% of training ;",
    (length(j.tomekLink))/length(which(Y==0))*100,"% of 0 class")
X<-X[id2keep,]
Y<-Y[id2keep]
cat("\n prop of 1 afer TomekLink:",(length(which(Y==1))/length(Y))*100,"% \n")
return(list(X=X,Y=Y))
}


#distance measure used in tomekLink function
dst<-function(X,i,j,distType="euclidean"){
d<-dist(rbind(X[i,],X[j,]), method= distType)
return(d)
}
4

1 に答える 1

0

私はあなたのコードをテストしていませんが、一見したところ、事前割り当てが役立つようです。i.tomekLink=c(i.tomekLink,i) を使用しないで、アプリオリに Tomek リンクを格納するためのメモリを割り当てようとします。

別のアイデアは、すべてのサンプルからすべてのサンプルへの距離行列を計算し、各サンプルの最も近い近傍を調べることです。それが別のクラスのものである場合は、tomek リンクがあります。

于 2012-11-22T11:29:14.027 に答える