有没有一种方法可以将SMOTE与NaN一起使用?
这是在NaN值存在的情况下尝试使用SMOTE的虚拟程序
# Imports
from collections import Counter
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import Imputer
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import make_pipeline
from imblearn.combine import SMOTEENN
# Load data
bc = load_breast_cancer()
X, y = bc.data, bc.target
# Initial number of samples per class
print('Number of samples for both classes: {} and {}.'.format(*Counter(y).values()))
# SMOTEd class distribution
print('Dataset has %s missing values.' % np.isnan(X).sum())
_, y_resampled = SMOTE().fit_sample(X, y)
print('Number of samples for both classes: {} and {}.'.format(*Counter(y_resampled).values()))
# Generate artificial missing values
X[X > 1.0] = np.nan
print('Dataset has %s missing values.' % np.isnan(X).sum())
#_, y_resampled = make_pipeline(Imputer(), SMOTE()).fit_sample(X, y)
sm = SMOTE(ratio = 'auto',k_neighbors = 5, n_jobs = -1)
smote_enn = SMOTEENN(smote = sm)
x_train_res, y_train_res = smote_enn.fit_sample(X, y)
print('Number of samples for both classes: {} and {}.'.format(*Counter(y_resampled).values()))
我得到以下输出/错误:
Number of samples for both classes: 212 and 357.
Dataset has 0 missing values.
Number of samples for both classes: 357 and 357.
Dataset has 6051 missing values.
ValueError: Input contains NaN, infinity or a value too large for dtype('float64').
答案 0 :(得分:0)
通常不,SMOTE正在准备数据集以进行进一步的模型拟合。
常规模型(例如随机森林等)不适用于label变量中的NA
,因为您实际上在这里预测什么?对于NA
的预测变量也是如此,其中大多数算法要么不起作用,要么只是忽略NA
的情况。
因此,错误很大程度上是设计使然,因为您不能也不应该在算法的训练数据集中缺少值,并且从逻辑上讲,您不希望“平衡”具有缺失值的案例,而只想通过有效标签。
如果您认为丢失的标签仍然代表应该平衡的有效信息(例如,您实际上想对NA
类进行过采样,因为您认为该类未提供足够的信息),那么它应该不是丢失的值,而应该是定义的值称为“未知”或其他值,表示具有“ NA”特征的已知类,但是我真的没有看到任何有意义的研究问题。
更新1:
另一种方法是首先估算缺失值,这样您实际上就可以通过三个步骤来拟合模型:
答案 1 :(得分:0)
您已经包含了答案。注意,使用fit_resample
代替fit_sample
。您应按以下方式使用make_pipeline
:
# Imports
import numpy as np
from collections import Counter
from sklearn.datasets import load_breast_cancer
from sklearn.impute import SimpleImputer
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import make_pipeline
from imblearn.combine import SMOTEENN
# Load data
bc = load_breast_cancer()
X, y = bc.data, bc.target
X[X > 1.0] = np.nan
# Over-sampling
smote = SMOTE(ratio='auto',k_neighbors=5, n_jobs=-1)
smote_enn = make_pipeline(SimpleImputer(), SMOTEENN(smote=smote))
_, y_res = smote_enn.fit_resample(X, y)
# Class distribution
print('Number of samples for both classes: {} and {}.'.format(*Counter(y_res).values()))
还要检查您的学习失衡版本。