簡體   English   中英

ValueError:在使用來自不平衡學習的 SMOTENC 時,無法將輸入數組從形狀 (3,96) 廣播到形狀 (184,96)

[英]ValueError: could not broadcast input array from shape (3,96) into shape (184,96) while using SMOTENC from imbalanced learn

我正在嘗試使用不平衡學習庫中的 SMOTENC 對包含分類變量和數值變量的 dataframe 進行過采樣。 總共有 55 列,其中 3 列是數字的。 數據集中每個 class(值計數)的樣本數如下:

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 包含每個樣本的 class 成員資格,x 包含特征的 rest。 但是,我無法對此數據集進行過度采樣,而是收到錯誤ValueError: could not broadcast input array from the shape (3,96) into shape (184,96) 據我所知,該錯誤與 ID 為 7 的 class 有關。為什么 SMOTENC 不能對這個 class 進行過采樣? 是否有限制,例如為對數據集進行過采樣而需要提供的最小樣本數? 另外,我沒有96列,這是從哪里來的?

有關該錯誤的更多詳細信息如下:請注意,我的所有分類特征都是二進制的,它們已經過一次熱編碼。 因此,它不需要 SMOTENC 進行任何額外的編碼,這意味着不應該增加列數。 發生錯誤的確切行是

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

這個 function (_generate_samples) 的評論說“如果中值標准等於零,我們必須根據 OHE 的編碼創建非空條目”。 在 base.py 中引發錯誤的完整部分是

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

但是,我不明白標准偏差如何為零,因為我知道數據集中的樣本彼此不相同,因此 std 必須與 0 不同。我知道該列是兩個稀疏列之一數值列(它們有很多零值)。 在 SMOTE 的源代碼中,我看到有一個 function 來處理稀疏列,但它似乎不能正常工作,這就是我得到錯誤的原因。 我不知道如何克服這個問題,我感謝任何關於此的幫助或建議。

要回答您的問題:

是否有限制,例如為對數據集進行過采樣而需要提供的最小樣本數?

根據我的經驗,如果您的樣本數量小於或等於傳遞給 SMOTENC class 的 k_neighbors 參數,您可能會遇到問題。 我已經看到了一些解決此問題的方法,但我懷疑它是否會導致您列出的錯誤,因為根據您提供的信息它並不適用。

最好嘗試提供一個最小的可重現示例 例如:

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, k_neighbors=2)
X_resampled, y_resampled = smote_nc.fit_resample(X, y)

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

我知道這些示例可能與您的示例不太相似,但這就是我要說明的重點。 print語句顯示可重現的 output 並提供代碼正在執行的操作的上下文。 目前,我看不出有人能准確地告訴您腳本中的問題所在。

我猜你的問題與你在這里所說的有關:

...我沒有 96 列,這是從哪里來的?

我不知道xy是什么樣子,但如果這是您發現問題的地方,我不會感到驚訝。

如果您無法提供更多代碼,它可能會幫助某人了解:

  • 您使用的是哪個版本的 python?
  • 你在什么類型的機器上運行它?
  • 您安裝了哪個版本的imblearn
  • 您是否能夠運行文檔中的示例? 像我上面發布的那個例子怎么樣?

我真誠地希望這可能會有所幫助,如果我有足夠的信息來解決這個問題,我很樂意回來並用一個真實的答案來編輯這個。 不過,目前,與您描述的數據集類似的數據集似乎在我的 (imbalanced-learn==0.8.0, scikit-learn==0.24.1) 的 32 位 Python 3.6.5 中運行良好64 位 Windows 10 PC。

當我有時間時,我可能會嘗試幾台不同的機器和 python 的一些不同版本,看看能否重現您的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM