大肠杆菌数据集的不平衡多类分类 Python

大肠杆菌数据集的不平衡多类分类

  • 关注博主学习更多内容
  • 关注v x GZH:多目标优化与学习Lab

教程概述

本教程分为五个部分;他们是:

  1. 大肠杆菌数据集

  2. 探索数据集

  3. 模型测试和基线结果

  4. 评估模型

    1. 评估机器学习算法
    2. 评估数据过采样
  5. 对新数据进行预测

大肠杆菌数据集

在这个项目中,我们将使用一个标准的不平衡机器学习数据集,称为“大肠杆菌”数据集,也称为“蛋白质定位位点”数据集。

该数据集描述了利用细胞定位位点的氨基酸序列对大肠杆菌蛋白质进行分类的问题。也就是说,根据蛋白质折叠前的化学成分来预测蛋白质如何与细胞结合。

该数据集归功于 Kenta Nakai,并由Paul Horton和Kenta Nakai在 1996 年发表的题为“预测蛋白质细胞定位位点的概率分类系统”的论文中发展成为当前的形式。他们的分类准确率达到了 81%。

该数据集由 336 个大肠杆菌蛋白质示例组成,每个示例均使用根据蛋白质氨基酸序列计算出的七个输入变量进行描述。

忽略序列名称,输入特征描述如下:

  • mcg

    :McGeoch 的信号序列识别方法。

  • gvh

    :von Heijne 的信号序列识别方法。

  • lip

    :von Heijne 的信号肽酶 II 共有序列评分。

  • chg

    :预测脂蛋白 N 末端存在电荷。

  • aac

    :外膜和周质蛋白氨基酸含量判别分析得分。

  • alm1

    :ALOM 跨膜区域预测程序的分数。

  • alm2

    :从序列中排除假定的可切割信号区域后 ALOM 程序的分数。

共有八个类,描述如下:

  • cp

    : 细胞质

  • im

    : 内膜无信号序列

  • pp

    : 周质

  • imU

    : 内膜,不可切割信号序列

  • om

    : 外膜

  • omL

    : 外膜脂蛋白

  • IML

    : 内膜脂蛋白

  • imS

    :内膜,可切割信号序列

各个类别的实例分布并不均匀,在某些情况下甚至严重不平衡。

例如,“ cp ”类有 143 个示例,而“ imL ”和“ imS ”类各只有两个示例。

接下来,让我们仔细看看数据。

探索数据集

首先,下载并解压缩数据集,并将其保存在当前工作目录中,名称为“ ecoli.csv ”。

请注意,此版本的数据集已删除第一列(序列名称),因为它不包含用于建模的通用信息。

  • 下载大肠杆菌数据集 (ecoli.csv)

查看文件的内容。

文件的前几行应如下所示:

0.49,0.29,0.48,0.50,0.56,0.24,0.35,cp

0.07,0.40,0.48,0.50,0.54,0.35,0.44,cp

0.56,0.40,0.48,0.50,0.49,0.37,0.46,cp

0.59,0.49,0.48,0.50,0.52,0.45,0.36,cp

0.23,0.32,0.48,0.50,0.55,0.25,0.35,cp

我们可以看到输入变量全部显示为数字,类标签是字符串值,需要在建模之前进行标签编码。

可以使用read_csv() Pandas 函数将数据集作为 DataFrame 加载,指定文件的位置以及没有标题行的事实。

# define the dataset location

filename = ‘ecoli.csv’

# load the csv file as a data frame

dataframe = read_csv(filename, header=None)

加载后,我们可以通过打印DataFrame的形状来汇总行数和列数。

# summarize the shape of the dataset

print(dataframe.shape)

接下来,我们可以计算每个输入变量的五数摘要。

# describe the dataset

set_option(‘precision’, 3)

print(dataframe.describe())

最后,我们还可以使用Counter对象汇总每个类中示例的数量。

# summarize the class distribution

target = dataframe.values[:,-1]

counter = Counter(target)

for k,v in counter.items():

per = v / len(target) * 100

print(‘Class=%s, Count=%d, Percentage=%.3f%%’ % (k, v, per))

将它们结合在一起,下面列出了加载和汇总数据集的完整示例。

