Gói R để kết hợp các cấp yếu tố cho datamining?


10

Tự hỏi nếu có ai đã chạy qua một gói / hàm trong R sẽ kết hợp các cấp của một yếu tố có tỷ lệ của tất cả các cấp trong một yếu tố nhỏ hơn một số ngưỡng? Cụ thể, một trong những bước đầu tiên trong quá trình chuẩn bị dữ liệu mà tôi tiến hành là kết hợp các mức yếu tố thưa thớt với nhau (nói thành một mức gọi là 'Khác'), không chiếm ít nhất 2% tổng số. Điều này được thực hiện không giám sát và được thực hiện khi mục tiêu là mô hình hóa một số hoạt động trong tiếp thị (không phát hiện gian lận, trong đó những sự cố rất nhỏ có thể cực kỳ quan trọng). Tôi đang tìm kiếm một chức năng sẽ thu gọn các mức cho đến khi một số tỷ lệ ngưỡng được đáp ứng.

CẬP NHẬT:

Nhờ những gợi ý tuyệt vời này mà tôi đã viết một chức năng khá dễ dàng. Mặc dù vậy, tôi đã nhận ra rằng có thể thu gọn các mức với tỷ lệ <tối thiểu và vẫn có mức được mã hóa lại là <tối thiểu, yêu cầu bổ sung mức thấp nhất với tỷ lệ> tối thiểu. Có khả năng có thể hiệu quả hơn nhưng nó dường như làm việc. Cải tiến tiếp theo sẽ là tìm ra cách nắm bắt các "quy tắc" để áp dụng logic thu gọn cho dữ liệu mới (bộ xác thực hoặc dữ liệu trong tương lai).

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

Đối với cách tiếp cận khác: stats.stackexchange.com/questions/227125/ từ
kjetil b halvorsen

Câu trả lời:


11

Có vẻ như đó chỉ là vấn đề "tái hiện" yếu tố; không cần tính tổng một phần hoặc tạo một bản sao của vectơ gốc. Ví dụ,

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"

Ở đây, các cấp yếu tố ban đầu được phân phối như sau:

 A  B  C  D  E 
18 23 35 36 38 

và sau đó nó trở thành

Other     C     D     E 
   41    35    36    38 

Nó có thể được thuận tiện bọc thành một chức năng. Có một combine_factor()chức năng trong gói định hình lại , vì vậy tôi đoán nó cũng có thể hữu ích.

Ngoài ra, vì bạn có vẻ thích khai thác dữ liệu, bạn có thể xem gói caret . Nó có rất nhiều tính năng hữu ích cho quá trình tiền xử lý dữ liệu, bao gồm các chức năng như nearZeroVar()cho phép gắn cờ các yếu tố dự đoán với sự phân bổ các giá trị quan sát rất mất cân bằng (Xem họa tiết, dữ liệu mẫu, chức năng tiền xử lý, trực quan hóa và các chức năng khác , ví dụ 5 sử dụng).


@CHI Cảm ơn. Tôi đã nghiên cứu gói caret và đã sử dụng nó để điều chỉnh các tham số meta. rất hữu dụng!.
B_Miner

@chl +1, cái hay đấy. Tôi đã viết chức năng của mình chỉ vì mã [mức (a)% trong% lf] <- "Khác" không hoạt động, vì vậy tôi cho rằng thay đổi cấp độ yếu tố là vấn đề phức tạp. Như thường lệ, hóa ra R không phức tạp, tôi :)
mpiktas

@mpiktas Thx. Bạn có thể làm việc ở cấp độ vectơ với a[as.character(a) %in% lf] <- lf[1]; a <- factor(droplevels(a), labels=c("Other",LETTERS[3:5])).
chl

+1. a [level (a)% in% lf] <- "Other" chắc chắn tiết kiệm được hàng tấn dòng mã. Khéo léo và hiệu quả!
Christopher Aden

Nhưng lưu ý rằng [a == "a"] <- "Khác" sẽ không hoạt động, điều này đối với tôi là khá tự nhiên khi cho rằng nó nên như vậy. Đặc biệt là vì [a == "a"] là hoàn toàn hợp lệ.
mpiktas

5

Vấn đề duy nhất với câu trả lời của Christopher là nó sẽ trộn lẫn thứ tự ban đầu của yếu tố. Đây là cách khắc phục của tôi:

 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)
 }

nơi change.levelslà chức năng sau đây. Tôi đã viết nó một thời gian trước đây, vì vậy tôi nghi ngờ có thể có những cách tốt hơn để đạt được những gì nó làm.

 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

Tôi đã viết một chức năng nhanh chóng sẽ thực hiện mục tiêu này. Tôi là người dùng R mới làm quen, vì vậy có thể chậm với các bảng lớn.

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)
}

Như một ví dụ về nó trong hành động:

> 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"

Cảm ơn đã quan sát, John. Tôi đã thay đổi nó một chút để làm cho nó một yếu tố. Tất cả những gì tôi đã làm là làm lại vectơ ban đầu từ bảng, vì vậy nếu có cách bỏ qua bước đó, việc này sẽ nhanh hơn.
Christopher Aden

Cảm ơn mọi người đã trả lời. R của tôi yếu nhưng khả năng thực hiện điều này với rất ít dòng mã là minh chứng cho việc nó mạnh đến mức nào và khiến tôi muốn học.
B_Miner
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.