我正在使用Keras和Bert (HuggingFace)构建一个多类文本分类模型,但是我有一个非常不平衡的数据集。我使用了Sklearn的SMOTE来为欠平衡的类生成额外的样本(总共有45个),当我使用来自Bert Tokenizer的输入ids时,它工作得很好。
但是,我也希望能够使用smote作为输入掩码I,以便允许模型确定填充值的位置。
我的问题是如何在输入ids和掩码ids中使用smote?到目前为止,我已经完成了以下操作,并且模型没有抱怨,但我不确定重放掩码是否与重放的输入ids行匹配。Smote需要两个输入、输入和标签,所以我用相同的随机状态复制了这个过程,只返回了所需的元素:
def smote(input_ids, input_masks, labels):
smote = SMOTE("not majority", random_state=27)
input_ids_resampled, labels_resampled = smote.fit_sample(input_ids, labels)
input_masks_resampled, _ = smote.fit_sample(input_masks, labels)
return input_ids_resampled, input_masks_resampled, labels_resampled这可以接受吗?有更好的方法吗?
发布于 2020-08-12 14:47:22
我只想澄清这一点,这是一个错误的方式应用到input_ ids。您需要对CLS进行相应的嵌入。使用BERT为每条推文获取CLS令牌,然后对其应用SMOTE。然后从分类器(任何分类器)传递它。这应该在没有微调的情况下完成。
发布于 2020-07-13 00:55:19
我不认为给出的代码是一个好主意。
由于掩码if告诉您哪些标记是真实的,哪些标记来自填充,如果您独立于输入if对它们进行采样,您将得到来自模型忽略的真实输入if的合成输入if,因为相应的合成掩码if(由完全独立的标记生成)指示您的合成输入if正在填充。
愚蠢的例子:
t_1: input ids = [1209, 80183, 290], mask ids = [1,1,0,]t_2: input ids = [39103, 38109, 2931], mask ids = [1,1,1]t_3: input ids = [1242, 1294, 3233], mask ids = [1,0, 0]为了简单起见,假设合成创造是通过平均两个张量来完成的。如果你的随机抽样平均t_1和t_2的输入is,但是t_2和t_3的掩码is,那么得到的合成t_4没有任何意义:它不是任何真实观察的平均值。
解决上述问题的合理方法:只对输入ids进行抽样,作为合成令牌的掩码ids,您可以获取相同掩码ids的平均值。我说的是平均值,但我认为掩码id向量的每个条目的中值可能更合适。我们可以通过将输入ids和掩码ids平放到一维张量中,并对其应用smote (我认为,假设smote是工作组件)来安排这一点。
然而,我认为上述修正仍然没有太大的意义。我不是一个伯特专家,但我的理解是,每个标记都对应于一个精确的整数(甚至可能是散列碰撞)。如果是这样的话,通过简单地对令牌进行平均处理,您将得到完全的胡言乱语。即使为每一个标记(例如,同一类中的5个张量)取中间值,也会导致一个完整的胡言乱语。
所以得出的结论是,我不知道如何解决这个问题。也许一个人可以在BERT模型的中点进行攻击,当令牌已经被部分处理成为浮动时。或甚至在退出标准伯特模型之前,微调到您的具体任务。
最后,我想留给下一个遇到这个问题的人:很明显,SMOTENC是对SMOTENC的一种修改,它适合于整数值向量(以及其他任务)。由于上述原因,我认为它不适合这个目的,但很高兴知道。
https://stackoverflow.com/questions/61776977
复制相似问题