# load and summarize the dataset

from pandas import read_csv

from pandas import set_option

from collections import Counter

# define the dataset location

filename = ‘ecoli.csv’

# load the csv file as a data frame

dataframe = read_csv(filename, header=None)

# summarize the shape of the dataset

print(dataframe.shape)

# describe the dataset

set_option(‘precision’, 3)

print(dataframe.describe())

# summarize the class distribution

target = dataframe.values[:,-1]

counter = Counter(target)

for k,v in counter.items():

per = v / len(target) * 100

print(‘Class=%s, Count=%d, Percentage=%.3f%%’ % (k, v, per))

运行示例首先加载数据集并确认行数和列数,即 336 行、7 个输入变量和 1 个目标变量。

查看每个变量的摘要,发现变量已居中,即转移到均值 0.5。变量似乎也已标准化,这意味着所有值都在 0 到 1 之间的范围内;至少没有变量的值超出这个范围。

然后总结班级分布,确认每个班级的观察结果存在严重偏差。我们可以看到,“ cp ”类占主导地位,约占 42% 的示例,少数类(例如“ imS ”、“ imL ”和“ omL ”)约占数据集的 1% 或更少。

可能没有足够的数据来从这些少数群体中进行概括。一种方法可能是简单地删除这些类的示例。

(336, 8)

        0        1        2        3        4        5        6

count 336.000 336.000 336.000 336.000 336.000 336.000 336.000

mean 0.500 0.500 0.495 0.501 0.500 0.500 0.500

std 0.195 0.148 0.088 0.027 0.122 0.216 0.209

min 0.000 0.160 0.480 0.500 0.000 0.030 0.000

25% 0.340 0.400 0.480 0.500 0.420 0.330 0.350

50% 0.500 0.470 0.480 0.500 0.495 0.455 0.430

75% 0.662 0.570 0.480 0.500 0.570 0.710 0.710

max 0.890 1.000 1.000 1.000 0.880 1.000 0.990

Class=cp, Count=143, Percentage=42.560%

Class=im, Count=77, Percentage=22.917%

Class=imS, Count=2, Percentage=0.595%

Class=imL, Count=2, Percentage=0.595%

Class=imU, Count=35, Percentage=10.417%

Class=om, Count=20, Percentage=5.952%

Class=omL, Count=5, Percentage=1.488%

Class=pp, Count=52, Percentage=15.476%

我们还可以通过为每个输入变量创建直方图来查看输入变量的分布。

下面列出了创建所有输入变量的直方图的完整示例。

# create histograms of all variables

from pandas import read_csv

from matplotlib import pyplot

# define the dataset location

filename = ‘ecoli.csv’

# load the csv file as a data frame

df = read_csv(filename, header=None)

# create a histogram plot of each variable

df.hist(bins=25)

# show the plot

pyplot.show()

我们可以看到0、5、6等变量可能具有多峰分布。变量2和3可以具有二元分布,并且变量1和4可以具有类高斯分布。

根据模型的选择,数据集可能会受益于标准化、规范化,或许还有幂变换。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIWNGtNx-1692799401746)(attachments/SJK9V4TB.png)]

大肠杆菌数据集中变量的直方图

现在我们已经审查了数据集,让我们看看开发一个用于评估候选模型的测试工具。

模型测试和基线结果

k 折交叉验证过程提供了对模型性能的良好总体估计,至少与单个训练测试分割相比,并没有过于乐观的偏差。我们将使用k=5,这意味着每次折叠将包含大约 336/5 或大约 67 个示例。

分层意味着每次折叠的目标是包含与整个训练数据集相同的类示例混合。重复意味着评估过程将执行多次,以帮助避免侥幸结果并更好地捕获所选模型的方差。我们将使用三个重复。

这意味着单个模型将被拟合和评估 5 * 3 或 15 次,并且将报告这些运行的平均值和标准偏差。

这可以使用RepeatedStratifiedKFold scikit-learn 类来实现。

所有课程都同等重要。因此,在这种情况下,我们将使用分类精度来评估模型。

首先,我们可以定义一个函数来加载数据集,并将输入变量拆分为输入和输出变量,并使用标签编码器来确保类标签按顺序编号。

# load the dataset

