查找最大和最小矩阵边际总变异性

时间:2016-11-20 12:47:51

标签: r matrix

是否有一种更优雅的方法可以根据二进制矩阵的填充和大小计算出二元矩阵的边际列总数中的最大最小变异性级别(CV) ?考虑到所有行和列总数必须为非零。 e.g。

foo(n_col, n_row, fill){ get maximum possible CV }

我们假设我们有一个名为m的矩阵,其中所有列和行总数都是> 0,但矩阵填充最少。

m <- matrix(rep(0,25), nrow = 5)
diag(m) <- 1
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    0    0    0    0
#[2,]    0    1    0    0    0
#[3,]    0    0    1    0    0
#[4,]    0    0    0    1    0
#[5,]    0    0    0    0    1

variability1 <- sd(colSums(m))/mean(colSums(m))
variability1
# [1] 0
# the maximum and minimum for this fill is zero 
# considering that  all column and row totals must be > 0

也许我们可以在增加的填充水平上检查最大值,如:

# find out which matrix elements are zeros
empty <- which(m < 1)
# vector for results
variability <- rep(NA, length(empty))
#
for(i in 1:length(variability)){
m[empty[[i]] ] <- 1
variability[[i]] <- sd(colSums(m))/mean(colSums(m))
}
# we get what should the maximum CV for each given level of matrix fill...
c(variability1, variability)

我认为像这样按列填充矩阵可以保持边际列总数的最大可变性?有没有更简单的方法来处理不同大小,填充和形状的矩阵的最大和最小可变性?

1 个答案:

答案 0 :(得分:3)

以下提供了问题的替代公式,作为对二元矩阵的列和的向量的选择的优化,其最大化给定fill的可变性。提供了该公式的有效性和解决它的结果算法的非正式论证。得到的算法与OP的断言一致

  

像这样按列填充矩阵可以保持边际列总数的最大可变性

首先,将fill定义为1 n_row二进制矩阵n_colm的数量。根据问题陈述的约束m是一个二进制矩阵,所有行和列的总和大于零,fill[max(n_row, n_col),n_row*n_col]范围内的整数。

问题是fill范围内[max(n_row, n_col),n_row*n_col]的给定值,找到最大值

 sd(colSums(m))/mean(colSums(m))

覆盖所有mmfill1个二进制矩阵,所有行和列的总和大于零。

我们注意到,最好根据m而不是m本身的列总和向量来指定此优化问题的域。这是因为存在具有相同列和的向量的不同m,因此具有相同的目标值。将列和的向量表示为x,上述优化问题可以重新表示为最大化:

sd(x)/mean(x)

这样x的每个元素都是[1, n_row]范围内的整数,sum(x)fill

此外,由于sum(x)被限制为等于fill,因此对于给定的mean(x),分母词x在所有fill上都是常数。因此,最大化的等效目标函数只是sd(x)或等价x的方差。

要最大化x的方差,我们需要选择x,使其值之间的差异最大化,同时仍满足x的约束。在这里,我们可以针对fill归纳地思考这个问题。让我们假设对于给定的fill,我们有x的解决方案,它在满足约束条件的同时最大化x的方差。问题变为:当我们将fill增加到fill + 1时,最大化其方差的新x是什么?因为我们有sum(x)=fill的约束,x中的每个元素都是整数,所以递增fill意味着我们必须增加x中的一个元素。暂时放宽x中每个元素的上限约束(即x[i] <= n_rowi中的[1,n_col]},然后问题变为:{{{{}}中的哪个元素1}}增加最大化x方差的增加。对于这个问题的答案,我们可以看一下x的泰勒级数展开:

var(x)

其中var(x + dx) = var(x) + gradient(var(x)) %*% dx + 1/2 * t(dx) %*% Hessian(var(x)) %*% dx 是长度为dx的向量,其中一个元素等于n_col,所有其他元素为1(即指标向量)。由于0var(x)中是二次方,因此二阶扩展就足够了。此外,由于x是指标向量,因此只有Hessian矩阵的对角元素很重要。这些是由:

给出的
dx

