微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ValueError:在使用来自不平衡学习的 SMOTENC 时,无法将输入数组从形状 (3,96) 广播到形状 (184,96)

如何解决ValueError:在使用来自不平衡学习的 SMOTENC 时,无法将输入数组从形状 (3,96) 广播到形状 (184,96)

我正在尝试使用不平衡学习库中的 SMOTENC 对包含分类变量和数值变量的数据框进行过采样。总共有 55 列,其中 3 列是数字。数据集中每类的样本数(值计数)如下:

ID   #of samples
2    281
0    184
6     57
4     27
3      5
7      3

我正在尝试使用代码对该数据集进行过采样:

sm = SMOTENC(cat_features,random_state=42,k_neighbors=1)
x_res,y_res = sm.fit_resample(x,y)

其中 cat_features 包含分类列的索引,y 包含每个样本的类成员,x 包含其余的特征。但是,我不能对该数据集进行过采样,而是收到错误 ValueError: Could not broadcast input array from the shape (3,96) into shape (184,96)。据我了解,该错误与 id 为 7 的类有关。为什么 SMOTENC 不能对此类进行过采样?是否有限制,例如对数据集进行过采样所需的最小样本数?另外,我没有 96 列,这是从哪里来的?

有关错误的更多详细信息如下: 请注意,我所有的分类特征都是二进制的,它们已经是单热编码的。因此,它不需要 SMOTENC 进行任何额外的编码,这意味着不应增加列数。发生错误的确切行是

..\lib\site-packages\imblearn\over_sampling\_smote\base.py",line 577,in _generate_samples
    ] = self._X_categorical_minority_encoded

这个函数的注释 (_generate_samples) 说 “在中值 std 等于零的情况下,我们必须根据 OHE 的编码创建非空条目”。 base.py 中出现错误的完整部分是

if math.isclose(self.median_std_,0):
            nn_data[
                :,self.continuous_features_.size :
            ] = self._X_categorical_minority_encoded

但是,我不明白标准偏差如何为零,因为我知道数据集中的样本彼此不同,因此 std 必须与 0 不同。我知道此列是其中之一两个稀疏的数值列(它们有很多零值)。在 SMOTE 的源代码中,我看到有一个处理稀疏列的函数,但它似乎无法正常工作,这就是我收到错误的方式。我不知道如何解决这个问题,感谢您对此提供的任何帮助或建议。

解决方法

回答您的问题:

是否有限制,例如对数据集进行过采样所需的最小样本数?

根据我的经验,如果您的样本数量小于或等于传递给 SMOTENC 类的 k_neighbors 参数,您可能会遇到问题。我已经看到了几种解决此问题的方法,但我怀疑它是否会导致您列出的错误,因为根据您提供的信息,它并不适用。

尝试提供 minimal reproducible example 是件好事。例如:

from imblearn.over_sampling import SMOTENC
from sklearn.datasets import make_classification
from collections import Counter

X,y = make_classification(n_samples=557,n_features=55,n_informative=52,n_redundant=0,n_repeated=0,n_classes=6,n_clusters_per_class=1,weights=[281/557,184/557,57/557,27/557,5/557,3/557],class_sep=1,random_state=42)

print(sorted(Counter(y).items()))
print (X[-1:])

smote_nc = SMOTENC(categorical_features=[0,2,3] random_state=42,k_neighbors=2)
X_resampled,y_resampled = smote_nc.fit_resample(X,y)

print(sorted(Counter(y_resampled).items()))
print (X_resampled[-1:])

import numpy as np
from collections import Counter
from imblearn.over_sampling import SMOTENC

rng = np.random.RandomState(15)
n_samples = 557
X = np.empty((n_samples,3),dtype=object)
X[:,0] = rng.choice(['2','0','6','4','3','7'],size=n_samples).astype(object)
X[:,1] = rng.randn(n_samples)
X[:,2] = rng.randint(3,size=n_samples)
y = np.array([0] * 281 + [1] * 184 + [2] * 57 + [3] * 27 + [4] * 5 + [5] * 3)

print(sorted(Counter(y).items()))
print (X[-1:])

smote_nc = SMOTENC(categorical_features=[0,2],random_state=42,y)

print(sorted(Counter(y_resampled).items()))
print (X_resampled[-10:])

我知道这些示例可能与您所拥有的不太相似,但这就是我想要表达的观点。 print 语句显示可重现的输出并提供代码正在执行的操作的上下文。目前,我看不出有人能确切地告诉您脚本中的问题所在。

我猜你的问题与你在这里所说的有关:

...我没有 96 列,这是从哪里来的?

我不知道 xy 是什么样子,但如果您在那里发现问题,我不会感到惊讶。

如果您不能提供更多代码,这可能有助于某人了解:

  • 您使用的是什么版本的 Python?
  • 您在什么类型的机器上运行它?
  • 您安装了哪个版本的 imblearn
  • 您能运行来自 the docs 的示例吗?像我上面发布的那个例子怎么样?

我真诚地希望这可能会有所帮助,如果我得到足够的信息来解决这个问题,我很乐意回来并用真实的答案编辑它。不过,目前,与您所描述的数据集类似的数据集似乎在 32 位 Python 3.6.5 中运行良好,在我的 (imbalanced-learn==0.8.0,scikit-learn==0.24.1) 上64 位 Windows 10 电脑。

我可能会在有时间的时候尝试一些不同的机器和一些不同版本的 python,看看我是否可以重现您的问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。