def load_dataset(full_path):

# load the dataset as a numpy array

data = read_csv(full_path, header=None)

# retrieve numpy array

data = data.values

# split into input and output elements

X, y = data[:, :-1], data[:, -1]

# label encode the target variable to have the classes 0 and 1

y = LabelEncoder().fit_transform(y)

return X, y

我们可以定义一个函数来使用分层重复 5 倍交叉验证来评估候选模型,然后返回针对每次折叠和重复计算的模型分数列表。

下面的evaluate_model ()函数实现了这一点。

# evaluate a model

def evaluate_model(X, y, model):

# define evaluation procedure

cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)

# evaluate model

scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=-1)

return scores

然后我们可以调用load_dataset()函数来加载并确认大肠杆菌数据集。

# define the location of the dataset

full_path = ‘ecoli.csv’

# load the dataset

X, y = load_dataset(full_path)

# summarize the loaded dataset

print(X.shape, y.shape, Counter(y))

在这种情况下,我们将评估在所有情况下预测多数类别的基线策略。

这可以使用DummyClassifier类自动实现,并将“策略”设置为“ most_frequent ”,这将预测训练数据集中最常见的类(例如类“ *cp ”)。*因此,考虑到这是训练数据集中最常见类别的分布,我们预计该模型的分类准确率约为 42%。

# define the reference model

model = DummyClassifier(strategy=‘most_frequent’)

将所有这些结合在一起,下面列出了使用分类准确性在大肠杆菌数据集上评估基线模型的完整示例。

# baseline model and test harness for the ecoli dataset

from collections import Counter

from numpy import mean

from numpy import std

from pandas import read_csv

from sklearn.preprocessing import LabelEncoder

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import RepeatedStratifiedKFold

from sklearn.dummy import DummyClassifier

# load the dataset

def load_dataset(full_path):

# load the dataset as a numpy array

data = read_csv(full_path, header=None)

# retrieve numpy array

data = data.values

# split into input and output elements

X, y = data[:, :-1], data[:, -1]

# label encode the target variable to have the classes 0 and 1

y = LabelEncoder().fit_transform(y)

return X, y

# evaluate a model

def evaluate_model(X, y, model):

# define evaluation procedure

cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)

# evaluate model

scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=-1)

return scores

# define the location of the dataset

full_path = ‘ecoli.csv’

# load the dataset

X, y = load_dataset(full_path)

# summarize the loaded dataset

print(X.shape, y.shape, Counter(y))

# define the reference model

model = DummyClassifier(strategy=‘most_frequent’)

# evaluate the model

scores = evaluate_model(X, y, model)

# summarize performance

print(‘Mean Accuracy: %.3f (%.3f)’ % (mean(scores), std(scores)))

运行该示例首先加载数据集,并正确报告案例数量为 336,以及类标签的分布符合我们的预期。

然后使用重复分层k 倍交叉验证来评估采用我们默认策略的DummyClassifier ,分类准确度平均值和标准差据报告约为 42.6%。

(336, 7) (336,) Counter({0: 143, 1: 77, 7: 52, 4: 35, 5: 20, 6: 5, 3: 2, 2: 2})

Mean Accuracy: 0.426 (0.006)

模型评估期间报告警告;例如:

Warning: The least populated class in y has only 2 members, which is too few. The minimum number of members in any class cannot be less than n_splits=5.

这是因为某些类别没有足够数量的示例用于 5 倍交叉验证,例如类别“ imS ”和“ imL ”。

在这种情况下,我们将从数据集中删除这些示例。这可以通过更新load_dataset()以删除具有这些类的行(例如四行)来实现。

# load the dataset

def load_dataset(full_path):

# load the dataset as a numpy array

df = read_csv(full_path, header=None)

# remove rows for the minority classes

df = df[df[7] != ‘imS’]

df = df[df[7] != ‘imL’]

# retrieve numpy array

data = df.values

# split into input and output elements

X, y = data[:, :-1], data[:, -1]

# label encode the target variable to have the classes 0 and 1

y = LabelEncoder().fit_transform(y)

return X, y

然后我们可以重新运行该示例来建立分类准确性的基线。

下面列出了完整的示例。

# baseline model and test harness for the ecoli dataset

from collections import Counter

from numpy import mean

from numpy import std

from pandas import read_csv

from sklearn.preprocessing import LabelEncoder

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import RepeatedStratifiedKFold

from sklearn.dummy import DummyClassifier

# load the dataset

def load_dataset(full_path):

# load the dataset as a numpy array

df = read_csv(full_path, header=None)

# remove rows for the minority classes

df = df[df[7] != ‘imS’]

df = df[df[7] != ‘imL’]

# retrieve numpy array

data = df.values

# split into input and output elements

X, y = data[:, :-1], data[:, -1]

# label encode the target variable to have the classes 0 and 1

y = LabelEncoder().fit_transform(y)

return X, y

# evaluate a model

def evaluate_model(X, y, model):

# define evaluation procedure

cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)

# evaluate model

scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=-1)

return scores

# define the location of the dataset

full_path = ‘ecoli.csv’

# load the dataset

X, y = load_dataset(full_path)

# summarize the loaded dataset

print(X.shape, y.shape, Counter(y))

# define the reference model

model = DummyClassifier(strategy=‘most_frequent’)

# evaluate the model

scores = evaluate_model(X, y, model)

# summarize performance

print(‘Mean Accuracy: %.3f (%.3f)’ % (mean(scores), std(scores)))

运行该示例确认示例数量减少了 4 个,从 336 个减少到 332 个。

我们还可以看到班级数量从 8 级减少到 6 级(0 级到 5 级)。

绩效基线定为 43.1%。该分数提供了该数据集的基线,可以通过该基线来比较所有其他分类算法。获得高于约 43.1% 的分数表明模型在此数据集上具有技能,而等于或低于该值的分数表明模型在此数据集上不具有技能。

(332, 7) (332,) Counter({0: 143, 1: 77, 5: 52, 2: 35, 3: 20, 4: 5})

Mean Accuracy: 0.431 (0.005)

现在我们有了测试工具和性能基线,我们可以开始评估该数据集上的一些模型。

评估模型

在本节中,我们将使用上一节中开发的测试工具在数据集上评估一套不同的技术。

报告的性能良好,但没有高度优化(例如,未调整超参数)。

你能做得更好吗?如果您可以使用相同的测试工具获得更好的分类准确性,我很想听听。请在下面的评论中告诉我。

评估机器学习算法

让我们首先评估数据集上的混合机器学习模型。

在数据集上抽查一套不同的非线性算法可能是一个好主意,可以快速找出哪些算法效果好、值得进一步关注,哪些算法不行。

我们将在大肠杆菌数据集上评估以下机器学习模型:

  • 线性判别分析 (LDA)
  • 支持向量机(SVM)
  • 袋装决策树 (BAG)
  • 随机森林 (RF)
  • 额外的树(ET)

我们将主要使用默认模型超参数,但集成算法中的树数量除外,我们将其设置为合理的默认值 1,000。

我们将依次定义每个模型并将它们添加到列表中,以便我们可以按顺序评估它们。下面的get_models ()函数定义了用于评估的模型列表,以及用于稍后绘制结果的模型短名称列表。

# define models to test

def get_models():

models, names = list(), list()

# LDA

models.append(LinearDiscriminantAnalysis())

names.append(‘LDA’)

# SVM

models.append(LinearSVC())

names.append(‘SVM’)

# Bagging

models.append(BaggingClassifier(n_estimators=1000))

names.append(‘BAG’)

# RF

models.append(RandomForestClassifier(n_estimators=1000))

names.append(‘RF’)

# ET

models.append(ExtraTreesClassifier(n_estimators=1000))

names.append(‘ET’)

return models, names

然后,我们可以依次枚举模型列表并评估每个模型,存储分数以供以后评估。

# define models

models, names = get_models()

results = list()

# evaluate each model

for i in range(len(models)):

# evaluate the model and store results

scores = evaluate_model(X, y, models[i])

results.append(scores)

# summarize performance

print(‘>%s %.3f (%.3f)’ % (names[i], mean(scores), std(scores)))

在运行结束时,我们可以将每个分数样本绘制为具有相同比例的箱须图,以便我们可以直接比较分布。

# plot the results

pyplot.boxplot(results, labels=names, showmeans=True)

pyplot.show()

将所有这些结合在一起,下面列出了在大肠杆菌数据集上评估一套机器学习算法的完整示例。

# spot check machine learning algorithms on the ecoli dataset

from numpy import mean

from numpy import std

from pandas import read_csv

from matplotlib import pyplot

from sklearn.preprocessing import LabelEncoder

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import RepeatedStratifiedKFold

from sklearn.svm import LinearSVC

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

from sklearn.ensemble import RandomForestClassifier

from sklearn.ensemble import ExtraTreesClassifier

from sklearn.ensemble import BaggingClassifier

# load the dataset

def load_dataset(full_path):

# load the dataset as a numpy array

df = read_csv(full_path, header=None)

# remove rows for the minority classes

df = df[df[7] != ‘imS’]

df = df[df[7] != ‘imL’]

# retrieve numpy array

data = df.values

# split into input and output elements

X, y = data[:, :-1], data[:, -1]

# label encode the target variable

y = LabelEncoder().fit_transform(y)

return X, y

# evaluate a model

def evaluate_model(X, y, model):

# define evaluation procedure

cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)

# evaluate model

scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=-1)

return scores

# define models to test

def get_models():

models, names = list(), list()

# LDA

models.append(LinearDiscriminantAnalysis())

names.append(‘LDA’)

# SVM

models.append(LinearSVC())

names.append(‘SVM’)

# Bagging

models.append(BaggingClassifier(n_estimators=1000))

names.append(‘BAG’)

# RF

models.append(RandomForestClassifier(n_estimators=1000))

names.append(‘RF’)

# ET

models.append(ExtraTreesClassifier(n_estimators=1000))

names.append(‘ET’)

return models, names

# define the location of the dataset

full_path = ‘ecoli.csv’

# load the dataset

X, y = load_dataset(full_path)

# define models

models, names = get_models()

results = list()

# evaluate each model

for i in range(len(models)):

# evaluate the model and store results

scores = evaluate_model(X, y, models[i])

results.append(scores)

# summarize performance

print(‘>%s %.3f (%.3f)’ % (names[i], mean(scores), std(scores)))

# plot the results

pyplot.boxplot(results, labels=names, showmeans=True)

pyplot.show()

运行该示例会依次评估每个算法并报告平均和标准差分类精度。

注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

在这种情况下,我们可以看到所有测试的算法都有技巧,达到了高于默认值 43.1% 的准确率。

结果表明,大多数算法在此数据集上表现良好,并且决策树集合可能表现最好,额外树实现了 88% 的准确率,随机森林实现了 89.5% 的准确率。

>LDA 0.886 (0.027)

>SVM 0.883 (0.027)

>BAG 0.851 (0.037)

>RF 0.895 (0.032)

>ET 0.880 (0.030)

创建一个图形,显示每个算法的结果样本的箱线图。该框显示中间 50% 的数据,每个框中间的橙色线显示样本的中位数,每个框内的绿色三角形显示样本的平均值。

我们可以看到,聚类在一起的决策树集合的分数分布与测试的其他算法分开。在大多数情况下,图上的平均值和中位数很接近,表明分数分布有些对称,这可能表明模型是稳定的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jgWn8IqL-1692799401749)(attachments/CSRGM2X9.png)]

不平衡大肠杆菌数据集上机器学习模型的箱线图

评估数据过采样

由于类如此之多,而许多类中的示例如此之少,数据集可能会从过采样中受益。

我们可以测试 SMOTE 算法应用于除多数类 ( cp ) 之外的所有类,从而提高性能。

一般来说,SMOTE 似乎对决策树集成没有帮助,因此我们将测试的算法集更改为以下内容:

  • 多项式 Logistic 回归 (LR)
  • 线性判别分析 (LDA)
  • 支持向量机(SVM)
  • k-最近邻 (KNN)
  • 高斯过程 (GP)

下面列出了用于定义这些模型的get_models()函数的更新版本。

# define models to test

def get_models():

models, names = list(), list()

# LR

models.append(LogisticRegression(solver=‘lbfgs’, multi_class=‘multinomial’))

names.append(‘LR’)

# LDA

