了解用于处理不平衡数据集的Imbalanced-Learn包

482 阅读9分钟

了解不平衡--处理不平衡数据集的学习包

Imbalanced-learn是一个Python包,用于处理机器学习中的不平衡数据集。在一个不平衡的数据集中,数据样本的数量在各个类之间的分布并不平均。

在一个不平衡的数据集中,类的标签是不平等的。一个类的数据样本数量较多,而另一个类标签的数据样本数量明显较少。例如,如果你根据各种输入参数,预测一个学生是否会通过考试。在这个例子中,我们有两个类标签:passnot pass

当我们有2000个数据样本用于pass 类,200个用于not pass 类时,该数据集是不平衡的。pass 类的标签是not pass 类标签的10倍。当使用一个不平衡的数据集时,它将导致模型的偏差和不准确的结果。这就是为什么我们必须使用各种技术和库来平衡数据集。

在本教程中,我们将使用imbalanced-learn 库来处理这个问题。它可以帮助我们平衡样本数据集,使其在各个类之间有一个平等的分割。

前提条件

读者应该知道以下内容。

  • [Python编程]简介。
  • [机器学习]简介。
  • [Pandas]的简单介绍。
  • [随机森林分类算法]简介。

Imbalanced-Learn的安装

为了开始使用这个库。让我们用下面的命令来安装它。

pip install -U imbalanced-learn

让我们加载我们的不平衡数据集。

不平衡数据集

这里使用的数据集是用于丙型肝炎病毒分类。该数据集有一列Activity ,有两个类标签:activeinactive 。这两个类的标签是不平衡的。让我们导入pandas ,它将被用来加载我们的数据集。

import pandas as pd

为了加载数据集,运行这段代码。

df = pd.read_csv('https://drive.google.com/file/d/1zbAbWIA9uBarN7TdmN6pQsEX8E5vOW9o/view?usp=sharing', index_col=False)

让我们用以下命令检查我们的数据集中的Activity 列。

print(df)

输出结果如下所示。

Dataset columns

对于任何数据集,我们通常有两个变量,X 变量,和y 变量。X 变量代表所有在模型训练期间被用作输入的列。

y 变量代表输出列。输出是任何机器学习模型的预测结果。在我们的例子中,y 变量是Activity 列。

让我们从X 变量中删除Activity 列,并将其保存在y 变量中。

X = df.drop(['Activity'], axis=1)
y = df['Activity']

现在我们已经分离了我们的两个变量,让我们看看类别分布。

班级分布

要查看班级分布情况,请运行以下命令。

activity_count = y.value_counts()
print(activity_count)

其输出结果如下。

Class distribution

从上面的输出中,我们可以看到,我们有一个不平衡的数据集。active 类是 "多数",该类有更多的数据样本,相比之下,inactive 类是 "少数 "类。

让我们用饼状图来看看视觉表现。

饼状图

要为班级分布绘制一个饼图,请运行以下命令。

y.value_counts().plot.pie(autopct='%.2f')

该图显示在下面的图片中。

Pie Chart

从上面的图片来看,active 类是71.28% ,而inactive 类是28.72% 。在模型训练之前,我们需要平衡这个数据集。

在平衡我们的数据集之前,让我们把数据集分成一个训练集和一个测试集。然后,我们将在用它进行模型训练之前平衡训练集。

将数据集分割成训练集和测试集,可以让我们避免模型的过拟合或欠拟合

分割数据集

让我们导入train_test_split 包来进行数据集拆分。

from sklearn.model_selection import train_test_split

现在让我们来分割数据集。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

数据集将使用test_size=0.2 进行分割。这意味着分割后的数据集的80%将是训练集,20%将是测试集。让我们来看看这两个分割集的大小。

((462, 881), (462,), (116, 881), (116,))

我们的训练集是(462, 881) 。它有462 数据样本和881 列。这就是我们要平衡的集合。让我们看看这个测试集中activeinactive 类的大小。

print(y_train.value_counts())

输出结果如下所示。

Class distribution

我们现在可以绘制一个饼状图来显示这个分布。

y_train.value_counts().plot.pie(autopct='%.2f')

该图显示如下。

Pie chart

现在让我们用以下技术来平衡训练集的数据集。

类平衡技术

Imbalanced-learn有各种技术来处理不平衡的数据集。

在本教程中,我们将只关注两种技术。

  1. 随机低取样
  2. 随机过量取样

随机欠采样技术

在随机欠采样技术中,作为active 的 "多数 "类将被减少。这使得它与 "少数 "类的比例相同,也就是inactive 类。

多数 "类有330 数据样本,而 "少数 "类有132 数据样本。使用这种技术,active 类的330 数据样本将被减少到132 。这将使两个类得到平衡。

随机欠抽样技术有一些函数和算法可以平衡数据集。我们来导入其中一个函数。

from imblearn.under_sampling import RandomUnderSampler

RandomUnderSampler 是用于平衡我们的数据集的函数。现在让我们来使用它。

rus = RandomUnderSampler(sampling_strategy=1)
X_train_rus, y_train_rus = rus.fit_resample(X_train, y_train)

在上面的代码中,我们指定了sampling_strategy=1 。这确保了 "多数 "类和 "少数 "类将有一个1:1 的类分布。然后我们添加X_train, y_train ,其中包含我们正在平衡的训练数据集。

rus.fit_resample 这种方法确保我们的函数完全适合训练集。在平衡过程中,没有数据样本被遗漏。然后,我们将我们的平衡数据集保存到一个新的变量 。X_train_rus, y_train_rus

让我们绘制一个新的平衡数据集的饼图。

