【问题标题】:Force `table` to include all factors from both arrays in R强制“表”包含 R 中两个数组中的所有因子
【发布时间】:2011-04-05 21:27:35
【问题描述】:

我正在使用以下 R 代码生成混淆矩阵,将某些数据的真实标签与神经网络的输出进行比较。

t <- table(as.factor(test.labels), as.factor(nnetpredict))

但是,有时神经网络无法预测某个类别中的任何一个,因此表格不是正方形的(例如,test.labels 因子中有 5 个级别,但 nnetpredict 中只有 3 个级别因素)。我想通过添加任何必要的因子水平并将它们的计数设置为零来使表格呈正方形。

我该怎么做呢?

示例:

> table(as.factor(a), as.factor(b))

    1 2 3 4 5 6 7 8 9 10
  1 1 0 0 0 0 0 0 1 0  0
  2 0 1 0 0 0 0 0 0 1  0
  3 0 0 1 0 0 0 0 0 0  1
  4 0 0 0 1 0 0 0 0 0  0
  5 0 0 0 0 1 0 0 0 0  0
  6 0 0 0 0 0 1 0 0 0  0
  7 0 0 0 0 0 0 1 0 0  0

您可以在上表中看到有 7 行,但有 10 列,因为 a 因子只有 7 个级别,而 b 因子有 10 个级别。我想要做的是用零填充表格,以便行标签和列标签相同,并且矩阵是正方形。从上面的示例中,这将产生:

    1 2 3 4 5 6 7 8 9 10
  1  1 0 0 0 0 0 0 1 0  0
  2  0 1 0 0 0 0 0 0 1  0
  3  0 0 1 0 0 0 0 0 0  1
  4  0 0 0 1 0 0 0 0 0  0
  5  0 0 0 0 1 0 0 0 0  0
  6  0 0 0 0 0 1 0 0 0  0
  7  0 0 0 0 0 0 1 0 0  0
  8  0 0 0 0 0 0 0 0 0  0
  9  0 0 0 0 0 0 0 0 0  0
  10 0 0 0 0 0 0 0 0 0  0

我需要这样做的原因有两个:

  • 用于显示给用户/在报告中
  • 这样我就可以使用函数来计算 Kappa 统计量,这需要像这样格式化的表格(正方形、同一行和列标签)

【问题讨论】:

  • 不要将对象命名为 t 以保留转置 (t()) 函数的功能。
  • 谢谢 - 没想到!
  • 明白了——我明白你现在需要做什么了,这比我最初想象的要复杂一些。我稍后会考虑这个。你总是有重叠水平的因素吗?因子的顺序是否总是相同的?
  • 谢谢 - 太好了。在这种情况下,我将有一个因素始终包含数字 0-9,而另一个因素将始终是其中的某个子集(大多数情况下它也将是完整的 0-9,但它是当不是我需要整理它时)。它们应该始终按升序排列,至少 table 命令似乎是这样做的。

标签: r machine-learning


【解决方案1】:

编辑 - 第二轮以解决问题中的其他细节。我删除了我的第一个答案,因为它不再相关。

这已经为我提供的测试用例产生了所需的输出,但我绝对建议使用您的真实数据进行彻底测试。此处的方法是找到表中两个输入的完整级别列表,并将该完整列表设置为生成表之前的级别。

squareTable <- function(x,y) {
    x <- factor(x)
    y <- factor(y)

    commonLevels <- sort(unique(c(levels(x), levels(y))))

    x <- factor(x, levels = commonLevels)
    y <- factor(y, levels = commonLevels)

    table(x,y)

}

两个测试用例:

> #Test case 1
> set.seed(1)
> x <- factor(sample(0:9, 100, TRUE))
> y <- factor(sample(3:7, 100, TRUE))
> 
> table(x,y)
   y
x   3 4 5 6 7
  0 2 1 3 1 0
  1 1 0 2 3 0
  2 1 0 3 4 3
  3 0 3 6 3 2
  4 4 4 3 2 1
  5 2 2 0 1 0
  6 1 2 3 2 3
  7 3 3 3 4 2
  8 0 4 1 2 4
  9 2 1 0 0 3