models.append(LinearDiscriminantAnalysis())

names.append(‘LDA’)

# SVM

models.append(LinearSVC())

names.append(‘SVM’)

# KNN

models.append(KNeighborsClassifier(n_neighbors=3))

names.append(‘KNN’)

# GP

models.append(GaussianProcessClassifier())

names.append(‘GP’)

return models, names

我们可以使用不平衡学习库中的SMOTE实现以及同一库中的Pipeline首先将 SMOTE 应用于训练数据集,然后拟合给定模型作为交叉验证过程的一部分。

SMOTE 将使用训练数据集中的 k 最近邻合成新示例,默认情况下,k设置为 5。

这对于我们数据集中的某些类来说太大了。因此,我们将尝试k值为 2。

# create pipeline

steps = [(‘o’, SMOTE(k_neighbors=2)), (‘m’, models[i])]

pipeline = Pipeline(steps=steps)

# evaluate the model and store results

scores = evaluate_model(X, y, pipeline)

将它们结合在一起,下面列出了在大肠杆菌数据集上使用 SMOTE 过采样的完整示例。

# spot check smote with machine learning algorithms on the ecoli dataset

from numpy import mean

from numpy import std

from pandas import read_csv

from matplotlib import pyplot

from sklearn.preprocessing import LabelEncoder

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import RepeatedStratifiedKFold

from sklearn.svm import LinearSVC

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

from sklearn.neighbors import KNeighborsClassifier

from sklearn.gaussian_process import GaussianProcessClassifier

from sklearn.linear_model import LogisticRegression

from imblearn.pipeline import Pipeline

from imblearn.over_sampling import SMOTE

# load the dataset

def load_dataset(full_path):

# load the dataset as a numpy array

df = read_csv(full_path, header=None)

# remove rows for the minority classes

df = df[df[7] != ‘imS’]

df = df[df[7] != ‘imL’]

# retrieve numpy array

data = df.values

# split into input and output elements

X, y = data[:, :-1], data[:, -1]

# label encode the target variable

y = LabelEncoder().fit_transform(y)

return X, y

# evaluate a model

def evaluate_model(X, y, model):

# define evaluation procedure

cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)

# evaluate model

scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=-1)

return scores

# define models to test

def get_models():

models, names = list(), list()

# LR

models.append(LogisticRegression(solver=‘lbfgs’, multi_class=‘multinomial’))

names.append(‘LR’)

# LDA

models.append(LinearDiscriminantAnalysis())

names.append(‘LDA’)

# SVM

models.append(LinearSVC())

names.append(‘SVM’)

# KNN

models.append(KNeighborsClassifier(n_neighbors=3))

names.append(‘KNN’)

# GP

models.append(GaussianProcessClassifier())

names.append(‘GP’)

return models, names

# define the location of the dataset

full_path = ‘ecoli.csv’

# load the dataset

X, y = load_dataset(full_path)

# define models

models, names = get_models()

results = list()

# evaluate each model

for i in range(len(models)):

# create pipeline

steps = [(‘o’, SMOTE(k_neighbors=2)), (‘m’, models[i])]

pipeline = Pipeline(steps=steps)

# evaluate the model and store results

scores = evaluate_model(X, y, pipeline)

results.append(scores)

# summarize performance

print(‘>%s %.3f (%.3f)’ % (names[i], mean(scores), std(scores)))

# plot the results

pyplot.boxplot(results, labels=names, showmeans=True)

pyplot.show()

运行该示例会依次评估每个算法并报告平均和标准差分类精度。

注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

在这种情况下,我们可以看到带有 SMOTE 的 LDA 导致从 88.6% 小幅下降到约 87.9%,而带有 SMOTE 的 SVM 则从约 88.3% 小幅增加到约 88.8%。

在这种情况下使用 SMOTE 时,SVM 似乎也是性能最佳的方法,尽管与上一节中的随机森林相比,它没有实现改进。

>LR 0.875 (0.024)

>LDA 0.879 (0.029)

>SVM 0.888 (0.025)

>KNN 0.835 (0.040)

>GP 0.876 (0.023)

为每个算法创建分类准确度分数的箱线图和须线图。