ax = y_train_rus.value_counts().plot.pie(autopct='%.2f')
_ = ax.set_title("Under-sampling")

该图显示如下。

Balanced dataset using random undersampling

从上面的图片中,我们可以看到active 类和inactive 类都是50% 。这表明,我们的数据集是平衡的。让我们看看activeinactive 两个类的大小。

print(y_train_rus.value_counts())

输出显示如下。

Class distribution

activeinactive 类是平衡的。

随机超量取样技术

在随机超量取样技术中,"少数 "类被增加,使其与 "多数 "类相等。这里,"多数 "类有330 数据样本,而 "少数 "类有132 数据样本。

在这种技术中,inactive 类的132 数据样本将被增加到330 。这将使两个类得到平衡。随机超量取样技术有一些函数和算法用于平衡数据集。让我们导入其中的一个函数。

from imblearn.over_sampling import RandomOverSampler

RandomOverSampler 是用来平衡我们的数据集的函数。现在让我们来实现它。

ros = RandomOverSampler(sampling_strategy=1)
X_train_ros, y_train_ros = ros.fit_resample(X_train, y_train)

在上面的代码中,我们指定了sampling_strategy=1 。这确保了 "少数 "类和 "多数 "类将有一个1:1 的类分布。然后我们添加X_train, y_train ,这是我们正在平衡的训练数据集。

rus.fit_resample 该方法确保我们的函数完全符合训练集的要求。在平衡过程中没有任何数据样本被遗漏。现在我们把我们的平衡数据集保存到一个新的变量 。X_train_ros, y_train_ros

让我们绘制一个新的平衡数据集的饼图。

ax = y_train_ros.value_counts().plot.pie(autopct='%.2f')
_ = ax.set_title("Over-sampling")

该图显示如下。

Balanced dataset using random oversampling

使用这种技术,我们仍然可以看到,active 类和inactive 类都是50% 。这表明,我们的数据集是平衡的。让我们看看activeinactive 两个类的大小。

print(y_train_ros.value_counts())

输出如下所示。

Class distribution

现在我们已经用技术平衡了我们的数据集,让我们开始建立我们的模型。我们将使用通过技术平衡的数据集建立我们的模型。然后我们将比较两个模型的准确度,看看哪种技术更好。

使用未取样的平衡类建立模型

让我们导入用于建立我们模型的算法。

from sklearn.ensemble import RandomForestClassifier

在建立我们的模型时,我们将使用RandomForestClassifier

model = RandomForestClassifier(random_state=42)
model.fit(X_train_rus, y_train_rus)

现在让我们把我们的数据集装入我们的平衡数据集。我们把我们的平衡数据集保存到一个名为X_train_rus, y_train_rus 的变量中。

model.fit(X_train_rus, y_train_rus)

该模型将从样本数据集中学习,并最终自行改进。让我们计算一下模型的准确度得分。我们用模型的预测能力来计算模型的准确性得分。我们使用测试数据集来进行预测。

该模型将把数据样本归入activeinactive 类。让我们导入进行预测所需的包。

from sklearn.metrics import matthews_corrcoef

matthews_corrcoef 将用于自动计算模型的准确度分数。它也有助于进行预测。让我们应用 来进行预测。model.predict

matthews_corrcoef 将使用 和 输出预测的准确性分数。这两个变量持有测试分割数据集。X_test y_test

y_test_pred = model.predict(X_test)
mcc_test = matthews_corrcoef(y_test, y_test_pred)

让我们来显示模型的性能结果。

df_labels = pd.Series(['MCC_test'], name = 'Performance_metric_names')
df_values = pd.Series([mcc_test], name = 'Performance_metric_values')
df2 = pd.concat([df_labels, df_values], axis=1)
print(df2)

我们在mcc_test 变量中保存我们的模型。上面的代码将绘制一个图表,显示Performance_metric_values ,如图所示。

Accuracy score

模型的准确度得分是0.712435 ,也就是71.2435%

现在,让我们使用下一个技术来建立我们的模型,看看准确率得分。

使用超量采样的平衡类建立模型

让我们重复上面的过程。唯一的区别是我们使用了一个不同的数据集变量。该数据集被保存在一个称为X_train_ros, y_train_ros 的变量中。

让我们导入一个随机森林算法。

from sklearn.ensemble import RandomForestClassifier

让我们建立模型。

model = RandomForestClassifier(random_state=42)
model.fit(X_train_ros, y_train_ros)

让我们导入计算我们模型的准确度分数所需的包。

from sklearn.metrics import matthews_corrcoef

我们可以应用该模型来进行预测。最终,计算出这些模型的准确率分数。

y_test_pred = model.predict(X_test)
mcc_test = matthews_corrcoef(y_test, y_test_pred)

和第一种方法一样,让我们来显示模型的性能结果。

df_labels = pd.Series(['MCC_test'], name = 'Performance_metric_names')
df_values = pd.Series([mcc_test], name = 'Performance_metric_values')
df3 = pd.concat([df_labels, df_values], axis=1)
df3

模型的准确度得分如下所示。

Accuracy score

模型的准确度得分是0.744225 ,即74.4225% 。与第一种方法的准确度得分相比,这个分数更高。这表明随机超采样技术比随机欠采样技术要好。

注意:这些技术也取决于我们所使用的数据集。

总结

在本教程中,我们已经了解了imbalanced-learn 包。我们经历了imbalanced-learn 的安装过程,探索了用于处理不平衡数据集的各种技术。

然后我们实现了随机超采样技术和随机欠采样技术。然后,我们使用这两种技术平衡的数据集建立了我们的模型。最后,我们得出结论,对于这个数据集,随机过度采样是更好的技术。