我已经在R中使用 SMOTE 创建了新数据,并且效果很好。当我进一步研究SMOTE的工作原理时,我找不到答案,SMOTE如何处理分类数据。
本文中仅显示了一个数值示例(第10页)。但是我仍然不知道SMOTE如何从分类示例数据中创建新数据。
这是论文的链接: https://arxiv.org/pdf/1106.1813.pdf
答案 0 :(得分:4)
这确实是一件重要的事情。就您所参考的论文而言,第6.1和6.2节描述了标称连续变量和仅标称变量情况下的可能过程。但是,DMwR
不会使用类似的东西。
如果查看SMOTE
的源代码,您会发现主要工作是由DMwR:::smote.exs
完成的。现在,我将简要解释该过程。
摘要是,因子级别的顺序很重要,并且当前似乎存在一个关于因子变量的错误,该错误使情况相反地起作用。也就是说,如果我们想找到因子水平为“ A”的观测值附近的观测值,则将“ A”以外的任何值视为“接近”,而将水平为“ A”的观测值视为“遥远”。因此,因子变量越多,它们具有的级别越少,连续变量越少,则此bug的影响应该越严重。
因此,除非我错了,否则该函数不应与因素一起使用。
作为示例,让我们考虑具有一个连续变量和一个因子变量的perc.over = 600
的情况。然后,我们到达smote.exs
,并带有与欠采样类别(例如50行)相对应的子数据帧,然后按以下步骤进行操作。
T
包含除类变量之外的所有变量。与连续变量相对应的列保持不变,而因子或字符被强制转换为整数。这意味着因子水平的顺序是必不可少的。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的因子水平“较高”。
for (a in nomatr) xd[, a] <- xd[, a] == 0
,我们将忽略第二列中与因子水平偏差有关的大多数信息:对于与第i次观察具有相同因子水平的情况,我们将偏差设置为1,将0设置为0除此以外。 (我相信它应该与之相反,这意味着它是一个错误;我将进行报告。)dd <- drop(xd^2 %*% rep(1, ncol(xd)))
,对于从第i个观察点开始的每个观察,可以将其视为平方距离的向量,并且kNNs <- order(dd)[2:(k + 1)]
给出k
最近邻的索引。故意将其为2:(k + 1)
,因为第一个元素应为i
(距离应为零)。但是,在这种情况下,由于要点4,第一个元素实际上并不总是i
,这确认了一个错误。neig <- sample(1:k, 1)
。那么difs <- T[kNNs[neig], ] - T[i, ]
是该邻居与第i个观察值之间的分量差异,例如,
difs
# [1] -0.1 -3.0
意味着邻居的两个变量的值都较低。
T[i, ] + runif(1) * difs
来构造,它实际上是第i个变量与邻居之间的凸组合。该行仅用于连续变量。对于因子,我们有c(T[kNNs[neig], a], T[i, a])[1 + round(runif(1), 0)]
,这意味着新观察值将具有与第i个观察值相同的因子水平,机会率为50%,并且与该选定邻居的可能性为50%。因此,这是一种离散插值。