SMOTE如何从分类数据中创建新数据?

时间:2018-12-06 13:27:53

标签: r

我已经在R中使用 SMOTE 创建了新数据,并且效果很好。当我进一步研究SMOTE的工作原理时,我找不到答案,SMOTE如何处理分类数据。

本文中仅显示了一个数值示例(第10页)。但是我仍然不知道SMOTE如何从分类示例数据中创建新数据。

这是论文的链接: https://arxiv.org/pdf/1106.1813.pdf

1 个答案:

答案 0 :(得分:4)

这确实是一件重要的事情。就您所参考的论文而言,第6.1和6.2节描述了标称连续变量和仅标称变量情况下的可能过程。但是,DMwR不会使用类似的东西。


如果查看SMOTE的源代码,您会发现主要工作是由DMwR:::smote.exs完成的。现在,我将简要解释该过程。

摘要是,因子级别的顺序很重要,并且当前似乎存在一个关于因子变量的错误,该错误使情况相反地起作用。也就是说,如果我们想找到因子水平为“ A”的观测值附近的观测值,则将“ A”以外的任何值视为“接近”,而将水平为“ A”的观测值视为“遥远”。因此,因子变量越多,它们具有的级别越少,连续变量越少,则此bug的影响应该越严重。

因此,除非我错了,否则该函数不应与因素一起使用。


作为示例,让我们考虑具有一个连续变量和一个因子变量的perc.over = 600的情况。然后,我们到达smote.exs,并带有与欠采样类别(例如50行)相对应的子数据帧,然后按以下步骤进行操作。

  1. 矩阵T包含除类变量之外的所有变量。与连续变量相对应的列保持不变,而因子或字符被强制转换为整数。这意味着因子水平的顺序是必不可少的。
  2. 接下来,我们生成50 * 6 = 300个新观测值。为此,我们为50个当前观测值(i = 1,...,50)中的每一个创建6个新观测值(n = 1,...,6)。
  3. 我们用xd <- scale(T, T[i, ], ranges)缩放数据,以便xd显示与第i个观测值的偏差。例如,对于i = 1,我们可能拥有

#             [,1]  [,2]
# [1,]  0.00000000  0.00
# [2,] -0.13333333  0.25
# [3,] -0.26666667  0.25

表示i = 2,3的连续变量小于i = 1的连续变量,但i = 2,3的因子水平“较高”。

  1. 然后通过运行for (a in nomatr) xd[, a] <- xd[, a] == 0,我们将忽略第二列中与因子水平偏差有关的大多数信息:对于与第i次观察具有相同因子水平的情况,我们将偏差设置为1,将0设置为0除此以外。 (我相信它应该与之相反,这意味着它是一个错误;我将进行报告。)
  2. 然后,我们设置dd <- drop(xd^2 %*% rep(1, ncol(xd))),对于从第i个观察点开始的每个观察,可以将其视为平方距离的向量,并且kNNs <- order(dd)[2:(k + 1)]给出k最近邻的索引。故意将其为2:(k + 1),因为第一个元素应为i(距离应为零)。但是,在这种情况下,由于要点4,第一个元素实际上并不总是i,这确认了一个错误。
  3. 现在,我们创建与第i个相似的第n个新观察。首先,我们选择一个最近的邻居neig <- sample(1:k, 1)。那么difs <- T[kNNs[neig], ] - T[i, ]是该邻居与第i个观察值之间的分量差异,例如,

difs
# [1] -0.1 -3.0

意味着邻居的两个变量的值都较低。

  1. 新案例通过运行T[i, ] + runif(1) * difs来构造,它实际上是第i个变量与邻居之间的凸组合。该行仅用于连续变量。对于因子,我们有c(T[kNNs[neig], a], T[i, a])[1 + round(runif(1), 0)],这意味着新观察值将具有与第i个观察值相同的因子水平,机会率为50%,并且与该选定邻居的可能性为50%。因此,这是一种离散插值。