由于Hessian的所有对角线项都相同,因此对于任何gradient(var(x))[i] = 2*(x[i]-mean(x))/(n_col-1), for all i in [1,n_col] Hessian(var(x))[i,i] = 2/n_col , for all i in [1,n_col] 的选择,泰勒级数的二阶项都是相同的。因此,只有第一顺序项才能确定dx中哪个元素增加,以最大化x方差的增加。从渐变项中可以看出,我们应该选择增加x中具有最大当前值i的{​​{1}}个元素,以便最大化方差的增加x。现在,我们重新引入x[i]的每个元素的上限约束。然后,最佳选择是增加x中具有最大当前值x的{​​{1}}个元素。请注意,如果i中有多个此类元素具有相同的最大值x,则选择其中任何一个元素都会导致x[i] < n_row方差的相同最大增加。

我们到目前为止所展示的是,给定x并且x[i] < n_row的解决方案在满足约束条件时最大化x的方差,我们有一条规则{{1}最大化fill的{​​{1}}方差的增量增量。仍然显示此规则会产生新的x,这是x最优化dx的新x的方差。我们现在通过矛盾来证明这一点。具体来说,如果新的fill + 1没有最大化x x的方差,那么x必须存在另一个列和fill + 1向量不同的规则x,以便

x

但是,由于fill + 1x_1最大化fill,并且渐变和Hessian的等式适用于任何dx_1,我们有:

var(x_1 + dx_1) > var(x + dx)
因而矛盾。更清楚地解释这些步骤:

  1. 从第1步到第2步,x var(x)的最佳选择是增加fill中的最大元素,从而增加x。此外,对于给定的var(x_1 + dx_1) = var(x_1) + gradient(var(x_1)) %*% dx_1 + 1/2 * t(dx_1) %*% Hessian(var(x_1)) %*% dx_1 <= var(x_1) + 2*(max(x_1)-mean(x_1))/(n_col-1) + constant <= var(x) + 2*(max(x)-mean(x))/(n_col-1) + constant = var(x + dx) ,二阶项是所有dx_1x_1的常量,因此我们只需将其表示为x_1
  2. 从第2步到第3步,我们假设gradient(var(x_1)) %*% dx_1 <= 2*(max(x_1)-mean(x_1))/(n_col-1)最大化x的方差,(ii)dx以获得最佳效果,我们假设{i} fill constant处的var(x_1) <= var(x)规则,以及xfill最大化gradient(var(x)) %*% dx = 2*(max(x)-mean(x))/(n_col-1)处的差异。要查看后者,请考虑dx的列总和fill的常见前驱向量。递增max(x_1) <= max(x)xfill之间的规则差异只是x_-1中要增加的元素的不同选择。从fill-1方差的泰勒级数展开式可以看出,x_-1中要增加到x的元素的选择必须大于或等于要去的x_1x_-1因为x_-1。因此,x_-1。现在将此推理扩展到以前某个x的列总和的任何公共向量,包括初始x_1,其中列和的初始向量全部为var(x_1) <= var(x)& #39; S。然后,对于一条路径,选择上面定义的最佳增量规则以达到max(x_1) <= max(x);而对于其他路径,请选择增量规则的任意路径以达到fill-k >= max(n_row, n_col)。由于最优规则总是在每一步增加状态的最大元素(受上限限制),因此很明显再次fill
  3. 最后,为了完成数学归纳,我们从1全部为x的初始填充开始。这通常会优化x_1,因为max(x_1) <= max(x)给定此初始填充时没有其他选择。现在,最优增量规则x是选择1的第一个元素来递增,因为所有元素都是相等的。结果var(x)通常会使初始填充的方差最大化为1,因为增加x的任何其他元素将导致相同的方差。

    以上论点立即建议以下算法在列和的向量上分配dx

    1. 遍历列总和x的向量中的每个元素。
    2. 对于每个x + dx - 元素x。请注意,我们会从填充中减去fill,以便我们可以保留这些以填充至少为x的列总和向量的其余元素,并将数量限制为i以满足问题的限制。
    3. 更新x[i] <- min(n_row, fill - (ncol_-i))
    4. 该算法和相关参数验证了OP的断言

        

      像这样按列填充矩阵可以保持边际列总数的最大可变性

      在R中,代码如下:

      (n_col-i)

      认识到循环中1的重复递减可以用n_row替换,上面简化为:

      fill <- fill - x[i]

      使用此功能,我们可以恢复OP的结果:

      foo <- function(n_col, n_row, fill) {
        ## preallocate the vector of column sums x and initialize to NA
        x <- rep(NA, n_col)
        for (i in seq_len(n_col)) {
          x[i] <- pmin.int(n_row, fill-(n_col-i))
          fill <- fill - x[i]
        }
        ## compute the variability given the vector of column sums x
        sd(x)/mean(x)
      }