我使用
ggseqplot()
库来计算 TraMineR
库中的熵。为了熟悉这个公式,我尝试使用简单的示例数据手动计算它,但没有成功。
字母:3
每个事件的概率:1/26、22/26、3/26
通过
ggseqdplot(mine_mvad.seq, with.entropy = TRUE)
获得的计算结果为0.265087328,这是默认的归一化熵。
公式这里是第77-78页。 我试过 :
- 1/log(3) / ((1/26*(log(1/26)) + 22/26*log(22/26) + 3/26*log(3/26)))
和
- (1/26*log(1/26) + 22/26*log(22/26) + 3/26*log(3/26))
但我没有得到正确的结果。我错过了公式中的一些内容。
分布 $(p_1,...,p_2)$ 的香农熵为 $-\sum_i p_i \log(p_i)$。在
TraMineR
中,熵是用自然对数计算的。
TraMineR
使用函数 seqient
计算纵向熵(即每个序列内的分布熵),并使用函数 seqstatd
计算每个位置的状态分布的横截面熵。函数 ggseqdplot
(来自包 ggseqplot
)绘制横截面分布和横截面熵。绘制的值取自 seqstatd
的结果。
在您的示例中,我们不知道分布
c(1/26, 22/26, 3/26)
对应什么。如果它是长度为 26 的序列内的分布,您应该与 seqient
的结果进行比较。如果是分布,比如在第一个位置,跨 26 个序列,那么您应该与 seqstatd
的结果进行比较(熵是返回列表的第三个元素或 $Entropy
)。两者都返回标准化值。标准化是通过除以给定字母表的最大可能熵(字母表大小的对数)来完成的。在这两种情况下,您都可以通过指定 norm=FALSE
来获取非标准化值。
为了说明这一点,我使用字母表
{"a","b","c"}
构建了一组 26 个长度为 26 的序列。
library(TraMineR)
sdat <- c("a/1-b/22-c/3","b/2-c/24","c/5-b/10-a/11")
sda <- sdat[c(1,rep(2,22),rep(3,3))]
sdsts <- seqformat(sda, from="SPS", to="STS",
SPS.in = list(xfix = "", sdsep = "/"), stsep="-")
myseq <- seqdef(sdsts, cnames=1:26)
seqIplot(myseq)
现在,我们计算横截面熵并显示前五个值:
myseq.distr <- seqstatd(myseq)
myseq.distr$Entropy[1:5]
## 1 2 3 4 5
## 0.4695343 0.3255263 0.1483905 0.1483905 0.1483905
第一个值(即第一个位置的横截面熵)计算为:
ent <- -((1/26*(log(1/26)) + 22/26*log(22/26) + 3/26*log(3/26)))
ent/log(3)
## [1] 0.4695343
我们得到第一个序列的纵向熵
seqient(myseq[1,])
## Entropy
## [1] 0.4695343
和非标准化值
seqient(myseq[1,], norm=FALSE)
## Entropy
## [1] 0.5158361