对特征相关性低且 class 方差低的高度不平衡数据集进行采样的正确方法是什么?
What is correct way of sampling a highly imbalanced dataset which has low between feature correlation and low between class variance?
我有一个包含 23 个相关性非常低的特征的数据集。两个 类 在 类.
之间的方差很小
类 与可用于欺诈检测的数据一样高度不平衡。什么是对此类数据进行采样的合适方法?
感谢您来到 SO 提问!
处理不平衡数据(通常定义为一个或多个 classes 的案例数量与其他数据有很大不同的数据——某种偏斜分布)是一项持续的挑战, 以及促使大量在线写作的文章。我喜欢 this article 作为起点。我将在 Python 中提供示例,但类似的想法也适用于 R
。
提供一个快速总结:出于多种原因,抽样很重要,其中最重要的是正确拆分数据以进行训练和测试。为了过于简单化,您可以更改从数据集(样本)中提取示例的方式,以便获得每个 class 的机会大致相等,或者您可以尝试模拟 class 的新示例当您进行拆分时,用更少的情况再次达到绘制 class 的相同概率。
为了清楚起见,假设变量 X
有两种情况:X = 0
和 X = 1
。我们将某些事件发生、出现某些特征、观察到某些响应等的情况称为 X = 1
。我们将其称为 "positive class"。最后,假设您有 100,000 个观察值,其中只有 1,000 个 X = 1
,其余为 X = 0
。因此,您的少数 class 是正 class,而您的不平衡(正到负)是 1/100。
如果您要抽取 50,000 个随机样本,并且希望正负比例大约为 50/50 class,您可以做几件事。
- 对少数人过度采样class
此方法让您从 X = 1
的数据中提取更多示例。要达到 50/50 的平衡,您需要从正数 class 中(随机地)抽取更多次才能达到 25,000 个示例。
要使用 sci-kit learn
执行此操作,您可以执行如下操作。
假设 X
是包含您的数据的数据框:
from sklearn.utils import resample
# make two dataframes, each with only one class
majority_df = X[X['outcome']==0]
minority_df = X[X['outcome']==1]
# Oversampling the minority
oversampled_minority_df = resample(minority_df,
replace=True,
n_samples=len(majority_df),
random_state=123)
几点评论:
- "Resampling"是从一个集合中一遍遍拉取数据的处理
replace
表示您希望进程 "put back" 它拉取的观察;在这种情况下,它只是意味着系统可以在重采样期间多次获取相同的观察结果(就好像它被放回袋子里供某人抓取一样)
n_samples
与 majority class 数据帧的长度相同,因此最终结果在 majority/minority 个例子
- 对大多数人进行欠采样 class
既然您已经了解了对少数 class 进行过采样,这恰恰相反。不是重复对少数 class 进行采样,直到你拥有与大多数相同数量的示例,在这里你只对大多数 class 进行采样,因为你拥有少数 class 的示例.
上面的代码可以逆向如下。仍然假设 X
是您的数据:
# Oversampling the minority
undersampled_majority_df = resample(majority_df,
replace=False,
n_samples=len(minority_df),
random_state=123)
几个注意事项:
- 这仍然是 "resampling",只是采样较少
replace
现在是假的,因为如果不需要的话你不想重复数据(你确实必须为过采样做)
n_samples
现在与 minority_df
的长度相匹配,因此样本数量相等
过度采样和欠采样 classes 都带有统计问题,您可以在其他地方进行研究。
另一种选择是合成数据。这再次过度简化了统计过程,扰乱了您拥有的数据,使 "new" 示例看起来与您现有的数据相似,但在过程中引入了一些(有用的)噪音。
一个用于处理不平衡数据和合成数据创建的流行包是 imblearn
。这个包本身有很多伟大的工作,但更好的是它与 sklearn
的相似程度以及两者的协同工作。
imblearn
提供流行的方法 SMOTE,或合成少数过采样技术,以及许多其他方法。然而,在这种情况下,imblearn
不是直接使用您的数据框,而是使用 SMOTE 作为其自身的拟合过程。
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
y = base_df['outcome']
X = base_df.drop('outcome', axis=1)
# setting up testing and training sets
X_train, X_test, y_train, y_test = train_test_split(X,
y,
test_size=0.20,
random_state=123)
sm = SMOTE(random_state=123, ratio=1.0)
X_train, y_train = sm.fit_sample(X_train, y_train)
您会注意到 sm
对象具有 fit_sample
方法,并且您在实例化它时设置了 positive/negative 的比例(通过 ratio
)。结果是在模型拟合期间平衡且可用的数据帧。
我有一个包含 23 个相关性非常低的特征的数据集。两个 类 在 类.
之间的方差很小类 与可用于欺诈检测的数据一样高度不平衡。什么是对此类数据进行采样的合适方法?
感谢您来到 SO 提问!
处理不平衡数据(通常定义为一个或多个 classes 的案例数量与其他数据有很大不同的数据——某种偏斜分布)是一项持续的挑战, 以及促使大量在线写作的文章。我喜欢 this article 作为起点。我将在 Python 中提供示例,但类似的想法也适用于 R
。
提供一个快速总结:出于多种原因,抽样很重要,其中最重要的是正确拆分数据以进行训练和测试。为了过于简单化,您可以更改从数据集(样本)中提取示例的方式,以便获得每个 class 的机会大致相等,或者您可以尝试模拟 class 的新示例当您进行拆分时,用更少的情况再次达到绘制 class 的相同概率。
为了清楚起见,假设变量 X
有两种情况:X = 0
和 X = 1
。我们将某些事件发生、出现某些特征、观察到某些响应等的情况称为 X = 1
。我们将其称为 "positive class"。最后,假设您有 100,000 个观察值,其中只有 1,000 个 X = 1
,其余为 X = 0
。因此,您的少数 class 是正 class,而您的不平衡(正到负)是 1/100。
如果您要抽取 50,000 个随机样本,并且希望正负比例大约为 50/50 class,您可以做几件事。
- 对少数人过度采样class
此方法让您从 X = 1
的数据中提取更多示例。要达到 50/50 的平衡,您需要从正数 class 中(随机地)抽取更多次才能达到 25,000 个示例。
要使用 sci-kit learn
执行此操作,您可以执行如下操作。
假设 X
是包含您的数据的数据框:
from sklearn.utils import resample
# make two dataframes, each with only one class
majority_df = X[X['outcome']==0]
minority_df = X[X['outcome']==1]
# Oversampling the minority
oversampled_minority_df = resample(minority_df,
replace=True,
n_samples=len(majority_df),
random_state=123)
几点评论:
- "Resampling"是从一个集合中一遍遍拉取数据的处理
replace
表示您希望进程 "put back" 它拉取的观察;在这种情况下,它只是意味着系统可以在重采样期间多次获取相同的观察结果(就好像它被放回袋子里供某人抓取一样)n_samples
与 majority class 数据帧的长度相同,因此最终结果在 majority/minority 个例子- 对大多数人进行欠采样 class
既然您已经了解了对少数 class 进行过采样,这恰恰相反。不是重复对少数 class 进行采样,直到你拥有与大多数相同数量的示例,在这里你只对大多数 class 进行采样,因为你拥有少数 class 的示例.
上面的代码可以逆向如下。仍然假设 X
是您的数据:
# Oversampling the minority
undersampled_majority_df = resample(majority_df,
replace=False,
n_samples=len(minority_df),
random_state=123)
几个注意事项:
- 这仍然是 "resampling",只是采样较少
replace
现在是假的,因为如果不需要的话你不想重复数据(你确实必须为过采样做)n_samples
现在与minority_df
的长度相匹配,因此样本数量相等
过度采样和欠采样 classes 都带有统计问题,您可以在其他地方进行研究。
另一种选择是合成数据。这再次过度简化了统计过程,扰乱了您拥有的数据,使 "new" 示例看起来与您现有的数据相似,但在过程中引入了一些(有用的)噪音。
一个用于处理不平衡数据和合成数据创建的流行包是 imblearn
。这个包本身有很多伟大的工作,但更好的是它与 sklearn
的相似程度以及两者的协同工作。
imblearn
提供流行的方法 SMOTE,或合成少数过采样技术,以及许多其他方法。然而,在这种情况下,imblearn
不是直接使用您的数据框,而是使用 SMOTE 作为其自身的拟合过程。
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
y = base_df['outcome']
X = base_df.drop('outcome', axis=1)
# setting up testing and training sets
X_train, X_test, y_train, y_test = train_test_split(X,
y,
test_size=0.20,
random_state=123)
sm = SMOTE(random_state=123, ratio=1.0)
X_train, y_train = sm.fit_sample(X_train, y_train)
您会注意到 sm
对象具有 fit_sample
方法,并且您在实例化它时设置了 positive/negative 的比例(通过 ratio
)。结果是在模型拟合期间平衡且可用的数据帧。