我们可以看到 LDA 有许多性能异常值,其值高达 90%,这非常有趣。这可能表明,如果专注于丰富的类,LDA 可以表现得更好。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ptHlDwfg-1692799401750)(attachments/63CV2Q4B.png)]

在不平衡大肠杆菌数据集上使用机器学习模型进行 SMOTE 的盒须图

现在我们已经了解了如何在此数据集上评估模型,让我们看看如何使用最终模型进行预测。

对新数据进行预测

在本节中,我们可以拟合最终模型并使用它对单行数据进行预测。

我们将使用随机森林模型作为最终模型,其分类准确率约为 89.5%。

首先,我们可以定义模型。

# define model to evaluate

model = RandomForestClassifier(n_estimators=1000)

一旦定义,我们就可以将其拟合到整个训练数据集上。

# fit the model

model.fit(X, y)

一旦拟合,我们可以通过调用predict()函数使用它来对新数据进行预测。这将返回每个示例的编码类标签。

然后我们可以使用标签编码器进行逆变换以获得字符串类标签。

例如:

# define a row of data

row = […]

# predict the class label

yhat = model.predict([row])

label = le.inverse_transform(yhat)[0]

为了证明这一点,我们可以使用拟合模型对一些我们知道结果的情况进行一些标签预测。

下面列出了完整的示例。

# fit a model and make predictions for the on the ecoli dataset

from pandas import read_csv

from sklearn.preprocessing import LabelEncoder

from sklearn.ensemble import RandomForestClassifier

# load the dataset

def load_dataset(full_path):

# load the dataset as a numpy array

df = read_csv(full_path, header=None)

# remove rows for the minority classes

df = df[df[7] != ‘imS’]

df = df[df[7] != ‘imL’]

# retrieve numpy array

data = df.values

# split into input and output elements

X, y = data[:, :-1], data[:, -1]

# label encode the target variable

le = LabelEncoder()

y = le.fit_transform(y)

return X, y, le

# define the location of the dataset

full_path = ‘ecoli.csv’

# load the dataset

X, y, le = load_dataset(full_path)

# define model to evaluate

model = RandomForestClassifier(n_estimators=1000)

# fit the model

model.fit(X, y)

# known class “cp”

row = [0.49,0.29,0.48,0.50,0.56,0.24,0.35]

yhat = model.predict([row])

label = le.inverse_transform(yhat)[0]

print(‘>Predicted=%s (expected cp)’ % (label))

# known class “im”

row = [0.06,0.61,0.48,0.50,0.49,0.92,0.37]

yhat = model.predict([row])

label = le.inverse_transform(yhat)[0]

print(‘>Predicted=%s (expected im)’ % (label))

# known class “imU”

row = [0.72,0.42,0.48,0.50,0.65,0.77,0.79]

yhat = model.predict([row])

label = le.inverse_transform(yhat)[0]

print(‘>Predicted=%s (expected imU)’ % (label))

# known class “om”

row = [0.78,0.68,0.48,0.50,0.83,0.40,0.29]

yhat = model.predict([row])

label = le.inverse_transform(yhat)[0]

print(‘>Predicted=%s (expected om)’ % (label))

# known class “omL”

row = [0.77,0.57,1.00,0.50,0.37,0.54,0.0]

yhat = model.predict([row])

label = le.inverse_transform(yhat)[0]

print(‘>Predicted=%s (expected omL)’ % (label))

# known class “pp”

row = [0.74,0.49,0.48,0.50,0.42,0.54,0.36]

yhat = model.predict([row])

label = le.inverse_transform(yhat)[0]

print(‘>Predicted=%s (expected pp)’ % (label))

运行示例首先在整个训练数据集上拟合模型。

然后,使用拟合模型来预测从六个类别中的每一类别中选取的一个示例的标签。

我们可以看到,为每个选定的示例预测了正确的类标签。然而,平均而言,我们预计十分之一的预测会是错误的,并且这些错误可能不会在各个类别中均匀分布。

>Predicted=cp (expected cp)

>Predicted=im (expected im)

>Predicted=imU (expected imU)

>Predicted=om (expected om)

>Predicted=omL (expected omL)

>Predicted=pp (expected pp)

你可能感兴趣的:(不平衡学习,分类,python,人工智能)