データマイニングのために因子レベルを組み合わせるためのRパッケージ?


10

ファクターのすべてのレベルの比率が特定のしきい値よりも小さいファクターのレベルを組み合わせるRのパッケージ/関数を誰かが実行したかどうか疑問に思いますか?具体的には、私が実施するデータ準備の最初のステップの1つは、少なくとも合計の2%を構成しない、因子のまばらなレベルを(たとえば、「その他」と呼ばれるレベルに)まとめることです。これは、監視なしで行われ、目的がマーケティングの活動をモデル化することである場合に行われます(これらの非常に小さな発生が非常に重要である可能性がある不正検出ではありません)。あるしきい値の割合に達するまでレベルを縮小する関数を探しています。

更新:

これらの素晴らしい提案のおかげで、私はかなり簡単に関数を書きました。ただし、比率<最小のレベルを折りたたむことは可能であり、再コーディングされたレベルが<最小であるため、比率>最小の最低レベルを追加する必要があることに気付きました。おそらくより効率的ですが、動作するようです。次の拡張は、折りたたみロジックを新しいデータ(検証セットまたは将来のデータ)に適用するための「ルール」を取得する方法を理解することです。

collapseFactors<- function(tableName,minPercent=5,fillIn ="RECODED" )
{
    for (i in 1:ncol(tableName))
        {   

            if(is.factor(tableName[,i]) == TRUE) #process just factors
            {


                sortedTable<-sort(prop.table(table(tableName[,i])))
                numberToCollapse<-length(sortedTable[sortedTable<(minPercent/100)])

                if (sum(sortedTable[1:numberToCollapse])<(minPercent/100))
                    {
                        numberToCollapse=numberToCollapse+1 #add next level if < minPercent
                    }

                if(numberToCollapse>1) #if not >1 then nothing to collapse
                {
                    lf <- names(sortedTable[1:numberToCollapse])
                    levels(tableName[,i])[levels(tableName[,i]) %in% lf] <- fillIn
                }
            }#end if a factor


        }#end for loop

    return(tableName)

}#end function

回答:


11

それは単に要因を「再調整」することの問題のようです。部分和を計算したり、元のベクトルのコピーを作成したりする必要はありません。例えば、

set.seed(101)
a <- factor(LETTERS[sample(5, 150, replace=TRUE, 
                           prob=c(.1, .15, rep(.75/3,3)))])
p <- 1/5
lf <- names(which(prop.table(table(a)) < p))
levels(a)[levels(a) %in% lf] <- "Other"

ここでは、元の因子レベルは次のように分布しています。

 A  B  C  D  E 
18 23 35 36 38 

そしてそれは

Other     C     D     E 
   41    35    36    38 

関数に簡単にラップできます。あるcombine_factor()関数リシェイプのパッケージには、私はそれがあまりにも有用である可能性を推測します、。

また、データマイニングに興味があるように思われる場合は、キャレットパッケージを確認することもできます。これには、nearZeroVar()観測値の非常に不均衡な分布で予測子にフラグを付けることができるような関数を含む、データの前処理に役立つ多くの機能があります(ビネット、サンプルデータ、前処理関数、視覚化およびその他の関数、p。5を参照)使用の)。


@CHIありがとう。私はキャレットパッケージを研究し、メタパラメーターの調整に使用しました。非常に便利!。
B_Miner 2010

@chl +1、いいね。コードa [levels(a)%in%lf] <-"Other"が機能しないため、関数を独自に作成したため、因子レベルの変更は複雑な作業であると想定しました。いつものように、Rは複雑ではないことが
わかりました。

@mpiktas Thx。たとえば、を使用してベクトルレベルで作業できa[as.character(a) %in% lf] <- lf[1]; a <- factor(droplevels(a), labels=c("Other",LETTERS[3:5]))ます。
10

+1。a [levels(a)%in%lf] <-"Other"を指定すると、大量のコード行が節約されます。賢くて効率的!
クリストファーアデン2010

ただし、a [a == "a"] <-"Other"は機能しないことに注意してください。特にa [a == "a"]は完全に有効です。
mpiktas 2010

5

クリストファーの答えの唯一の問題は、それが因子の元の順序を混同することです。これが私の修正です:

 Merge.factors <- function(x, p) {
     t <- table(x)
     levt <- cbind(names(t), names(t)) 
     levt[t/sum(t)<p, 2] <- "Other"
     change.levels(x, levt)
 }

どこchange.levels次関数です。少し前に書いたので、それを実現するためのより良い方法があるのではないかと思います。

 change.levels <- function(f, levt) {
     ##Change the the names of the factor f levels from
     ##substitution table levt.
     ## In the first column there are the original levels, in
     ## the second column -- the substitutes
     lv <- levels(f)
     if(sum(sort(lv) != sort(levt[, 1]))>0)
     stop ("The names from substitution table does not match given level names")
     res <- rep(NA, length(f))

     for(i in lv) {
          res[f==i] <- as.character(levt[levt[, 1]==i, 2])
     }
     factor(res)
}

4

この目標を達成するためのクイック関数を書きました。私は初心者のRユーザーなので、大きなテーブルでは遅くなる可能性があります。

Merge.factors <- function(x, p) { 
    #Combines factor levels in x that are less than a specified proportion, p.
    t <- table(x)
    y <- subset(t, prop.table(t) < p)
    z <- subset(t, prop.table(t) >= p)
    other <- rep("Other", sum(y))
    new.table <- c(z, table(other))
    new.x <- as.factor(rep(names(new.table), new.table))
    return(new.x)
}

実際の例として:

> a <- rep("a", 100)
> b <- rep("b", 1000)
> c <- rep("c", 1000)
> d <- rep("d", 1000)
> e <- rep("e", 400)
> f <- rep("f", 100)
> x <- factor(c(a, b, c, d, e, f))
> summary(x)
   a    b    c    d    e    f 
 100 1000 1000 1000  400  100 
> prop.table(table(x))
x
         a          b          c          d          e          f 
0.02777778 0.27777778 0.27777778 0.27777778 0.11111111 0.02777778 
> 
> w <- Merge.factors(x, .05)
> summary(w)
    b     c     d     e Other 
 1000  1000  1000   400   200 
> class(w)
[1] "factor"

観察をありがとう、ジョン。それを要因にするために、少し変更しました。私がしたことはテーブルから元のベクトルを作り直すことだけだったので、そのステップをスキップする方法があれば、これはより速くなります。
Christopher Aden

回答してくれた皆さんありがとう。私のRは弱いですが、数行のコードでこれを実行する能力は、それがいかに強力であるかを証明し、学びたくなります。
B_Miner
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.