> squareTable(x,y)
   y
x   0 1 2 3 4 5 6 7 8 9
  0 0 0 0 2 1 3 1 0 0 0
  1 0 0 0 1 0 2 3 0 0 0
  2 0 0 0 1 0 3 4 3 0 0
  3 0 0 0 0 3 6 3 2 0 0
  4 0 0 0 4 4 3 2 1 0 0
  5 0 0 0 2 2 0 1 0 0 0
  6 0 0 0 1 2 3 2 3 0 0
  7 0 0 0 3 3 3 4 2 0 0
  8 0 0 0 0 4 1 2 4 0 0
  9 0 0 0 2 1 0 0 3 0 0
> squareTable(y,x)
   y
x   0 1 2 3 4 5 6 7 8 9
  0 0 0 0 0 0 0 0 0 0 0
  1 0 0 0 0 0 0 0 0 0 0
  2 0 0 0 0 0 0 0 0 0 0
  3 2 1 1 0 4 2 1 3 0 2
  4 1 0 0 3 4 2 2 3 4 1
  5 3 2 3 6 3 0 3 3 1 0
  6 1 3 4 3 2 1 2 4 2 0
  7 0 0 3 2 1 0 3 2 4 3
  8 0 0 0 0 0 0 0 0 0 0
  9 0 0 0 0 0 0 0 0 0 0
> 
> #Test case 2
> set.seed(1)
> xx <- factor(sample(0:2, 100, TRUE))
> yy <- factor(sample(3:5, 100, TRUE))
> 
> table(xx,yy)
   yy
xx   3  4  5
  0  4 14  9
  1 14 15  9
  2 11 11 13
> squareTable(xx,yy)
   y
x    0  1  2  3  4  5
  0  0  0  0  4 14  9
  1  0  0  0 14 15  9
  2  0  0  0 11 11 13
  3  0  0  0  0  0  0
  4  0  0  0  0  0  0
  5  0  0  0  0  0  0
> squareTable(yy,xx)
   y
x    0  1  2  3  4  5
  0  0  0  0  0  0  0
  1  0  0  0  0  0  0
  2  0  0  0  0  0  0
  3  4 14 11  0  0  0
  4 14 15 11  0  0  0
  5  9  9 13  0  0  0

【讨论】:

  • @robintw - 更新了答案,认为我们现在应该走在正确的轨道上。让我知道! -C
  • 谢谢 - 这看起来正是我想要的。唯一的问题是有时我会收到一条错误消息Error in t &lt; squareTable(test.labels, nnetpredict) : non-conformable arrays。我不确定为什么会发生这种情况 - 当发生这种情况时,我在数据中看不到任何不同!有什么想法吗?
  • @robintw - 这很奇怪 - 该错误通常意味着您正在尝试执行乘法或无法相乘的矩阵等......这在这里不是很直观。听起来它至少在某些时候像宣传的那样有效?我会首先检查str() 是否有一个测试用例有效,一个测试用例无效,并尝试找出差异。如果可能的话dput() 将一个工作和不工作的例子的内容放入问题中。
  • 谢谢。我设法找到了一个工作和不工作的例子,我把它们放在一个要点中:gist.github.com/905603,因为它们对于这里的问题来说有点太长了。
  • @robintw - 嗯,这两个例子都可以在我的机器上运行,没有任何问题。我认为as.factor() 位可能是多余的,因为该函数将所有内容转换为一个因子 - 但无论哪种方式,代码在我的机器上都可以正常执行。您是否将其用作更大功能的一部分?错误可能来自其他地方吗?我想知道是否存在范围界定问题。也许关闭 R 并重新开始一个新的会话?只是在这里大声思考......
猜你喜欢
  • 2015-07-30
  • 1970-01-01
  • 2019-08-23
  • 2013-11-15
  • 1970-01-01
  • 2021-12-12
  • 2015-06-19
  • 1970-01-01
相关资源
最近更新 更多