python 计算(最小)描述长度- MDL

icomxhvb  于 2023-05-05  发布在  Python
关注(0)|答案(1)|浏览(123)

我有两个整数数组,xy

x = np.array([[1, 2, 0, 12,  4],
              [5, 2, 1, 10, 12]]
            )

y = np.array([[1, 2, 0, 11,  4],
              [5, 3, 0, 10, 15]]
            )

我想使用x来压缩/计算y的描述长度(以“位”为单位),然后比较作为压缩结果的“节省的位”的数量。考虑到我们的数据很小,我们将简单地使用n_bits = 8(8位)来存储每个整数。在未压缩的情况下,总共需要2 x 5 x 8 = 80位来存储y(即,DL(y) = 80)。类似地,DL(x) = 80。现在,让我们假设x是压缩y的最佳“模型”/“假设”,然后根据MDL框架:

DL(y, x) = DL(y|x) + DL(x)

其中DL(x)是存储x所需的位数,DL(y|x)是给定xy的剩余位:

residual = x - y

array([[ 0,  0,  0, -1,  0],
       [ 0,  1, -1,  0,  3]])

那么,这个残差数组的DL(y|x)是多少?根据我遇到的一些例子(我并不完全理解),DL(y|x)可以通过首先确定残差中唯一值的数量来计算

n_bits = 8
n_unique = len(np.unique(residual))  # 4
DL_residual = 2 * 5 * np.log2(n_unique) + n_unique * n_bits  # 52 bits

如果我理解正确的话,由于n_unique = 4(即残差的基数为4),那么看起来2 * 5 * np.log2(n_unique)是用来存储残差的位数。但是,我完全不知道为什么需要n_unique * n_bits(也许不是??)。很天真地,我会假设2 * 5 * np.log2(n_unique)就足够了。
我甚至不知道这是否是计算残差的描述长度的正确方法,最终,我需要弄清楚残差的描述长度是多少。

brjng4g3

brjng4g31#

TLDR;您需要2 * 5 * np.log2(n_unique)位来存储唯一值的位置,但是您还需要n_unique * n_bits位来存储唯一值本身。
为了使用x压缩y而应用的变换如下所示:
1.使用x作为y的最佳可能模型并计算residual。如果x是完美的,那么您期望在residual中看到全零。然而,由于它不是完美的,所以还有一些其他的值。您已获得以下残差:

array([[ 0,  0,  0, -1,  0],
       [ 0,  1, -1,  0,  3]])

1.许多值为0,其他一些值相同。因此,为了压缩residual,我们确定唯一的整数值,并将每个值替换为存储唯一值的数据结构中的值的索引。我将在这里使用一个列表,特别是以下内容:

[0, -1, 1, 3]

当我在这个列表中用它们的索引替换值时,残差变成:

array([[ 0,  0,  0,  1,  0],
       [ 0,  2,  1,  0,  2]])

由于索引甚至比值更小,我们需要更少的位来存储它们。我们只需要2 * 5 * log2(len(unique))位来存储这个转换后的数组。但是,如果我们只存储这个值,我们就缺少了重建y所需要插入的实际值!3.因此,我们还需要存储包含唯一值的列表。这里的元素是具有通常位数n_bits的整数。我们有n_unique=4,所以要存储unique,我们需要n_unique * n_bits位,而只存储索引。
如果x能完美预测y,那么residual将全为零。在这种情况下,只有一个唯一值(0)。有了这个,你只需要存储数组的大小,或者如果你不想存储这个信息,一个0的字符串编码为一个单一的位。当然,你也需要存储0
事实上,即使residual只包含其他值,也会获得相同的压缩大小。

相关问题