用什么R代码来计算分类变量中每个水平的熵

v09wglhw  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(153)

我有相当多的分类变量在我的数据集,这些变量有两个以上的水平每个。现在我想要一个R代码函数(或循环),可以计算熵和信息增益的每个水平在每个分类变量,并返回最低的熵和最高的信息增益。

data <- list(buys = c("no", "no", "yes", "yes", "yes", "no", "yes", "no", "yes", "yes", "yes", "yes", "yes", "no"),credit = c("fair", "excellent", "fair", "fair", "fair", "excellent", "excellent", "fair", "fair", "fair", "excellent", "excellent", "fair", "excellent"),student = c("no", "no", "no","no", "yes", "yes", "yes", "no", "yes", "yes", "yes", "no", "yes", "no"),income = c("high", "high", "high", "medium", "low", "low", "low", "medium", "low", "medium", "medium", "medium", "high", "medium"),age = c(25, 27, 35, 41, 48, 42, 36, 29, 26, 45, 23, 33, 37, 44))
data<- as.data.frame(data)

以上是一个示例 Dataframe

entropy_tab <- function(x) { tabfun2 <- prop.table(table(data[,x],training_credit_Risk[,13]) + 1e-6, margin = 1)sum(prop.table(table(data[,x]))*rowSums(-tabfun2*log2(tabfun2)))}

上面的函数计算每个变量的熵,我想要一个函数来计算每个级别对熵的贡献?即“优秀”和“一般”对“信用”熵的贡献

vdzxcuhz

vdzxcuhz1#

在测度论中,事件A在具有测度mu的测度空间中的 * 期望惊奇 * 为

-mu(A)log(mu(A))

所以熵是所有事件的预期意外之和,所以你要找的是每个变量的每个水平的预期意外。
请注意,您无法将数据框的惊喜表现为数据框,因为数据框中的每个变量都有不同数量的水平。
你能做到

exp_surprisal <- function(x, base=exp(1)) {
  t <- table(x)
  freq <- t/sum(t)
  ifelse(freq==0, 0, -freq * log(freq, base))
}

然后

lapply(data, exp_surprisal)

给予

$buys
x
       no       yes 
0.3677212 0.2840353 

$credit
x
excellent      fair 
0.3631277 0.3197805 

$student
x
       no       yes 
0.3465736 0.3465736 

$income
x
     high       low    medium 
0.3579323 0.3579323 0.3631277 

$age
x
       23        25        26        27        29        33        35        36        37        41        42        44        45        48 
0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041 0.1885041

注意,您还可以定义

entropy <- function(x) sum(exp_surprisal(x))

得到熵。
然后

lapply(data, entropy)

给予

$buys
[1] 0.6517566

$credit
[1] 0.6829081

$student
[1] 0.6931472

$income
[1] 1.078992

$age
[1] 2.639057
z18hc3ub

z18hc3ub2#

你必须修改你的函数,使它有两个输入,你想要的变量和变量的水平,然后在函数内部根据你想要的变量的水平进行子集化,然后我使用mapply循环遍历变量credit和它的每一个水平。

entropy_tab <- function(x,y) { 
  tabfun2 <- prop.table(table(data[,x][data[,x] == y] ,data[,5][data[,x]==y]) + 1e-6, margin = 1)
sum(prop.table(table(data[,x][data[,x] == y]))*rowSums(-tabfun2*log2(tabfun2)))
}

x <- mapply(entropy_tab, c("credit","credit"), unique(data$credit))

names(x) <- unique(data$credit)

#checks
entropy_tab("credit","excellent")
entropy_tab("credit","fair")

相关问题