📜  使用 smote 进行过采样 - Python (1)

📅  最后修改于: 2023-12-03 15:36:34.361000             🧑  作者: Mango

使用SMOTE进行过采样 - Python

在机器学习领域中,不平衡的数据集是很常见的问题。对于一些分类问题,如欺诈检测,有时会出现数据集中的某些类别远远少于其他类别。这称为类别不平衡问题。

为了解决这个问题,一种流行的方法是使用过采样技术。其中一种过采样技术是Synthetic Minority Over-sampling Technique (SMOTE)。它是一种基于K近邻算法的合成样本生成方法。

安装依赖

使用SMOTE之前,我们需要安装imblearn库。可以使用以下命令进行安装:

!pip install imblearn
载入数据

首先,让我们看一下一个不平衡的数据集。我们使用Scikit-learn库中的make_classification函数生成一个数据集。该数据集中类0有1000个样本,类1只有100个样本。

from sklearn.datasets import make_classification

X, y = make_classification(n_classes=2, class_sep=2,
                           weights=[0.9, 0.1], n_informative=3,
                           n_redundant=1, flip_y=0, n_features=20,
                           n_clusters_per_class=1, n_samples=1000,
                           random_state=10)

现在,我们的数据集中有2个类别和20个特征。

过采样

我们将使用imblearn库的SMOTE类进行过采样。当我们向SMOTE函数提供原始数据时,它将合成新的数据以增加较小类别的数量。

from imblearn.over_sampling import SMOTE

smote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)

现在,我们使用SMOTE类合成数据,以使两个类别具有相同数量的样本。其中,X_res 与 y_res 为过采样后的数据。

print(f"Original data shape: {X.shape}, {y.shape}")
print(f"Resampled data shape: {X_res.shape}, {y_res.shape}")
Original data shape: (1000, 20), (1000,)
Resampled data shape: (1800, 20), (1800,)

如您所见,原始数据集中类0有1000个样本,类1只有100个样本。过采样之后,两个类别都包含900个样本。

性能评估

我们可以使用不同的模型进行分类以评估过采样技术的性能。在这里,我们将使用逻辑回归模型。我们将对原始数据和过采样后数据分别进行拟合并比较两者的性能。

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score

# Split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
X_res_train, X_res_test, y_res_train, y_res_test = train_test_split(X_res, y_res, random_state=42)

# Train Logistic Regression and predict
lr = LogisticRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)

lr_res = LogisticRegression()
lr_res.fit(X_res_train, y_res_train)
y_res_pred = lr_res.predict(X_test)

# Evaluate performance
print("Performance on original data")
print("Accuracy:", accuracy_score(y_test, y_pred))
print("Precision:", precision_score(y_test, y_pred))
print("Recall:", recall_score(y_test, y_pred))
print("F1:", f1_score(y_test, y_pred))

print("\nPerformance on resampled data")
print("Accuracy:", accuracy_score(y_test, y_res_pred))
print("Precision:", precision_score(y_test, y_res_pred))
print("Recall:", recall_score(y_test, y_res_pred))
print("F1:", f1_score(y_test, y_res_pred))

输出结果为:

Performance on original data
Accuracy: 0.92
Precision: 0.5
Recall: 0.25
F1: 0.3333333333333333

Performance on resampled data
Accuracy: 0.88
Precision: 0.4
Recall: 0.5
F1: 0.4444444444444444

如您所见,过采样数据的准确率较低,但召回率较高。

总结

在这篇文章中,我们学习了使用SMOTE进行过采样以解决类别不平衡问题。特别是,我们看到了如何使用imblearn库中的SMOTE类来生成合成数据。我们使用逻辑回归模型对原始数据和过采样后数据进行拟合和性能评估,并比较了两者的性能。